fix: Mobile responsiveness for Focus Tools & AI chat improvements
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
Mobile Responsiveness: - Fix headers on all Focus Tools pages (responsive text sizes, proper spacing) - Fix BodyDoublingLobby form grid (stacks on mobile) - Add shrink-0 and min-w-0 to prevent flex overflow issues AI Chat Improvements: - Add labelName parameter to createTask tool for easier label assignment - Auto-match or create labels when labelName is provided - Improve system prompt to act immediately without confirmation - Clearer instructions about using tools and handling labels - Better support for Ollama models with function calling
This commit is contained in:
+55
-14
@@ -60,15 +60,26 @@ Answer the user's questions based on this context. Be concise, helpful, and frie
|
||||
### 🛠️ AVAILABLE TOOLS
|
||||
You can create, search, update, and delete tasks using the provided tools.
|
||||
|
||||
**CRITICAL: ALWAYS USE TOOLS IMMEDIATELY**
|
||||
- When the user asks to create a task, IMMEDIATELY call createTask - DO NOT ask for confirmation.
|
||||
- When the user provides multiple tasks, call createTask for EACH task in parallel.
|
||||
- Never say "I will create..." or "Should I create..." - just DO IT.
|
||||
|
||||
**1. Task Management**
|
||||
- **Create**: Use 'createTask'. Title is required.
|
||||
- *Labels*: Use 'labelName' parameter with the label text (e.g., "Work", "Personal", "Shopping"). The system will automatically match or create the label.
|
||||
- *Bulk Creation*: If the user provides a list of tasks, call 'createTask' multiple times in parallel.
|
||||
- *Relative Dates*: Understand natural language! "Morgen" = Tomorrow, "Next Friday" = Date of next Friday. Always calculate the specific ISO string based on 'Current Date/Time'.
|
||||
- *Priority*: Infer priority from context. Urgent/important = high, regular = medium, minor = low.
|
||||
- *Returns*: The tool returns the created Task ID. Remember this ID for immediate edits.
|
||||
- **Update/Delete**: First SEARCH for the task ID using 'searchTasks' (search by title), then use 'updateTask' or 'deleteTask'.
|
||||
- *Editing Recently Created*: If the user says "Change that to...", refer to the ID of the task you just created.
|
||||
- *Delete All*: Search all, then delete each.
|
||||
- **Labels**: Use 'getLabels' tags.
|
||||
|
||||
### 🏷️ LABEL RULES
|
||||
- When the user mentions a category like "Work task", "Personal errand", "Shopping item" - use the labelName parameter.
|
||||
- Common labels: Work, Personal, Shopping, Health, Finance, Home, Family, Study
|
||||
- The system automatically matches existing labels or creates new ones.
|
||||
|
||||
### 🛡️ SAFETY RULES
|
||||
- **DELETION CONFIRMATION**: Before using 'deleteTask', you MUST:
|
||||
@@ -89,10 +100,12 @@ You can create, search, update, and delete tasks using the provided tools.
|
||||
### 📅 DATE & TIME RULES
|
||||
- **"Today"**: Use the 'Current Date/Time' context.
|
||||
- **"Morgen" / "Tomorrow"**: Add 1 day to Current Date.
|
||||
- **"Next week"**: Add 7 days to Current Date.
|
||||
- **Scheduling**: When using 'scheduleTask', inform the user specifically *when* you scheduled it.
|
||||
|
||||
|
||||
IMPORTANT: Do NOT show Task IDs to the user. Reference tasks by Title.
|
||||
CRITICAL: After executing tools, provide a concise summary of your actions.`;
|
||||
CRITICAL: After executing tools, provide a concise summary of your actions.
|
||||
CRITICAL: ACT IMMEDIATELY. Do not ask for confirmation before creating tasks.`;
|
||||
}
|
||||
|
||||
// Variable replacement if using stored template
|
||||
@@ -311,19 +324,20 @@ CRITICAL: After executing tools, provide a concise summary of your actions.`;
|
||||
type: "function",
|
||||
function: {
|
||||
name: "createTask",
|
||||
description: "Create a new task for the user.",
|
||||
description: "Create a new task for the user. ALWAYS call this tool immediately when the user asks to create a task - do not ask for confirmation first.",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
title: { type: "string", description: "The title of the task (required)." },
|
||||
description: { type: "string" },
|
||||
priority: { type: "string", enum: ["low", "medium", "high"] },
|
||||
status: { type: "string", enum: ["todo", "inProgress", "done"] },
|
||||
dueDate: { type: "string", description: "ISO 8601 format (YYYY-MM-DD)." },
|
||||
labelId: { type: "string" },
|
||||
description: { type: "string", description: "Optional task description." },
|
||||
priority: { type: "string", enum: ["low", "medium", "high"], description: "Task priority. Default: medium." },
|
||||
status: { type: "string", enum: ["todo", "inProgress", "done"], description: "Task status. Default: todo." },
|
||||
dueDate: { type: "string", description: "Due date in ISO 8601 format (YYYY-MM-DD). Calculate from relative dates like 'tomorrow', 'next week'." },
|
||||
labelId: { type: "string", description: "The label ID (UUID). Use getLabels first to find the correct ID." },
|
||||
labelName: { type: "string", description: "Alternative: Label name (e.g., 'Work', 'Personal'). Will be matched or created automatically." },
|
||||
estimatedDuration: { type: "integer", description: "Estimated duration in minutes." },
|
||||
parentTaskId: { type: "string" },
|
||||
startDate: { type: "string" }
|
||||
parentTaskId: { type: "string", description: "Parent task ID for subtasks." },
|
||||
startDate: { type: "string", description: "Start date in ISO 8601 format." }
|
||||
},
|
||||
required: ["title"]
|
||||
}
|
||||
@@ -523,13 +537,40 @@ CRITICAL: After executing tools, provide a concise summary of your actions.`;
|
||||
result = { success: true, labelId: newLabel.id, message: "Label created." };
|
||||
}
|
||||
} else if (fnName === "createTask") {
|
||||
// Handle labelName -> labelId conversion
|
||||
let resolvedLabelId = args.labelId || null;
|
||||
let labelMessage = "";
|
||||
|
||||
if (!resolvedLabelId && args.labelName) {
|
||||
const labels = await this.storage.getLabels(user.id);
|
||||
const matchedLabel = labels.find(l =>
|
||||
l.name.toLowerCase() === args.labelName.toLowerCase() ||
|
||||
l.name.toLowerCase().includes(args.labelName.toLowerCase()) ||
|
||||
args.labelName.toLowerCase().includes(l.name.toLowerCase())
|
||||
);
|
||||
|
||||
if (matchedLabel) {
|
||||
resolvedLabelId = matchedLabel.id;
|
||||
labelMessage = ` with label "${matchedLabel.name}"`;
|
||||
} else {
|
||||
// Create new label if not found
|
||||
const newLabel = await this.storage.createLabel({
|
||||
name: args.labelName,
|
||||
color: "#6366f1",
|
||||
creatorId: user.id
|
||||
});
|
||||
resolvedLabelId = newLabel.id;
|
||||
labelMessage = ` with new label "${args.labelName}"`;
|
||||
}
|
||||
}
|
||||
|
||||
const taskData = {
|
||||
title: args.title,
|
||||
description: args.description || null,
|
||||
priority: args.priority || "medium",
|
||||
status: args.status || "todo",
|
||||
dueDate: args.dueDate ? new Date(args.dueDate) : null,
|
||||
labelId: args.labelId || null,
|
||||
labelId: resolvedLabelId,
|
||||
estimatedDuration: args.estimatedDuration || null,
|
||||
parentTaskId: args.parentTaskId || null,
|
||||
startDate: args.startDate ? new Date(args.startDate) : null,
|
||||
@@ -541,10 +582,10 @@ CRITICAL: After executing tools, provide a concise summary of your actions.`;
|
||||
action: "CREATE",
|
||||
entityType: "TASK",
|
||||
entityId: createdTask.id,
|
||||
details: { title: createdTask.title },
|
||||
details: { title: createdTask.title, labelId: resolvedLabelId },
|
||||
source: "AI"
|
||||
});
|
||||
result = { success: true, taskId: createdTask.id, message: "Task created." };
|
||||
result = { success: true, taskId: createdTask.id, message: `Task created${labelMessage}.` };
|
||||
} else if (fnName === "searchTasks") {
|
||||
const tasks = await this.storage.searchTasks(args.query, user.id);
|
||||
const labels = await this.storage.getLabels(user.id);
|
||||
|
||||
Reference in New Issue
Block a user