From 6753c0e7a06c3a7e9cd460d8b453d9467435958d Mon Sep 17 00:00:00 2001 From: limityan Date: Tue, 2 Jun 2026 14:00:44 +0800 Subject: [PATCH] refactor(agent-runtime): own event facts --- docs/plans/core-decomposition-completed.md | 5 +- docs/plans/core-decomposition-plan.md | 19 ++-- scripts/check-core-boundaries.mjs | 106 +++++++++++++++++- src/crates/agent-runtime/AGENTS.md | 3 +- src/crates/agent-runtime/src/events.rs | 56 +++++++++ src/crates/agent-runtime/src/lib.rs | 1 + .../agent-runtime/tests/events_contracts.rs | 70 ++++++++++++ src/crates/core/AGENTS-CN.md | 3 + src/crates/core/AGENTS.md | 4 + .../src/agentic/coordination/scheduler.rs | 13 +-- src/crates/core/src/agentic/events/types.rs | 13 ++- .../core/src/agentic/execution/types.rs | 25 +---- 12 files changed, 265 insertions(+), 53 deletions(-) create mode 100644 src/crates/agent-runtime/src/events.rs create mode 100644 src/crates/agent-runtime/tests/events_contracts.rs diff --git a/docs/plans/core-decomposition-completed.md b/docs/plans/core-decomposition-completed.md index 68cd92f54..7730bf9f0 100644 --- a/docs/plans/core-decomposition-completed.md +++ b/docs/plans/core-decomposition-completed.md @@ -58,7 +58,8 @@ delivery 纯决策,thread goal runtime 的 turn accounting、goal mutation、continuation plan 和 tool response assembly, subagent query scope / visibility / availability 决策,以及 round-boundary yield / injection state 和 turn-outcome queue policy;prompt-loop 的 user-context policy 和 tool / skill / subagent listing reminder - ordering 也已归入该 crate,core 只保留旧路径 re-export。 + ordering 已归入该 crate;finish-reason label、session-state event label 和 turn-outcome event fact 也已由 + `bitfun-agent-runtime` 承接,core 只保留旧路径 re-export 或 concrete adapter。 - persisted thread goal 的 portable DTO、status、continuation plan 和 tool response contract 已归入 `bitfun-runtime-ports`;`get_goal` / `create_goal` / `update_goal` 已进入产品 tool registry。 - `bitfun-harness` 已建立为可独立构建的 Harness contract crate,当前承接 workflow descriptor、legacy route @@ -68,7 +69,7 @@ 明确未完成: - `bitfun-agent-runtime` 不代表 session manager、concrete prompt assembly、concrete agent definition loading、scheduler 生命周期、 - event delivery 或 post-turn hook 已迁移。 + event delivery 或 post-turn hook 已迁移;当前 event 迁移只覆盖无副作用的 wire label / fact 映射。 - thread goal 的 metadata store、token subscriber、scheduler delivery adapter 和 goal `Tool` handler 仍在 `bitfun-core`;runtime 决策已经归属 `bitfun-agent-runtime`,后续不应再把它误归入普通 concrete tool IO。 - `bitfun-harness` 不代表 Deep Review、DeepResearch、MiniApp 的 concrete workflow execution 已迁移;PR4 provider diff --git a/docs/plans/core-decomposition-plan.md b/docs/plans/core-decomposition-plan.md index f3ee0e5f8..e2cd2934c 100644 --- a/docs/plans/core-decomposition-plan.md +++ b/docs/plans/core-decomposition-plan.md @@ -120,18 +120,18 @@ PR1 不迁移任何 concrete service owner,因此预期不会修改产品行 本阶段把 `bitfun-agent-runtime` 从单一 scheduler helper 扩展为有真实 owner 的 Agent Runtime SDK 基线。 已承接范围包括 scheduler/background delivery 纯决策,thread goal 的 turn accounting、goal mutation、 continuation / budget-limit / objective-updated plan、tool response assembly 和 skip/retry/usage-limit policy, -以及 subagent query scope、visibility / availability、round-boundary yield / injection state 和 -turn-outcome queue policy,并已承接 user-context policy 与 listing reminder ordering 这类 prompt-loop -纯事实。 +以及 subagent query scope、visibility / availability、round-boundary yield / injection state、turn-outcome +queue policy、finish-reason label、session-state event label 和 turn-outcome event fact,并已承接 +user-context policy 与 listing reminder ordering 这类 prompt-loop 纯事实。 仍不外移 concrete scheduler 生命周期:core 继续负责 running-turn injection delivery、submit、turn id、metadata、session manager、metadata store、token subscriber、scheduler delivery adapter、goal `Tool` handler、concrete prompt assembly、 concrete agent definition loading、custom subagent file IO / config adapter、event delivery 和 post-turn hook。 后续 Agent Runtime SDK 工作不得再把 thread goal runtime 当作普通 concrete tool IO;继续推进时应聚焦 -agent definition registry loading、permission coordination、runtime events、prompt module / prompt cache -contract 和 concrete scheduler lifecycle 的受保护迁移。user-context policy 与 listing reminder ordering -这类 prompt-loop 纯事实已归入 `bitfun-agent-runtime`,不得再回流到 core。 +agent definition registry loading、permission coordination、event delivery / post-turn hook、prompt module / +prompt cache contract 和 concrete scheduler lifecycle 的受保护迁移。prompt-loop 纯事实与 runtime event +facts 已归入 `bitfun-agent-runtime`,不得再回流到 core。 #### 4.2.3 本次 PR 验收 @@ -174,9 +174,10 @@ PR4 不迁移 concrete service IO、tool IO、surface command 语义、session m - 先迁移只读 facts、queue policy decision、runtime event facts,不先移动 concrete scheduler 生命周期。 - 保留 mode-scoped visibility、hidden/custom/review grouping、background result delivery、running-turn injection、idle-session follow-up 和 persisted thread goal continuation 语义。 -- thread goal runtime、subagent visibility/availability、round-boundary yield/injection 和 turn-outcome queue - policy 已归入 `bitfun-agent-runtime`;后续只允许 core 继续作为 metadata store、config/file IO adapter、 - concrete prompt assembly、concrete scheduler lifecycle、scheduler delivery、event delivery 和 `Tool` adapter。 +- thread goal runtime、subagent visibility/availability、round-boundary yield/injection、turn-outcome queue + policy、finish-reason label、session-state event label 和 turn-outcome event fact 已归入 + `bitfun-agent-runtime`;后续只允许 core 继续作为 metadata store、config/file IO adapter、concrete prompt + assembly、concrete scheduler lifecycle、scheduler delivery、event delivery 和 `Tool` adapter。 - 验证 subagent availability、queue/preempt/cancel suppression、DeepResearch citation / post-turn hook、goal verification events、`get_goal` / `create_goal` / `update_goal` tool response wire shape。 ### 5.3 Product-Domain Runtime Owner diff --git a/scripts/check-core-boundaries.mjs b/scripts/check-core-boundaries.mjs index b333d9d9b..0e2dfa34f 100644 --- a/scripts/check-core-boundaries.mjs +++ b/scripts/check-core-boundaries.mjs @@ -748,6 +748,46 @@ const forbiddenContentRules = [ }, ], }, + { + path: 'src/crates/core/src/agentic/execution/types.rs', + patterns: [ + { + regex: /\bpub\s+enum\s+FinishReason\b/, + message: + 'core execution types must not own finish-reason event facts; use bitfun-agent-runtime events', + }, + ], + }, + { + path: 'src/crates/core/src/agentic/events/types.rs', + patterns: [ + { + regex: /SessionState::Idle\s*=>\s*"idle"/, + message: + 'core event types must not own session-state wire labels; use bitfun-agent-runtime events', + }, + { + regex: /SessionState::Processing\s*\{[^}]*\}\s*=>\s*"processing"/, + message: + 'core event types must not own session-state wire labels; use bitfun-agent-runtime events', + }, + { + regex: /SessionState::Error\s*\{[^}]*\}\s*=>\s*"error"/, + message: + 'core event types must not own session-state wire labels; use bitfun-agent-runtime events', + }, + ], + }, + { + path: 'src/crates/core/src/agentic/coordination/scheduler.rs', + patterns: [ + { + regex: /\bfn\s+turn_outcome_kind\s*\(/, + message: + 'core scheduler must not own turn-outcome event facts; use bitfun-agent-runtime events', + }, + ], + }, { path: 'src/crates/core/src/agentic/tools/framework.rs', patterns: [ @@ -2326,6 +2366,44 @@ const requiredContentRules = [ }, ], }, + { + path: 'src/crates/agent-runtime/src/events.rs', + reason: + 'agent-runtime must own runtime event facts that do not require concrete scheduler or session IO', + patterns: [ + { + regex: /\bpub enum FinishReason\b/, + message: 'missing agent-runtime finish-reason event fact', + }, + { + regex: /\bpub const fn session_state_label\b/, + message: 'missing agent-runtime session-state label fact', + }, + { + regex: /\bpub fn turn_outcome_kind\b/, + message: 'missing agent-runtime turn-outcome event fact', + }, + ], + }, + { + path: 'src/crates/agent-runtime/tests/events_contracts.rs', + reason: + 'agent-runtime event owner must keep behavior-equivalence contracts for event wire labels', + patterns: [ + { + regex: /\bfinish_reason_display_preserves_wire_labels\b/, + message: 'missing finish-reason wire-label regression', + }, + { + regex: /\bsession_state_labels_match_existing_event_wire_values\b/, + message: 'missing session-state label regression', + }, + { + regex: /\bturn_outcome_kind_matches_existing_reply_policy_contract\b/, + message: 'missing turn-outcome event fact regression', + }, + ], + }, { path: 'src/crates/core/src/agentic/agents/prompt_builder/user_context.rs', reason: @@ -3340,9 +3418,13 @@ const requiredContentRules = [ }, { regex: - /use bitfun_runtime_ports::\{(?=[\s\S]*DialogSessionStateFact)(?=[\s\S]*DialogSubmitQueueAction)(?=[\s\S]*DialogSubmitQueueFacts)(?=[\s\S]*DialogTurnOutcomeKind)(?=[\s\S]*resolve_dialog_submit_queue_action)(?=[\s\S]*should_skip_agent_session_reply_contract)(?=[\s\S]*should_suppress_agent_session_cancelled_reply_contract)[\s\S]*\};/, + /use bitfun_runtime_ports::\{(?=[\s\S]*DialogSessionStateFact)(?=[\s\S]*DialogSubmitQueueAction)(?=[\s\S]*DialogSubmitQueueFacts)(?=[\s\S]*resolve_dialog_submit_queue_action)(?=[\s\S]*should_skip_agent_session_reply_contract)(?=[\s\S]*should_suppress_agent_session_cancelled_reply_contract)[\s\S]*\};/, message: 'missing dialog scheduler decision contract import', }, + { + regex: /use bitfun_agent_runtime::events::turn_outcome_kind;/, + message: 'missing agent-runtime turn-outcome event fact import', + }, { regex: /use bitfun_agent_runtime::scheduler::\{(?=[\s\S]*BackgroundDeliveryAction)(?=[\s\S]*BackgroundDeliveryFacts)(?=[\s\S]*resolve_background_delivery_action)[\s\S]*\};/, @@ -7398,6 +7480,26 @@ function runManifestParserSelfTest() { 'prepended_prompt_reminders_keep_runtime_injection_order', ], }, + { + path: 'src/crates/agent-runtime/src/events.rs', + contracts: ['FinishReason', 'session_state_label', 'turn_outcome_kind'], + }, + { + path: 'src/crates/agent-runtime/tests/events_contracts.rs', + contracts: [ + 'finish_reason_display_preserves_wire_labels', + 'session_state_labels_match_existing_event_wire_values', + 'turn_outcome_kind_matches_existing_reply_policy_contract', + ], + }, + { + path: 'src/crates/core/src/agentic/execution/types.rs', + contracts: ['bitfun_agent_runtime::events::FinishReason'], + }, + { + path: 'src/crates/core/src/agentic/events/types.rs', + contracts: ['bitfun_agent_runtime::events::session_state_label'], + }, { path: 'src/crates/core/src/agentic/agents/prompt_builder/user_context.rs', contracts: ['bitfun_agent_runtime::prompt'], @@ -7575,7 +7677,7 @@ function runManifestParserSelfTest() { 'DialogSubmitOutcome', 'DialogSubmitQueueAction', 'DialogSubmitQueueFacts', - 'DialogTurnOutcomeKind', + 'bitfun_agent_runtime::events::turn_outcome_kind', 'dialog_policy_may_preempt', 'resolve_dialog_submit_queue_action', 'should_skip_agent_session_reply_contract', diff --git a/src/crates/agent-runtime/AGENTS.md b/src/crates/agent-runtime/AGENTS.md index cd2a7cadf..14d1f3970 100644 --- a/src/crates/agent-runtime/AGENTS.md +++ b/src/crates/agent-runtime/AGENTS.md @@ -16,7 +16,8 @@ and tested without `bitfun-core`. thread-goal accounting/mutation/continuation decisions, cancellation routing, runtime event facts, registry visibility/availability, round-boundary yield/injection state, turn-outcome queue decisions, prompt-loop user-context - policy, and prompt listing reminder ordering. + policy, prompt listing reminder ordering, finish-reason labels, + session-state event labels, and turn-outcome event facts. - Keep concrete prompt assembly, workspace context IO, prompt cache coordination, and dynamic environment collection outside this crate until a reviewed migration proves behavior equivalence. diff --git a/src/crates/agent-runtime/src/events.rs b/src/crates/agent-runtime/src/events.rs new file mode 100644 index 000000000..0f08823e1 --- /dev/null +++ b/src/crates/agent-runtime/src/events.rs @@ -0,0 +1,56 @@ +//! Runtime event owner facts. + +use crate::scheduler::{TurnOutcome, TurnOutcomeStatus}; +use bitfun_runtime_ports::{DialogSessionStateFact, DialogTurnOutcomeKind}; +use std::fmt; + +/// Why a dialog execution or model round finished. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum FinishReason { + /// Normal completion + Complete, + /// Need to execute tools + ToolCalls, + /// User cancelled + Cancelled, + /// Error + Error, +} + +impl FinishReason { + pub const fn as_str(&self) -> &'static str { + match self { + FinishReason::Complete => "complete", + FinishReason::ToolCalls => "tool_calls", + FinishReason::Cancelled => "cancelled", + FinishReason::Error => "error", + } + } +} + +impl fmt::Display for FinishReason { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.as_str()) + } +} + +pub const fn session_state_label(state: DialogSessionStateFact) -> &'static str { + match state { + DialogSessionStateFact::Missing => "missing", + DialogSessionStateFact::Idle => "idle", + DialogSessionStateFact::Processing => "processing", + DialogSessionStateFact::Error => "error", + } +} + +pub const fn turn_outcome_status_kind(status: TurnOutcomeStatus) -> DialogTurnOutcomeKind { + match status { + TurnOutcomeStatus::Completed => DialogTurnOutcomeKind::Completed, + TurnOutcomeStatus::Cancelled => DialogTurnOutcomeKind::Cancelled, + TurnOutcomeStatus::Failed => DialogTurnOutcomeKind::Failed, + } +} + +pub fn turn_outcome_kind(outcome: &TurnOutcome) -> DialogTurnOutcomeKind { + turn_outcome_status_kind(outcome.status()) +} diff --git a/src/crates/agent-runtime/src/lib.rs b/src/crates/agent-runtime/src/lib.rs index 83461d812..880827e3a 100644 --- a/src/crates/agent-runtime/src/lib.rs +++ b/src/crates/agent-runtime/src/lib.rs @@ -4,6 +4,7 @@ //! depending on `bitfun-core` concrete session or scheduler lifecycle. pub mod agents; +pub mod events; pub mod prompt; pub mod scheduler; pub mod thread_goal; diff --git a/src/crates/agent-runtime/tests/events_contracts.rs b/src/crates/agent-runtime/tests/events_contracts.rs new file mode 100644 index 000000000..c4416e226 --- /dev/null +++ b/src/crates/agent-runtime/tests/events_contracts.rs @@ -0,0 +1,70 @@ +use bitfun_agent_runtime::events::{ + session_state_label, turn_outcome_kind, turn_outcome_status_kind, FinishReason, +}; +use bitfun_agent_runtime::scheduler::{TurnOutcome, TurnOutcomeStatus}; +use bitfun_runtime_ports::{DialogSessionStateFact, DialogTurnOutcomeKind}; + +#[test] +fn finish_reason_display_preserves_wire_labels() { + assert_eq!(FinishReason::Complete.as_str(), "complete"); + assert_eq!(FinishReason::ToolCalls.as_str(), "tool_calls"); + assert_eq!(FinishReason::Cancelled.as_str(), "cancelled"); + assert_eq!(FinishReason::Error.as_str(), "error"); + + assert_eq!(FinishReason::Complete.to_string(), "complete"); + assert_eq!(FinishReason::ToolCalls.to_string(), "tool_calls"); + assert_eq!(FinishReason::Cancelled.to_string(), "cancelled"); + assert_eq!(FinishReason::Error.to_string(), "error"); +} + +#[test] +fn session_state_labels_match_existing_event_wire_values() { + assert_eq!(session_state_label(DialogSessionStateFact::Idle), "idle"); + assert_eq!( + session_state_label(DialogSessionStateFact::Processing), + "processing" + ); + assert_eq!(session_state_label(DialogSessionStateFact::Error), "error"); + assert_eq!( + session_state_label(DialogSessionStateFact::Missing), + "missing" + ); +} + +#[test] +fn turn_outcome_kind_matches_existing_reply_policy_contract() { + assert_eq!( + turn_outcome_status_kind(TurnOutcomeStatus::Completed), + DialogTurnOutcomeKind::Completed + ); + assert_eq!( + turn_outcome_status_kind(TurnOutcomeStatus::Cancelled), + DialogTurnOutcomeKind::Cancelled + ); + assert_eq!( + turn_outcome_status_kind(TurnOutcomeStatus::Failed), + DialogTurnOutcomeKind::Failed + ); + + let completed = TurnOutcome::Completed { + turn_id: "turn-complete".to_string(), + final_response: "done".to_string(), + }; + let cancelled = TurnOutcome::Cancelled { + turn_id: "turn-cancelled".to_string(), + }; + let failed = TurnOutcome::Failed { + turn_id: "turn-failed".to_string(), + error: "network offline".to_string(), + }; + + assert_eq!( + turn_outcome_kind(&completed), + DialogTurnOutcomeKind::Completed + ); + assert_eq!( + turn_outcome_kind(&cancelled), + DialogTurnOutcomeKind::Cancelled + ); + assert_eq!(turn_outcome_kind(&failed), DialogTurnOutcomeKind::Failed); +} diff --git a/src/crates/core/AGENTS-CN.md b/src/crates/core/AGENTS-CN.md index 938cf0725..292b18769 100644 --- a/src/crates/core/AGENTS-CN.md +++ b/src/crates/core/AGENTS-CN.md @@ -48,6 +48,9 @@ SessionManager → Session → DialogTurn → ModelRound reminder ordering 归属 `bitfun-agent-runtime`。core 保留具体 prompt assembly、workspace / remote / project-layout context IO、language/config lookup、prompt cache 协调和旧路径兼容 re-export。 +- Finish-reason label、session-state event label 和 turn-outcome event fact + 归属 `bitfun-agent-runtime`。core 保留具体 event routing、event emission、 + session state storage 和旧路径兼容 re-export。 - Tool 相关轻量 contract、portable tool context facts/provider、纯 manifest/exposure contract、generic registry / static-provider / dynamic-provider container、file guidance marker、file-read freshness 比较策略和 oversized tool-result preview/rendering 纯策略归属 `bitfun-agent-tools`;core tool runtime 通过 `product_runtime.rs` 统一负责产品工具组装、`dyn Tool` 适配、snapshot decoration、runtime manifest assembly / context filtering、按需工具说明发现(`GetToolSpec`)执行,以及 collapsed unlock observation source。 - `ToolUseContext`、session file-read state storage、tool-result filesystem writes 与具体工具实现继续留在 core,除非已有评审过的 port/provider 方案和等价测试。 - Tool 迁移必须保持 expanded/collapsed exposure、prompt 可见 manifest、`ToolUseContext.unlocked_collapsed_tools`,以及 desktop/MCP/ACP tool catalog 行为等价。 diff --git a/src/crates/core/AGENTS.md b/src/crates/core/AGENTS.md index b3b4be02e..ab949da2e 100644 --- a/src/crates/core/AGENTS.md +++ b/src/crates/core/AGENTS.md @@ -54,6 +54,10 @@ SessionManager → Session → DialogTurn → ModelRound ordering belong in `bitfun-agent-runtime`. Core keeps concrete prompt assembly, workspace / remote / project-layout context IO, language/config lookup, prompt cache coordination, and old-path compatibility re-exports. +- Finish-reason labels, session-state event labels, and turn-outcome event + facts belong in + `bitfun-agent-runtime`. Core keeps concrete event routing, event emission, + session state storage, and old-path compatibility re-exports. - For tools, keep lightweight contracts, pure manifest/exposure contracts, generic contextual prompt-manifest resolver contracts, generic catalog snapshot provider contracts, generic GetToolSpec catalog provider/detail/ diff --git a/src/crates/core/src/agentic/coordination/scheduler.rs b/src/crates/core/src/agentic/coordination/scheduler.rs index 49f864ec0..a14816459 100644 --- a/src/crates/core/src/agentic/coordination/scheduler.rs +++ b/src/crates/core/src/agentic/coordination/scheduler.rs @@ -39,6 +39,7 @@ use uuid::Uuid; const MAX_QUEUE_DEPTH: usize = 20; +use bitfun_agent_runtime::events::turn_outcome_kind; use bitfun_agent_runtime::scheduler::{ resolve_background_delivery_action, BackgroundDeliveryAction, BackgroundDeliveryFacts, }; @@ -46,7 +47,7 @@ use bitfun_runtime_ports::{ resolve_dialog_submit_queue_action, should_skip_agent_session_reply as should_skip_agent_session_reply_contract, should_suppress_agent_session_cancelled_reply as should_suppress_agent_session_cancelled_reply_contract, - DialogSessionStateFact, DialogSubmitQueueAction, DialogSubmitQueueFacts, DialogTurnOutcomeKind, + DialogSessionStateFact, DialogSubmitQueueAction, DialogSubmitQueueFacts, }; pub use bitfun_runtime_ports::{ AgentSessionReplyRoute, DialogQueuePriority, DialogSteerOutcome, DialogSubmissionPolicy, @@ -484,14 +485,6 @@ impl DialogScheduler { } } - fn turn_outcome_kind(outcome: &TurnOutcome) -> DialogTurnOutcomeKind { - match outcome { - TurnOutcome::Completed { .. } => DialogTurnOutcomeKind::Completed, - TurnOutcome::Cancelled { .. } => DialogTurnOutcomeKind::Cancelled, - TurnOutcome::Failed { .. } => DialogTurnOutcomeKind::Failed, - } - } - /// Submit a user message for a session. /// /// - Session idle, queue empty → dispatched immediately. @@ -995,7 +988,7 @@ impl DialogScheduler { suppressed_cancelled_reply: bool, ) -> bool { should_skip_agent_session_reply_contract( - Self::turn_outcome_kind(outcome), + turn_outcome_kind(outcome), suppressed_cancelled_reply, ) } diff --git a/src/crates/core/src/agentic/events/types.rs b/src/crates/core/src/agentic/events/types.rs index c40b4ce34..687c69d4a 100644 --- a/src/crates/core/src/agentic/events/types.rs +++ b/src/crates/core/src/agentic/events/types.rs @@ -3,6 +3,8 @@ //! Uses bitfun-events layer event definitions, extending core-specific functionality here use crate::agentic::core::SessionState; +use bitfun_agent_runtime::events::session_state_label; +use bitfun_runtime_ports::DialogSessionStateFact; // ============ Re-export events layer types ============ pub use bitfun_events::agentic::ErrorCategory; @@ -24,9 +26,10 @@ pub type AgenticEvent = BaseAgenticEvent; /// Convert SessionState to String (for transmission) pub fn session_state_to_string(state: &SessionState) -> String { - match state { - SessionState::Idle => "idle".to_string(), - SessionState::Processing { .. } => "processing".to_string(), - SessionState::Error { .. } => "error".to_string(), - } + let fact = match state { + SessionState::Idle => DialogSessionStateFact::Idle, + SessionState::Processing { .. } => DialogSessionStateFact::Processing, + SessionState::Error { .. } => DialogSessionStateFact::Error, + }; + session_state_label(fact).to_string() } diff --git a/src/crates/core/src/agentic/execution/types.rs b/src/crates/core/src/agentic/execution/types.rs index 43db92696..be67d3eea 100644 --- a/src/crates/core/src/agentic/execution/types.rs +++ b/src/crates/core/src/agentic/execution/types.rs @@ -8,6 +8,7 @@ use crate::agentic::tools::pipeline::SubagentParentInfo; use crate::agentic::tools::ToolRuntimeRestrictions; use crate::agentic::workspace::WorkspaceServices; use crate::agentic::WorkspaceBinding; +pub use bitfun_agent_runtime::events::FinishReason; use bitfun_runtime_ports::DelegationPolicy; use serde_json::Value; use std::collections::HashMap; @@ -90,30 +91,6 @@ pub struct RoundResult { pub had_thinking_content: bool, } -/// Finish reason -#[derive(Debug, Clone, PartialEq)] -pub enum FinishReason { - /// Normal completion - Complete, - /// Need to execute tools - ToolCalls, - /// User cancelled - Cancelled, - /// Error - Error, -} - -impl std::fmt::Display for FinishReason { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - FinishReason::Complete => write!(f, "complete"), - FinishReason::ToolCalls => write!(f, "tool_calls"), - FinishReason::Cancelled => write!(f, "cancelled"), - FinishReason::Error => write!(f, "error"), - } - } -} - /// Execution result #[derive(Debug, Clone)] pub struct ExecutionResult {