ralph/commands/task/decompose/
types.rs1use crate::contracts::{Model, ReasoningEffort, Runner, Task, TaskStatus};
17use serde::{Deserialize, Serialize};
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
20#[serde(rename_all = "snake_case")]
21pub enum DecompositionChildPolicy {
22 Fail,
23 Append,
24 Replace,
25}
26
27#[derive(Debug, Clone)]
28pub struct TaskDecomposeOptions {
29 pub source_input: String,
30 pub attach_to_task_id: Option<String>,
31 pub max_depth: u8,
32 pub max_children: usize,
33 pub max_nodes: usize,
34 pub status: TaskStatus,
35 pub child_policy: DecompositionChildPolicy,
36 pub with_dependencies: bool,
37 pub runner_override: Option<Runner>,
38 pub model_override: Option<Model>,
39 pub reasoning_effort_override: Option<ReasoningEffort>,
40 pub runner_cli_overrides: crate::contracts::RunnerCliOptionsPatch,
41 pub repoprompt_tool_injection: bool,
42}
43
44#[derive(Debug, Clone, Serialize)]
45#[serde(tag = "kind", rename_all = "snake_case")]
46pub enum DecompositionSource {
47 Freeform { request: String },
48 ExistingTask { task: Box<Task> },
49}
50
51#[derive(Debug, Clone, Serialize)]
52pub struct DecompositionAttachTarget {
53 pub task: Box<Task>,
54 pub has_existing_children: bool,
55}
56
57#[derive(Debug, Clone, Serialize)]
58pub struct DecompositionPreview {
59 pub source: DecompositionSource,
60 pub attach_target: Option<DecompositionAttachTarget>,
61 pub plan: DecompositionPlan,
62 pub write_blockers: Vec<String>,
63 pub child_status: TaskStatus,
64 pub child_policy: DecompositionChildPolicy,
65 pub with_dependencies: bool,
66}
67
68#[derive(Debug, Clone, Serialize)]
69pub struct DecompositionPlan {
70 pub root: PlannedNode,
71 pub warnings: Vec<String>,
72 pub total_nodes: usize,
73 pub leaf_nodes: usize,
74 pub dependency_edges: Vec<DependencyEdgePreview>,
75}
76
77#[derive(Debug, Clone, Serialize)]
78pub struct DependencyEdgePreview {
79 pub task_title: String,
80 pub depends_on_title: String,
81}
82
83#[derive(Debug, Clone, Serialize)]
84pub struct TaskDecomposeWriteResult {
85 pub root_task_id: Option<String>,
86 pub parent_task_id: Option<String>,
87 pub created_ids: Vec<String>,
88 pub replaced_ids: Vec<String>,
89 pub parent_annotated: bool,
90}
91
92#[derive(Debug, Clone, Deserialize)]
93#[serde(deny_unknown_fields)]
94pub(super) struct RawDecompositionResponse {
95 #[serde(default)]
96 pub(super) warnings: Vec<String>,
97 pub(super) tree: RawPlannedNode,
98}
99
100#[derive(Debug, Clone, Deserialize)]
101#[serde(deny_unknown_fields)]
102pub(super) struct RawPlannedNode {
103 #[serde(default)]
104 pub(super) key: Option<String>,
105 pub(super) title: String,
106 #[serde(default)]
107 pub(super) description: Option<String>,
108 #[serde(default)]
109 pub(super) plan: Vec<String>,
110 #[serde(default)]
111 pub(super) tags: Vec<String>,
112 #[serde(default)]
113 pub(super) scope: Vec<String>,
114 #[serde(default)]
115 pub(super) depends_on: Vec<String>,
116 #[serde(default)]
117 pub(super) children: Vec<RawPlannedNode>,
118}
119
120#[derive(Debug, Clone, Serialize)]
121pub struct PlannedNode {
122 pub planner_key: String,
123 pub title: String,
124 pub description: Option<String>,
125 pub plan: Vec<String>,
126 pub tags: Vec<String>,
127 pub scope: Vec<String>,
128 pub depends_on_keys: Vec<String>,
129 pub children: Vec<PlannedNode>,
130 #[serde(skip_serializing)]
131 pub(super) dependency_refs: Vec<String>,
132}
133
134#[derive(Debug, Clone, Copy, PartialEq, Eq)]
135pub(super) enum SourceKind {
136 Freeform,
137 ExistingTask,
138}
139
140pub(super) struct PlannerState {
141 pub(super) remaining_nodes: usize,
142 pub(super) warnings: Vec<String>,
143 pub(super) with_dependencies: bool,
144}