use anyhow::Result;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::{
runtime::RuntimeHandle,
tool::spec::typed_spec,
types::{ToolCapabilityFamily, TrustLevel},
};
use super::{
serialize_success,
work_item_query::{query_context, view_for_record, WorkItemQueryContext, WorkItemView},
BuiltinToolDefinition,
};
use crate::tool::helpers::{parse_tool_args, validate_non_empty};
pub(crate) const NAME: &str = "GetWorkItem";
#[derive(Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub(crate) struct GetWorkItemArgs {
pub(crate) work_item_id: String,
#[serde(default)]
pub(crate) include_todo_list: bool,
}
#[derive(Serialize, Deserialize)]
pub(crate) struct GetWorkItemResult {
pub(crate) context: WorkItemQueryContext,
pub(crate) work_item: WorkItemView,
}
pub(crate) fn definition() -> Result<BuiltinToolDefinition> {
Ok(BuiltinToolDefinition {
family: ToolCapabilityFamily::CoreAgent,
spec: typed_spec::<GetWorkItemArgs>(
NAME,
"Read one work item by id, including its lifecycle view, current focus flag, plan artifact descriptor, bounded plan preview, and optional todo_list.",
)?,
})
}
pub(crate) async fn execute(
runtime: &RuntimeHandle,
_agent_id: &str,
_trust: &TrustLevel,
input: &Value,
) -> Result<crate::tool::ToolResult> {
let args: GetWorkItemArgs = parse_tool_args(NAME, input)?;
let work_item_id = validate_non_empty(args.work_item_id, NAME, "work_item_id")?;
let record = runtime
.latest_work_item(&work_item_id)
.await?
.ok_or_else(|| {
crate::tool::ToolError::new(
"unknown_work_item",
format!("unknown work item {work_item_id}"),
)
})?;
let context = query_context(runtime).await?;
let work_item = view_for_record(
runtime,
&context,
record,
args.include_todo_list,
None,
None,
)
.await?;
serialize_success(NAME, &GetWorkItemResult { context, work_item })
}