1use std::sync::Arc;
2
3use anyhow::{anyhow, Result};
4use assistant_tool::{ActionLog, Tool};
5use chrono::{Local, Utc};
6use gpui::{App, Entity, Task};
7use language_model::LanguageModelRequestMessage;
8use project::Project;
9use schemars::JsonSchema;
10use serde::{Deserialize, Serialize};
11
12#[derive(Debug, Serialize, Deserialize, JsonSchema)]
13#[serde(rename_all = "snake_case")]
14pub enum Timezone {
15 /// Use UTC for the datetime.
16 Utc,
17 /// Use local time for the datetime.
18 Local,
19}
20
21#[derive(Debug, Serialize, Deserialize, JsonSchema)]
22pub struct NowToolInput {
23 /// The timezone to use for the datetime.
24 timezone: Timezone,
25}
26
27pub struct NowTool;
28
29impl Tool for NowTool {
30 fn name(&self) -> String {
31 "now".into()
32 }
33
34 fn description(&self) -> String {
35 "Returns the current datetime in RFC 3339 format. Only use this tool when the user specifically asks for it or the current task would benefit from knowing the current datetime.".into()
36 }
37
38 fn input_schema(&self) -> serde_json::Value {
39 let schema = schemars::schema_for!(NowToolInput);
40 serde_json::to_value(&schema).unwrap()
41 }
42
43 fn ui_text(&self, _input: &serde_json::Value) -> String {
44 "Get current time".to_string()
45 }
46
47 fn run(
48 self: Arc<Self>,
49 input: serde_json::Value,
50 _messages: &[LanguageModelRequestMessage],
51 _project: Entity<Project>,
52 _action_log: Entity<ActionLog>,
53 _cx: &mut App,
54 ) -> Task<Result<String>> {
55 let input: NowToolInput = match serde_json::from_value(input) {
56 Ok(input) => input,
57 Err(err) => return Task::ready(Err(anyhow!(err))),
58 };
59
60 let now = match input.timezone {
61 Timezone::Utc => Utc::now().to_rfc3339(),
62 Timezone::Local => Local::now().to_rfc3339(),
63 };
64 let text = format!("The current datetime is {now}.");
65
66 Task::ready(Ok(text))
67 }
68}