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};
11use ui::IconName;
12
13#[derive(Debug, Serialize, Deserialize, JsonSchema)]
14#[serde(rename_all = "snake_case")]
15pub enum Timezone {
16 /// Use UTC for the datetime.
17 Utc,
18 /// Use local time for the datetime.
19 Local,
20}
21
22#[derive(Debug, Serialize, Deserialize, JsonSchema)]
23pub struct NowToolInput {
24 /// The timezone to use for the datetime.
25 timezone: Timezone,
26}
27
28pub struct NowTool;
29
30impl Tool for NowTool {
31 fn name(&self) -> String {
32 "now".into()
33 }
34
35 fn needs_confirmation(&self) -> bool {
36 false
37 }
38
39 fn description(&self) -> String {
40 "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()
41 }
42
43 fn icon(&self) -> IconName {
44 IconName::Info
45 }
46
47 fn input_schema(&self) -> serde_json::Value {
48 let schema = schemars::schema_for!(NowToolInput);
49 serde_json::to_value(&schema).unwrap()
50 }
51
52 fn ui_text(&self, _input: &serde_json::Value) -> String {
53 "Get current time".to_string()
54 }
55
56 fn run(
57 self: Arc<Self>,
58 input: serde_json::Value,
59 _messages: &[LanguageModelRequestMessage],
60 _project: Entity<Project>,
61 _action_log: Entity<ActionLog>,
62 _cx: &mut App,
63 ) -> Task<Result<String>> {
64 let input: NowToolInput = match serde_json::from_value(input) {
65 Ok(input) => input,
66 Err(err) => return Task::ready(Err(anyhow!(err))),
67 };
68
69 let now = match input.timezone {
70 Timezone::Utc => Utc::now().to_rfc3339(),
71 Timezone::Local => Local::now().to_rfc3339(),
72 };
73 let text = format!("The current datetime is {now}.");
74
75 Task::ready(Ok(text))
76 }
77}