ruby_todo 1.0.1 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyTodo
4
+ module AIAssistant
5
+ # Module for natural language task creation
6
+ module TaskCreator
7
+ # Handle natural language task creation
8
+ def handle_natural_language_task_creation(prompt, api_key)
9
+ # Get the default notebook
10
+ notebook_name = default_notebook_name
11
+
12
+ # Extract task description from prompt
13
+ task_description = extract_task_description(prompt)
14
+
15
+ # Generate task details using AI
16
+ task_details = generate_task_details(task_description, api_key)
17
+
18
+ # Create the task
19
+ create_task_from_details(notebook_name, task_details)
20
+ end
21
+
22
+ # Get the default notebook name or fallback to "default"
23
+ def default_notebook_name
24
+ default_notebook = RubyTodo::Notebook.default_notebook
25
+ default_notebook ? default_notebook.name : "default"
26
+ end
27
+
28
+ # Extract task description from the prompt
29
+ def extract_task_description(prompt)
30
+ if prompt =~ /create(?:\s+a)?\s+(?:new\s+)?task\s+(?:to|for|about)\s+(.+)/i
31
+ Regexp.last_match(1).strip
32
+ else
33
+ ""
34
+ end
35
+ end
36
+
37
+ # Generate task details using AI
38
+ def generate_task_details(task_description, api_key)
39
+ # Build the query for AI
40
+ task_query = build_task_query(task_description)
41
+
42
+ # Query OpenAI for task details
43
+ content = query_openai_for_task_details(task_query, api_key)
44
+
45
+ # Parse the response
46
+ parse_task_details_response(content, task_description)
47
+ end
48
+
49
+ # Build the query to send to OpenAI
50
+ def build_task_query(task_description)
51
+ "Generate a professional task with the following information:\n" \
52
+ "Task description: #{task_description}\n" \
53
+ "Please generate a JSON response with these fields:\n" \
54
+ "- title: A concise, professional title for the task\n" \
55
+ "- description: A detailed description of what the task involves\n" \
56
+ "- priority: Suggested priority (high, medium, or low)\n" \
57
+ "- tags: Relevant tags as a comma-separated string"
58
+ end
59
+ end
60
+
61
+ # Module for OpenAI query related to task creation
62
+ module TaskOpenAIQuery
63
+ # Query OpenAI for task details
64
+ def query_openai_for_task_details(task_query, api_key)
65
+ client = OpenAI::Client.new(access_token: api_key)
66
+ messages = [
67
+ { role: "system", content: "You are a task management assistant that generates professional task details." },
68
+ { role: "user", content: task_query }
69
+ ]
70
+
71
+ say "Generating professional task details..." if @options[:verbose]
72
+
73
+ response = client.chat(parameters: {
74
+ model: "gpt-4o-mini",
75
+ messages: messages,
76
+ temperature: 0.7,
77
+ max_tokens: 500
78
+ })
79
+
80
+ response["choices"][0]["message"]["content"]
81
+ end
82
+ end
83
+
84
+ # Module for parsing and processing AI responses
85
+ module TaskResponseProcessor
86
+ # Parse the OpenAI response for task details
87
+ def parse_task_details_response(content, task_description)
88
+ # Try to extract JSON from the response
89
+ json_match = content.match(/```json\n(.+?)\n```/m) || content.match(/\{.+\}/m)
90
+ if json_match
91
+ json_str = json_match[0].gsub(/```json\n|```/, "")
92
+ JSON.parse(json_str)
93
+ else
94
+ extract_task_details_with_regex(content, task_description)
95
+ end
96
+ rescue JSON::ParserError
97
+ extract_task_details_with_regex(content, task_description)
98
+ end
99
+
100
+ # Extract task details using regex as a fallback
101
+ def extract_task_details_with_regex(content, task_description)
102
+ title_match = content.match(/title["\s:]+([^"]+)["]/i)
103
+ desc_match = content.match(/description["\s:]+([^"]+)["]/i)
104
+ priority_match = content.match(/priority["\s:]+([^"]+)["]/i)
105
+ tags_match = content.match(/tags["\s:]+([^"]+)["]/i)
106
+
107
+ {
108
+ "title" => title_match ? title_match[1] : "Task from #{task_description}",
109
+ "description" => desc_match ? desc_match[1] : task_description,
110
+ "priority" => priority_match ? priority_match[1] : "medium",
111
+ "tags" => tags_match ? tags_match[1] : ""
112
+ }
113
+ end
114
+
115
+ # Create a task from the generated details
116
+ def create_task_from_details(notebook_name, task_details)
117
+ # Ensure we have a valid notebook
118
+ notebook = RubyTodo::Notebook.find_by(name: notebook_name)
119
+ unless notebook
120
+ # Try to create the notebook if it doesn't exist
121
+ RubyTodo::CLI.start(["notebook:create", notebook_name])
122
+ notebook = RubyTodo::Notebook.find_by(name: notebook_name)
123
+ end
124
+
125
+ # Use default notebook as fallback if we couldn't create or find the specified one
126
+ unless notebook
127
+ default_notebook = RubyTodo::Notebook.default_notebook
128
+ notebook_name = default_notebook ? default_notebook.name : "default"
129
+ # Create default notebook if it doesn't exist
130
+ unless RubyTodo::Notebook.find_by(name: notebook_name)
131
+ RubyTodo::CLI.start(["notebook:create", notebook_name])
132
+ end
133
+ end
134
+
135
+ args = ["task:add", notebook_name, task_details["title"]]
136
+ args << "--description" << task_details["description"] if task_details["description"]
137
+ args << "--priority" << task_details["priority"] if task_details["priority"]
138
+ args << "--tags" << task_details["tags"] if task_details["tags"]
139
+
140
+ RubyTodo::CLI.start(args)
141
+ rescue StandardError => e
142
+ say "Error creating task: #{e.message}".red
143
+ say "Attempting simplified task creation...".yellow
144
+
145
+ # Fallback to simplified command
146
+ begin
147
+ RubyTodo::CLI.start(["task:add", notebook_name, task_details["title"]])
148
+ rescue StandardError => e2
149
+ say "Failed to create task: #{e2.message}".red
150
+ end
151
+ end
152
+ end
153
+
154
+ # Include all task creation modules
155
+ module TaskCreatorCombined
156
+ include TaskCreator
157
+ include TaskOpenAIQuery
158
+ include TaskResponseProcessor
159
+ end
160
+ end
161
+ end