stagent 0.5.0 → 0.6.0
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.
- package/README.md +8 -8
- package/dist/cli.js +146 -2
- package/docs/.coverage-gaps.json +21 -0
- package/docs/.last-generated +1 -1
- package/docs/features/agent-intelligence.md +36 -14
- package/docs/features/chat.md +33 -56
- package/docs/features/cost-usage.md +14 -10
- package/docs/features/dashboard-kanban.md +30 -13
- package/docs/features/delivery-channels.md +198 -0
- package/docs/features/design-system.md +10 -10
- package/docs/features/documents.md +8 -8
- package/docs/features/home-workspace.md +20 -15
- package/docs/features/inbox-notifications.md +22 -10
- package/docs/features/keyboard-navigation.md +11 -11
- package/docs/features/monitoring.md +1 -1
- package/docs/features/playbook.md +30 -32
- package/docs/features/profiles.md +33 -11
- package/docs/features/projects.md +2 -2
- package/docs/features/provider-runtimes.md +58 -14
- package/docs/features/schedules.md +70 -40
- package/docs/features/settings.md +74 -46
- package/docs/features/shared-components.md +7 -15
- package/docs/features/tool-permissions.md +9 -9
- package/docs/features/workflows.md +32 -21
- package/docs/getting-started.md +33 -9
- package/docs/index.md +25 -16
- package/docs/journeys/developer.md +124 -207
- package/docs/journeys/personal-use.md +70 -79
- package/docs/journeys/power-user.md +107 -151
- package/docs/journeys/work-use.md +81 -113
- package/docs/manifest.json +77 -45
- package/docs/superpowers/plans/2026-03-30-finish-in-progress-features.md +547 -0
- package/docs/use-cases/agency-operator.md +84 -0
- package/docs/use-cases/solo-founder.md +75 -0
- package/docs/why-stagent.md +59 -0
- package/package.json +10 -3
- package/src/app/api/channels/[id]/route.ts +103 -0
- package/src/app/api/channels/[id]/test/route.ts +52 -0
- package/src/app/api/channels/inbound/slack/route.ts +109 -0
- package/src/app/api/channels/inbound/telegram/poll/route.ts +128 -0
- package/src/app/api/channels/inbound/telegram/route.ts +76 -0
- package/src/app/api/channels/route.ts +71 -0
- package/src/app/api/chat/conversations/route.ts +15 -0
- package/src/app/api/chat/entities/search/route.ts +46 -31
- package/src/app/api/environment/profiles/suggest/route.ts +19 -3
- package/src/app/api/environment/scan/route.ts +8 -1
- package/src/app/api/handoffs/[id]/route.ts +76 -0
- package/src/app/api/handoffs/route.ts +89 -0
- package/src/app/api/memory/route.ts +181 -0
- package/src/app/api/profiles/[id]/route.ts +16 -1
- package/src/app/api/profiles/[id]/test/route.ts +4 -0
- package/src/app/api/profiles/[id]/test-results/route.ts +22 -0
- package/src/app/api/profiles/[id]/test-single/route.ts +64 -0
- package/src/app/api/profiles/assist/route.ts +35 -0
- package/src/app/api/profiles/import-repo/apply-updates/route.ts +123 -0
- package/src/app/api/profiles/import-repo/check-updates/route.ts +163 -0
- package/src/app/api/profiles/import-repo/confirm/route.ts +118 -0
- package/src/app/api/profiles/import-repo/preview/route.ts +107 -0
- package/src/app/api/profiles/import-repo/route.ts +29 -0
- package/src/app/api/profiles/import-repo/scan/route.ts +25 -0
- package/src/app/api/profiles/route.ts +73 -22
- package/src/app/api/runtimes/ollama/route.ts +86 -0
- package/src/app/api/runtimes/suggest/route.ts +29 -0
- package/src/app/api/schedules/[id]/heartbeat-history/route.ts +77 -0
- package/src/app/api/schedules/[id]/route.ts +41 -3
- package/src/app/api/schedules/parse/route.ts +66 -0
- package/src/app/api/schedules/route.ts +71 -12
- package/src/app/api/settings/author-default/route.ts +7 -0
- package/src/app/api/settings/learning/route.ts +41 -0
- package/src/app/api/settings/ollama/route.ts +34 -0
- package/src/app/api/settings/providers/route.ts +57 -0
- package/src/app/api/settings/routing/route.ts +24 -0
- package/src/app/api/settings/web-search/route.ts +28 -0
- package/src/app/api/tasks/[id]/execute/route.ts +13 -1
- package/src/app/documents/page.tsx +3 -0
- package/src/app/environment/page.tsx +8 -1
- package/src/app/settings/page.tsx +10 -4
- package/src/app/workflows/[id]/edit/page.tsx +2 -0
- package/src/app/workflows/new/page.tsx +2 -0
- package/src/components/chat/chat-command-popover.tsx +22 -19
- package/src/components/chat/chat-input.tsx +5 -0
- package/src/components/chat/chat-model-selector.tsx +42 -1
- package/src/components/chat/chat-shell.tsx +2 -0
- package/src/components/dashboard/welcome-landing.tsx +9 -9
- package/src/components/environment/artifact-card.tsx +27 -1
- package/src/components/environment/environment-dashboard.tsx +50 -2
- package/src/components/environment/environment-summary-card.tsx +5 -2
- package/src/components/environment/suggested-profiles.tsx +117 -52
- package/src/components/handoffs/handoff-approval-card.tsx +159 -0
- package/src/components/memory/memory-browser.tsx +315 -0
- package/src/components/profiles/learned-context-panel.tsx +4 -4
- package/src/components/profiles/profile-assist-panel.tsx +512 -0
- package/src/components/profiles/profile-browser.tsx +109 -8
- package/src/components/profiles/profile-card.tsx +29 -1
- package/src/components/profiles/profile-detail-view.tsx +200 -28
- package/src/components/profiles/profile-form-view.tsx +220 -82
- package/src/components/profiles/repo-import-wizard.tsx +648 -0
- package/src/components/profiles/smoke-test-editor.tsx +106 -0
- package/src/components/schedules/schedule-create-sheet.tsx +9 -1
- package/src/components/schedules/schedule-form.tsx +348 -9
- package/src/components/schedules/schedule-list.tsx +15 -2
- package/src/components/settings/auth-method-selector.tsx +7 -1
- package/src/components/settings/budget-guardrails-section.tsx +111 -48
- package/src/components/settings/channels-section.tsx +526 -0
- package/src/components/settings/chat-settings-section.tsx +27 -1
- package/src/components/settings/data-management-section.tsx +8 -6
- package/src/components/settings/learning-context-section.tsx +124 -0
- package/src/components/settings/ollama-section.tsx +270 -0
- package/src/components/settings/providers-runtimes-section.tsx +499 -0
- package/src/components/settings/web-search-section.tsx +101 -0
- package/src/components/shared/tag-input.tsx +156 -0
- package/src/components/tasks/kanban-board.tsx +32 -0
- package/src/components/tasks/kanban-column.tsx +4 -2
- package/src/components/tasks/task-card.tsx +1 -0
- package/src/components/tasks/task-chip-bar.tsx +6 -1
- package/src/components/tasks/task-create-panel.tsx +55 -5
- package/src/components/workflows/workflow-form-view.tsx +38 -3
- package/src/hooks/use-chat-autocomplete.ts +24 -26
- package/src/hooks/use-project-skills.ts +66 -0
- package/src/hooks/use-tag-suggestions.ts +31 -0
- package/src/instrumentation.ts +4 -1
- package/src/lib/agents/__tests__/claude-agent.test.ts +3 -0
- package/src/lib/agents/__tests__/learned-context.test.ts +10 -0
- package/src/lib/agents/agentic-loop.ts +235 -0
- package/src/lib/agents/browser-mcp.ts +59 -4
- package/src/lib/agents/claude-agent.ts +26 -199
- package/src/lib/agents/handoff/bus.ts +164 -0
- package/src/lib/agents/handoff/governance.ts +47 -0
- package/src/lib/agents/handoff/types.ts +16 -0
- package/src/lib/agents/learned-context.ts +27 -7
- package/src/lib/agents/memory/decay.ts +61 -0
- package/src/lib/agents/memory/extractor.ts +181 -0
- package/src/lib/agents/memory/retrieval.ts +96 -0
- package/src/lib/agents/memory/types.ts +6 -0
- package/src/lib/agents/profiles/__tests__/project-profiles.test.ts +119 -0
- package/src/lib/agents/profiles/__tests__/registry.test.ts +11 -3
- package/src/lib/agents/profiles/builtins/code-reviewer/profile.yaml +2 -2
- package/src/lib/agents/profiles/builtins/content-creator/SKILL.md +19 -0
- package/src/lib/agents/profiles/builtins/content-creator/profile.yaml +27 -0
- package/src/lib/agents/profiles/builtins/customer-support-agent/SKILL.md +19 -0
- package/src/lib/agents/profiles/builtins/customer-support-agent/profile.yaml +26 -0
- package/src/lib/agents/profiles/builtins/data-analyst/profile.yaml +2 -2
- package/src/lib/agents/profiles/builtins/devops-engineer/profile.yaml +2 -2
- package/src/lib/agents/profiles/builtins/document-writer/profile.yaml +2 -2
- package/src/lib/agents/profiles/builtins/financial-analyst/SKILL.md +19 -0
- package/src/lib/agents/profiles/builtins/financial-analyst/profile.yaml +24 -0
- package/src/lib/agents/profiles/builtins/general/profile.yaml +2 -2
- package/src/lib/agents/profiles/builtins/health-fitness-coach/profile.yaml +2 -2
- package/src/lib/agents/profiles/builtins/learning-coach/profile.yaml +2 -2
- package/src/lib/agents/profiles/builtins/marketing-strategist/SKILL.md +19 -0
- package/src/lib/agents/profiles/builtins/marketing-strategist/profile.yaml +27 -0
- package/src/lib/agents/profiles/builtins/operations-coordinator/SKILL.md +19 -0
- package/src/lib/agents/profiles/builtins/operations-coordinator/profile.yaml +26 -0
- package/src/lib/agents/profiles/builtins/project-manager/profile.yaml +2 -2
- package/src/lib/agents/profiles/builtins/researcher/SKILL.md +1 -0
- package/src/lib/agents/profiles/builtins/researcher/profile.yaml +2 -2
- package/src/lib/agents/profiles/builtins/sales-researcher/SKILL.md +19 -0
- package/src/lib/agents/profiles/builtins/sales-researcher/profile.yaml +26 -0
- package/src/lib/agents/profiles/builtins/shopping-assistant/SKILL.md +1 -0
- package/src/lib/agents/profiles/builtins/shopping-assistant/profile.yaml +2 -2
- package/src/lib/agents/profiles/builtins/sweep/profile.yaml +1 -1
- package/src/lib/agents/profiles/builtins/technical-writer/profile.yaml +2 -2
- package/src/lib/agents/profiles/builtins/travel-planner/SKILL.md +2 -0
- package/src/lib/agents/profiles/builtins/travel-planner/profile.yaml +2 -2
- package/src/lib/agents/profiles/builtins/wealth-manager/SKILL.md +2 -0
- package/src/lib/agents/profiles/builtins/wealth-manager/profile.yaml +2 -2
- package/src/lib/agents/profiles/project-profiles.ts +193 -0
- package/src/lib/agents/profiles/registry.ts +130 -6
- package/src/lib/agents/profiles/types.ts +28 -0
- package/src/lib/agents/router.ts +174 -2
- package/src/lib/agents/runtime/__tests__/catalog.test.ts +15 -4
- package/src/lib/agents/runtime/anthropic-direct.ts +644 -0
- package/src/lib/agents/runtime/catalog.ts +57 -2
- package/src/lib/agents/runtime/claude.ts +205 -1
- package/src/lib/agents/runtime/index.ts +22 -0
- package/src/lib/agents/runtime/ollama-adapter.ts +409 -0
- package/src/lib/agents/runtime/openai-direct.ts +514 -0
- package/src/lib/agents/runtime/profile-assist-types.ts +30 -0
- package/src/lib/agents/runtime/types.ts +2 -0
- package/src/lib/agents/tool-permissions.ts +203 -0
- package/src/lib/channels/gateway.ts +321 -0
- package/src/lib/channels/poller.ts +268 -0
- package/src/lib/channels/registry.ts +90 -0
- package/src/lib/channels/slack-adapter.ts +188 -0
- package/src/lib/channels/telegram-adapter.ts +218 -0
- package/src/lib/channels/types.ts +43 -0
- package/src/lib/channels/webhook-adapter.ts +74 -0
- package/src/lib/chat/context-builder.ts +22 -2
- package/src/lib/chat/engine.ts +95 -13
- package/src/lib/chat/ollama-engine.ts +198 -0
- package/src/lib/chat/stagent-tools.ts +106 -20
- package/src/lib/chat/tool-catalog.ts +24 -0
- package/src/lib/chat/tool-registry.ts +90 -0
- package/src/lib/chat/tools/chat-history-tools.ts +4 -4
- package/src/lib/chat/tools/document-tools.ts +7 -7
- package/src/lib/chat/tools/handoff-tools.ts +70 -0
- package/src/lib/chat/tools/notification-tools.ts +4 -4
- package/src/lib/chat/tools/profile-tools.ts +3 -3
- package/src/lib/chat/tools/project-tools.ts +3 -3
- package/src/lib/chat/tools/schedule-tools.ts +29 -13
- package/src/lib/chat/tools/settings-tools.ts +2 -2
- package/src/lib/chat/tools/task-tools.ts +66 -11
- package/src/lib/chat/tools/usage-tools.ts +2 -2
- package/src/lib/chat/tools/workflow-tools.ts +8 -8
- package/src/lib/chat/types.ts +11 -5
- package/src/lib/constants/known-tools.ts +19 -0
- package/src/lib/constants/prose-styles.ts +1 -1
- package/src/lib/constants/settings.ts +7 -0
- package/src/lib/data/channel-bindings.ts +85 -0
- package/src/lib/data/clear.ts +22 -0
- package/src/lib/data/profile-test-results.ts +48 -0
- package/src/lib/data/seed-data/conversations.ts +196 -0
- package/src/lib/data/seed-data/learned-context.ts +99 -0
- package/src/lib/data/seed-data/notifications.ts +54 -1
- package/src/lib/data/seed-data/profile-test-results.ts +96 -0
- package/src/lib/data/seed-data/repo-imports.ts +51 -0
- package/src/lib/data/seed-data/views.ts +60 -0
- package/src/lib/data/seed.ts +51 -0
- package/src/lib/db/bootstrap.ts +162 -0
- package/src/lib/db/migrations/0013_add_repo_imports.sql +15 -0
- package/src/lib/db/migrations/0014_add_linked_profile_id.sql +3 -0
- package/src/lib/db/migrations/0015_add_channel_bindings.sql +23 -0
- package/src/lib/db/schema.ts +187 -1
- package/src/lib/environment/__tests__/auto-scan.test.ts +86 -0
- package/src/lib/environment/__tests__/profile-linker.test.ts +187 -0
- package/src/lib/environment/auto-scan.ts +48 -0
- package/src/lib/environment/data.ts +25 -0
- package/src/lib/environment/profile-generator.ts +40 -10
- package/src/lib/environment/profile-linker.ts +143 -0
- package/src/lib/environment/profile-rules.ts +96 -0
- package/src/lib/import/dedup.ts +149 -0
- package/src/lib/import/format-adapter.ts +631 -0
- package/src/lib/import/github-api.ts +219 -0
- package/src/lib/import/repo-scanner.ts +251 -0
- package/src/lib/schedules/__tests__/nlp-parser.test.ts +330 -0
- package/src/lib/schedules/active-hours.ts +120 -0
- package/src/lib/schedules/heartbeat-parser.ts +224 -0
- package/src/lib/schedules/heartbeat-prompt.ts +153 -0
- package/src/lib/schedules/nlp-parser.ts +357 -0
- package/src/lib/schedules/scheduler.ts +218 -3
- package/src/lib/settings/__tests__/budget-guardrails.test.ts +39 -1
- package/src/lib/settings/helpers.ts +6 -0
- package/src/lib/settings/routing.ts +24 -0
- package/src/lib/settings/runtime-setup.ts +28 -1
- package/src/lib/usage/ledger.ts +2 -1
- package/src/lib/validators/__tests__/settings.test.ts +9 -0
- package/src/lib/validators/profile.ts +39 -0
- package/src/lib/workflows/blueprints/builtins/business-daily-briefing.yaml +102 -0
- package/src/lib/workflows/blueprints/builtins/content-marketing-pipeline.yaml +90 -0
- package/src/lib/workflows/blueprints/builtins/customer-support-triage.yaml +107 -0
- package/src/lib/workflows/blueprints/builtins/financial-reporting.yaml +104 -0
- package/src/lib/workflows/blueprints/builtins/lead-research-pipeline.yaml +82 -0
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState, useCallback } from "react";
|
|
4
|
+
import {
|
|
5
|
+
Send,
|
|
6
|
+
Plus,
|
|
7
|
+
Trash2,
|
|
8
|
+
Zap,
|
|
9
|
+
MessageSquare,
|
|
10
|
+
Globe,
|
|
11
|
+
CheckCircle2,
|
|
12
|
+
XCircle,
|
|
13
|
+
MinusCircle,
|
|
14
|
+
Loader2,
|
|
15
|
+
} from "lucide-react";
|
|
16
|
+
import { toast } from "sonner";
|
|
17
|
+
import {
|
|
18
|
+
Card,
|
|
19
|
+
CardContent,
|
|
20
|
+
CardDescription,
|
|
21
|
+
CardHeader,
|
|
22
|
+
CardTitle,
|
|
23
|
+
} from "@/components/ui/card";
|
|
24
|
+
import { Button } from "@/components/ui/button";
|
|
25
|
+
import { Input } from "@/components/ui/input";
|
|
26
|
+
import { Label } from "@/components/ui/label";
|
|
27
|
+
import { Switch } from "@/components/ui/switch";
|
|
28
|
+
import { Badge } from "@/components/ui/badge";
|
|
29
|
+
import {
|
|
30
|
+
Dialog,
|
|
31
|
+
DialogContent,
|
|
32
|
+
DialogDescription,
|
|
33
|
+
DialogFooter,
|
|
34
|
+
DialogHeader,
|
|
35
|
+
DialogTitle,
|
|
36
|
+
DialogTrigger,
|
|
37
|
+
} from "@/components/ui/dialog";
|
|
38
|
+
import {
|
|
39
|
+
Select,
|
|
40
|
+
SelectContent,
|
|
41
|
+
SelectItem,
|
|
42
|
+
SelectTrigger,
|
|
43
|
+
SelectValue,
|
|
44
|
+
} from "@/components/ui/select";
|
|
45
|
+
|
|
46
|
+
interface ChannelConfig {
|
|
47
|
+
id: string;
|
|
48
|
+
channelType: "slack" | "telegram" | "webhook";
|
|
49
|
+
name: string;
|
|
50
|
+
config: string;
|
|
51
|
+
status: "active" | "disabled";
|
|
52
|
+
testStatus: "untested" | "ok" | "failed";
|
|
53
|
+
direction: "outbound" | "bidirectional";
|
|
54
|
+
createdAt: string;
|
|
55
|
+
updatedAt: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const CHANNEL_ICONS: Record<string, typeof Send> = {
|
|
59
|
+
slack: Zap,
|
|
60
|
+
telegram: MessageSquare,
|
|
61
|
+
webhook: Globe,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const TEST_STATUS_ICONS: Record<string, typeof CheckCircle2> = {
|
|
65
|
+
ok: CheckCircle2,
|
|
66
|
+
failed: XCircle,
|
|
67
|
+
untested: MinusCircle,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const TEST_STATUS_COLORS: Record<string, string> = {
|
|
71
|
+
ok: "text-green-600",
|
|
72
|
+
failed: "text-red-600",
|
|
73
|
+
untested: "text-muted-foreground",
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export function ChannelsSection() {
|
|
77
|
+
const [channels, setChannels] = useState<ChannelConfig[]>([]);
|
|
78
|
+
const [dialogOpen, setDialogOpen] = useState(false);
|
|
79
|
+
const [testingId, setTestingId] = useState<string | null>(null);
|
|
80
|
+
|
|
81
|
+
// Form state
|
|
82
|
+
const [formType, setFormType] = useState<"slack" | "telegram" | "webhook">("slack");
|
|
83
|
+
const [formName, setFormName] = useState("");
|
|
84
|
+
const [formWebhookUrl, setFormWebhookUrl] = useState("");
|
|
85
|
+
const [formBotToken, setFormBotToken] = useState("");
|
|
86
|
+
const [formChatId, setFormChatId] = useState("");
|
|
87
|
+
const [formUrl, setFormUrl] = useState("");
|
|
88
|
+
const [formHeaders, setFormHeaders] = useState("");
|
|
89
|
+
// Slack bidirectional fields
|
|
90
|
+
const [formSlackBotToken, setFormSlackBotToken] = useState("");
|
|
91
|
+
const [formSigningSecret, setFormSigningSecret] = useState("");
|
|
92
|
+
const [formSlackChannelId, setFormSlackChannelId] = useState("");
|
|
93
|
+
const [saving, setSaving] = useState(false);
|
|
94
|
+
|
|
95
|
+
const fetchChannels = useCallback(async () => {
|
|
96
|
+
try {
|
|
97
|
+
const res = await fetch("/api/channels");
|
|
98
|
+
if (res.ok) {
|
|
99
|
+
const data = await res.json();
|
|
100
|
+
setChannels(data);
|
|
101
|
+
}
|
|
102
|
+
} catch {
|
|
103
|
+
// Ignore
|
|
104
|
+
}
|
|
105
|
+
}, []);
|
|
106
|
+
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
fetchChannels();
|
|
109
|
+
}, [fetchChannels]);
|
|
110
|
+
|
|
111
|
+
const resetForm = () => {
|
|
112
|
+
setFormType("slack");
|
|
113
|
+
setFormName("");
|
|
114
|
+
setFormWebhookUrl("");
|
|
115
|
+
setFormBotToken("");
|
|
116
|
+
setFormChatId("");
|
|
117
|
+
setFormUrl("");
|
|
118
|
+
setFormHeaders("");
|
|
119
|
+
setFormSlackBotToken("");
|
|
120
|
+
setFormSigningSecret("");
|
|
121
|
+
setFormSlackChannelId("");
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const handleCreate = async () => {
|
|
125
|
+
let config: Record<string, unknown> = {};
|
|
126
|
+
if (formType === "slack") {
|
|
127
|
+
config = { webhookUrl: formWebhookUrl };
|
|
128
|
+
// Include bidirectional fields if provided
|
|
129
|
+
if (formSlackBotToken.trim()) config.botToken = formSlackBotToken.trim();
|
|
130
|
+
if (formSigningSecret.trim()) config.signingSecret = formSigningSecret.trim();
|
|
131
|
+
if (formSlackChannelId.trim()) config.slackChannelId = formSlackChannelId.trim();
|
|
132
|
+
} else if (formType === "telegram") {
|
|
133
|
+
config = { botToken: formBotToken, chatId: formChatId };
|
|
134
|
+
} else {
|
|
135
|
+
let headers: Record<string, string> | undefined;
|
|
136
|
+
if (formHeaders.trim()) {
|
|
137
|
+
try {
|
|
138
|
+
headers = JSON.parse(formHeaders);
|
|
139
|
+
} catch {
|
|
140
|
+
toast.error("Invalid headers JSON");
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
config = { url: formUrl, ...(headers ? { headers } : {}) };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
setSaving(true);
|
|
148
|
+
try {
|
|
149
|
+
const res = await fetch("/api/channels", {
|
|
150
|
+
method: "POST",
|
|
151
|
+
headers: { "Content-Type": "application/json" },
|
|
152
|
+
body: JSON.stringify({
|
|
153
|
+
channelType: formType,
|
|
154
|
+
name: formName,
|
|
155
|
+
config,
|
|
156
|
+
}),
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
if (res.ok) {
|
|
160
|
+
toast.success("Channel created");
|
|
161
|
+
setDialogOpen(false);
|
|
162
|
+
resetForm();
|
|
163
|
+
fetchChannels();
|
|
164
|
+
} else {
|
|
165
|
+
const data = await res.json();
|
|
166
|
+
toast.error(data.error ?? "Failed to create channel");
|
|
167
|
+
}
|
|
168
|
+
} catch {
|
|
169
|
+
toast.error("Failed to create channel");
|
|
170
|
+
} finally {
|
|
171
|
+
setSaving(false);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
const handleToggle = async (id: string, currentStatus: string) => {
|
|
176
|
+
const newStatus = currentStatus === "active" ? "disabled" : "active";
|
|
177
|
+
try {
|
|
178
|
+
const res = await fetch(`/api/channels/${id}`, {
|
|
179
|
+
method: "PATCH",
|
|
180
|
+
headers: { "Content-Type": "application/json" },
|
|
181
|
+
body: JSON.stringify({ status: newStatus }),
|
|
182
|
+
});
|
|
183
|
+
if (res.ok) {
|
|
184
|
+
toast.success(`Channel ${newStatus === "active" ? "enabled" : "disabled"}`);
|
|
185
|
+
fetchChannels();
|
|
186
|
+
}
|
|
187
|
+
} catch {
|
|
188
|
+
toast.error("Failed to update channel");
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const handleTest = async (id: string) => {
|
|
193
|
+
setTestingId(id);
|
|
194
|
+
try {
|
|
195
|
+
const res = await fetch(`/api/channels/${id}/test`, { method: "POST" });
|
|
196
|
+
const data = await res.json();
|
|
197
|
+
if (data.testStatus === "ok") {
|
|
198
|
+
toast.success("Connection test passed");
|
|
199
|
+
} else {
|
|
200
|
+
toast.error(`Test failed: ${data.error}`);
|
|
201
|
+
}
|
|
202
|
+
fetchChannels();
|
|
203
|
+
} catch {
|
|
204
|
+
toast.error("Failed to test channel");
|
|
205
|
+
} finally {
|
|
206
|
+
setTestingId(null);
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
const handleDelete = async (id: string) => {
|
|
211
|
+
try {
|
|
212
|
+
const res = await fetch(`/api/channels/${id}`, { method: "DELETE" });
|
|
213
|
+
if (res.ok) {
|
|
214
|
+
toast.success("Channel deleted");
|
|
215
|
+
fetchChannels();
|
|
216
|
+
}
|
|
217
|
+
} catch {
|
|
218
|
+
toast.error("Failed to delete channel");
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
const handleDirectionToggle = async (ch: ChannelConfig) => {
|
|
223
|
+
const newDirection = ch.direction === "outbound" ? "bidirectional" : "outbound";
|
|
224
|
+
try {
|
|
225
|
+
const res = await fetch(`/api/channels/${ch.id}`, {
|
|
226
|
+
method: "PATCH",
|
|
227
|
+
headers: { "Content-Type": "application/json" },
|
|
228
|
+
body: JSON.stringify({ direction: newDirection }),
|
|
229
|
+
});
|
|
230
|
+
if (res.ok) {
|
|
231
|
+
toast.success(
|
|
232
|
+
newDirection === "bidirectional"
|
|
233
|
+
? "Bidirectional chat enabled"
|
|
234
|
+
: "Reverted to outbound-only"
|
|
235
|
+
);
|
|
236
|
+
fetchChannels();
|
|
237
|
+
}
|
|
238
|
+
} catch {
|
|
239
|
+
toast.error("Failed to update direction");
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const getWebhookUrl = (ch: ChannelConfig): string => {
|
|
244
|
+
const base = typeof window !== "undefined" ? window.location.origin : "";
|
|
245
|
+
if (ch.channelType === "telegram") {
|
|
246
|
+
return `${base}/api/channels/inbound/telegram?configId=${ch.id}`;
|
|
247
|
+
}
|
|
248
|
+
if (ch.channelType === "slack") {
|
|
249
|
+
return `${base}/api/channels/inbound/slack?configId=${ch.id}`;
|
|
250
|
+
}
|
|
251
|
+
return `${base}/api/channels/inbound/webhook?configId=${ch.id}`;
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
return (
|
|
255
|
+
<Card>
|
|
256
|
+
<CardHeader>
|
|
257
|
+
<div className="flex items-center justify-between">
|
|
258
|
+
<div>
|
|
259
|
+
<CardTitle className="flex items-center gap-2">
|
|
260
|
+
<Send className="h-5 w-5" />
|
|
261
|
+
Delivery Channels
|
|
262
|
+
</CardTitle>
|
|
263
|
+
<CardDescription>
|
|
264
|
+
Configure Slack, Telegram, or webhook channels for schedule notifications
|
|
265
|
+
and agent output delivery.
|
|
266
|
+
</CardDescription>
|
|
267
|
+
</div>
|
|
268
|
+
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
|
|
269
|
+
<DialogTrigger asChild>
|
|
270
|
+
<Button size="sm" onClick={resetForm}>
|
|
271
|
+
<Plus className="mr-1 h-4 w-4" />
|
|
272
|
+
Add Channel
|
|
273
|
+
</Button>
|
|
274
|
+
</DialogTrigger>
|
|
275
|
+
<DialogContent>
|
|
276
|
+
<DialogHeader>
|
|
277
|
+
<DialogTitle>Add Delivery Channel</DialogTitle>
|
|
278
|
+
<DialogDescription>
|
|
279
|
+
Configure a new channel for delivering notifications and results.
|
|
280
|
+
</DialogDescription>
|
|
281
|
+
</DialogHeader>
|
|
282
|
+
<div className="space-y-4">
|
|
283
|
+
<div className="space-y-2">
|
|
284
|
+
<Label>Channel Type</Label>
|
|
285
|
+
<Select value={formType} onValueChange={(v) => setFormType(v as typeof formType)}>
|
|
286
|
+
<SelectTrigger>
|
|
287
|
+
<SelectValue />
|
|
288
|
+
</SelectTrigger>
|
|
289
|
+
<SelectContent>
|
|
290
|
+
<SelectItem value="slack">Slack</SelectItem>
|
|
291
|
+
<SelectItem value="telegram">Telegram</SelectItem>
|
|
292
|
+
<SelectItem value="webhook">Webhook</SelectItem>
|
|
293
|
+
</SelectContent>
|
|
294
|
+
</Select>
|
|
295
|
+
</div>
|
|
296
|
+
|
|
297
|
+
<div className="space-y-2">
|
|
298
|
+
<Label>Name</Label>
|
|
299
|
+
<Input
|
|
300
|
+
placeholder="e.g. Team Notifications"
|
|
301
|
+
value={formName}
|
|
302
|
+
onChange={(e) => setFormName(e.target.value)}
|
|
303
|
+
/>
|
|
304
|
+
</div>
|
|
305
|
+
|
|
306
|
+
{formType === "slack" && (
|
|
307
|
+
<>
|
|
308
|
+
<div className="space-y-2">
|
|
309
|
+
<Label>Webhook URL</Label>
|
|
310
|
+
<Input
|
|
311
|
+
placeholder="https://hooks.slack.com/services/..."
|
|
312
|
+
value={formWebhookUrl}
|
|
313
|
+
onChange={(e) => setFormWebhookUrl(e.target.value)}
|
|
314
|
+
/>
|
|
315
|
+
</div>
|
|
316
|
+
<div className="space-y-2">
|
|
317
|
+
<Label>
|
|
318
|
+
Bot Token{" "}
|
|
319
|
+
<span className="text-muted-foreground font-normal">
|
|
320
|
+
(for bidirectional chat)
|
|
321
|
+
</span>
|
|
322
|
+
</Label>
|
|
323
|
+
<Input
|
|
324
|
+
placeholder="xoxb-..."
|
|
325
|
+
value={formSlackBotToken}
|
|
326
|
+
onChange={(e) => setFormSlackBotToken(e.target.value)}
|
|
327
|
+
/>
|
|
328
|
+
</div>
|
|
329
|
+
<div className="space-y-2">
|
|
330
|
+
<Label>
|
|
331
|
+
Signing Secret{" "}
|
|
332
|
+
<span className="text-muted-foreground font-normal">
|
|
333
|
+
(for bidirectional chat)
|
|
334
|
+
</span>
|
|
335
|
+
</Label>
|
|
336
|
+
<Input
|
|
337
|
+
placeholder="From Basic Information → App Credentials"
|
|
338
|
+
value={formSigningSecret}
|
|
339
|
+
onChange={(e) => setFormSigningSecret(e.target.value)}
|
|
340
|
+
/>
|
|
341
|
+
</div>
|
|
342
|
+
<div className="space-y-2">
|
|
343
|
+
<Label>
|
|
344
|
+
Channel ID{" "}
|
|
345
|
+
<span className="text-muted-foreground font-normal">
|
|
346
|
+
(for bidirectional chat)
|
|
347
|
+
</span>
|
|
348
|
+
</Label>
|
|
349
|
+
<Input
|
|
350
|
+
placeholder="C0123456789"
|
|
351
|
+
value={formSlackChannelId}
|
|
352
|
+
onChange={(e) => setFormSlackChannelId(e.target.value)}
|
|
353
|
+
/>
|
|
354
|
+
</div>
|
|
355
|
+
</>
|
|
356
|
+
)}
|
|
357
|
+
|
|
358
|
+
{formType === "telegram" && (
|
|
359
|
+
<>
|
|
360
|
+
<div className="space-y-2">
|
|
361
|
+
<Label>Bot Token</Label>
|
|
362
|
+
<Input
|
|
363
|
+
placeholder="123456:ABC-DEF..."
|
|
364
|
+
value={formBotToken}
|
|
365
|
+
onChange={(e) => setFormBotToken(e.target.value)}
|
|
366
|
+
/>
|
|
367
|
+
</div>
|
|
368
|
+
<div className="space-y-2">
|
|
369
|
+
<Label>Chat ID</Label>
|
|
370
|
+
<Input
|
|
371
|
+
placeholder="-1001234567890"
|
|
372
|
+
value={formChatId}
|
|
373
|
+
onChange={(e) => setFormChatId(e.target.value)}
|
|
374
|
+
/>
|
|
375
|
+
</div>
|
|
376
|
+
</>
|
|
377
|
+
)}
|
|
378
|
+
|
|
379
|
+
{formType === "webhook" && (
|
|
380
|
+
<>
|
|
381
|
+
<div className="space-y-2">
|
|
382
|
+
<Label>URL</Label>
|
|
383
|
+
<Input
|
|
384
|
+
placeholder="https://example.com/webhook"
|
|
385
|
+
value={formUrl}
|
|
386
|
+
onChange={(e) => setFormUrl(e.target.value)}
|
|
387
|
+
/>
|
|
388
|
+
</div>
|
|
389
|
+
<div className="space-y-2">
|
|
390
|
+
<Label>Custom Headers (JSON, optional)</Label>
|
|
391
|
+
<Input
|
|
392
|
+
placeholder='{"Authorization": "Bearer ..."}'
|
|
393
|
+
value={formHeaders}
|
|
394
|
+
onChange={(e) => setFormHeaders(e.target.value)}
|
|
395
|
+
/>
|
|
396
|
+
</div>
|
|
397
|
+
</>
|
|
398
|
+
)}
|
|
399
|
+
</div>
|
|
400
|
+
<DialogFooter>
|
|
401
|
+
<Button variant="outline" onClick={() => setDialogOpen(false)}>
|
|
402
|
+
Cancel
|
|
403
|
+
</Button>
|
|
404
|
+
<Button onClick={handleCreate} disabled={saving || !formName.trim()}>
|
|
405
|
+
{saving ? "Creating..." : "Create Channel"}
|
|
406
|
+
</Button>
|
|
407
|
+
</DialogFooter>
|
|
408
|
+
</DialogContent>
|
|
409
|
+
</Dialog>
|
|
410
|
+
</div>
|
|
411
|
+
</CardHeader>
|
|
412
|
+
<CardContent>
|
|
413
|
+
{channels.length === 0 ? (
|
|
414
|
+
<p className="text-sm text-muted-foreground py-4 text-center">
|
|
415
|
+
No delivery channels configured. Add one to start receiving notifications.
|
|
416
|
+
</p>
|
|
417
|
+
) : (
|
|
418
|
+
<div className="space-y-3">
|
|
419
|
+
{channels.map((ch) => {
|
|
420
|
+
const Icon = CHANNEL_ICONS[ch.channelType] ?? Globe;
|
|
421
|
+
const TestIcon = TEST_STATUS_ICONS[ch.testStatus] ?? MinusCircle;
|
|
422
|
+
const testColor = TEST_STATUS_COLORS[ch.testStatus] ?? "";
|
|
423
|
+
|
|
424
|
+
return (
|
|
425
|
+
<div
|
|
426
|
+
key={ch.id}
|
|
427
|
+
className="rounded-lg border p-3 space-y-2"
|
|
428
|
+
>
|
|
429
|
+
<div className="flex items-center justify-between">
|
|
430
|
+
<div className="flex items-center gap-3">
|
|
431
|
+
<Icon className="h-4 w-4 text-muted-foreground" />
|
|
432
|
+
<div>
|
|
433
|
+
<div className="flex items-center gap-2">
|
|
434
|
+
<span className="text-sm font-medium">{ch.name}</span>
|
|
435
|
+
<Badge variant="outline" className="text-xs capitalize">
|
|
436
|
+
{ch.channelType}
|
|
437
|
+
</Badge>
|
|
438
|
+
{ch.direction === "bidirectional" && (
|
|
439
|
+
<Badge variant="default" className="text-xs">
|
|
440
|
+
Chat
|
|
441
|
+
</Badge>
|
|
442
|
+
)}
|
|
443
|
+
</div>
|
|
444
|
+
</div>
|
|
445
|
+
</div>
|
|
446
|
+
<div className="flex items-center gap-3">
|
|
447
|
+
{/* Toggles */}
|
|
448
|
+
<div className="flex items-center gap-3">
|
|
449
|
+
{ch.channelType !== "webhook" && (
|
|
450
|
+
<div className="flex items-center gap-1.5">
|
|
451
|
+
<Label
|
|
452
|
+
htmlFor={`chat-${ch.id}`}
|
|
453
|
+
className="text-xs text-muted-foreground cursor-pointer"
|
|
454
|
+
>
|
|
455
|
+
Chat
|
|
456
|
+
</Label>
|
|
457
|
+
<Switch
|
|
458
|
+
id={`chat-${ch.id}`}
|
|
459
|
+
checked={ch.direction === "bidirectional"}
|
|
460
|
+
onCheckedChange={() => handleDirectionToggle(ch)}
|
|
461
|
+
/>
|
|
462
|
+
</div>
|
|
463
|
+
)}
|
|
464
|
+
<div className="flex items-center gap-1.5">
|
|
465
|
+
<Label
|
|
466
|
+
htmlFor={`active-${ch.id}`}
|
|
467
|
+
className="text-xs text-muted-foreground cursor-pointer"
|
|
468
|
+
>
|
|
469
|
+
Active
|
|
470
|
+
</Label>
|
|
471
|
+
<Switch
|
|
472
|
+
id={`active-${ch.id}`}
|
|
473
|
+
checked={ch.status === "active"}
|
|
474
|
+
onCheckedChange={() => handleToggle(ch.id, ch.status)}
|
|
475
|
+
/>
|
|
476
|
+
</div>
|
|
477
|
+
</div>
|
|
478
|
+
<div className="h-4 w-px bg-border" />
|
|
479
|
+
{/* Actions */}
|
|
480
|
+
<div className="flex items-center gap-1.5">
|
|
481
|
+
<Button
|
|
482
|
+
variant="outline"
|
|
483
|
+
size="sm"
|
|
484
|
+
onClick={() => handleTest(ch.id)}
|
|
485
|
+
disabled={testingId === ch.id}
|
|
486
|
+
>
|
|
487
|
+
{testingId === ch.id ? (
|
|
488
|
+
<Loader2 className="mr-1 h-3.5 w-3.5 animate-spin" />
|
|
489
|
+
) : (
|
|
490
|
+
<Zap className="mr-1 h-3.5 w-3.5" />
|
|
491
|
+
)}
|
|
492
|
+
Test
|
|
493
|
+
</Button>
|
|
494
|
+
<div className="flex items-center gap-1">
|
|
495
|
+
<TestIcon className={`h-3 w-3 ${testColor}`} />
|
|
496
|
+
<span className={`text-xs ${testColor}`}>
|
|
497
|
+
{ch.testStatus}
|
|
498
|
+
</span>
|
|
499
|
+
</div>
|
|
500
|
+
<Button
|
|
501
|
+
variant="ghost"
|
|
502
|
+
size="icon"
|
|
503
|
+
onClick={() => handleDelete(ch.id)}
|
|
504
|
+
>
|
|
505
|
+
<Trash2 className="h-4 w-4 text-destructive" />
|
|
506
|
+
</Button>
|
|
507
|
+
</div>
|
|
508
|
+
</div>
|
|
509
|
+
</div>
|
|
510
|
+
{ch.direction === "bidirectional" && (
|
|
511
|
+
<div className="pl-7 text-xs text-muted-foreground">
|
|
512
|
+
<span className="font-medium">Webhook URL:</span>{" "}
|
|
513
|
+
<code className="bg-muted px-1 py-0.5 rounded text-[11px] select-all">
|
|
514
|
+
{getWebhookUrl(ch)}
|
|
515
|
+
</code>
|
|
516
|
+
</div>
|
|
517
|
+
)}
|
|
518
|
+
</div>
|
|
519
|
+
);
|
|
520
|
+
})}
|
|
521
|
+
</div>
|
|
522
|
+
)}
|
|
523
|
+
</CardContent>
|
|
524
|
+
</Card>
|
|
525
|
+
);
|
|
526
|
+
}
|
|
@@ -17,12 +17,13 @@ import {
|
|
|
17
17
|
SelectTrigger,
|
|
18
18
|
SelectValue,
|
|
19
19
|
} from "@/components/ui/select";
|
|
20
|
-
import { CHAT_MODELS, DEFAULT_CHAT_MODEL } from "@/lib/chat/types";
|
|
20
|
+
import { CHAT_MODELS, DEFAULT_CHAT_MODEL, type ChatModelOption } from "@/lib/chat/types";
|
|
21
21
|
import { FormSectionCard } from "@/components/shared/form-section-card";
|
|
22
22
|
import { MessageCircle } from "lucide-react";
|
|
23
23
|
|
|
24
24
|
export function ChatSettingsSection() {
|
|
25
25
|
const [defaultModel, setDefaultModel] = useState(DEFAULT_CHAT_MODEL);
|
|
26
|
+
const [ollamaModels, setOllamaModels] = useState<ChatModelOption[]>([]);
|
|
26
27
|
|
|
27
28
|
const fetchSettings = useCallback(async () => {
|
|
28
29
|
try {
|
|
@@ -38,6 +39,21 @@ export function ChatSettingsSection() {
|
|
|
38
39
|
|
|
39
40
|
useEffect(() => {
|
|
40
41
|
fetchSettings();
|
|
42
|
+
// Fetch Ollama models for the dropdown
|
|
43
|
+
fetch("/api/runtimes/ollama")
|
|
44
|
+
.then((r) => (r.ok ? r.json() : { models: [] }))
|
|
45
|
+
.then((data: { models?: Array<{ name: string }> }) => {
|
|
46
|
+
setOllamaModels(
|
|
47
|
+
(data.models ?? []).map((m) => ({
|
|
48
|
+
id: `ollama:${m.name}`,
|
|
49
|
+
label: m.name.replace(/:latest$/, ""),
|
|
50
|
+
provider: "ollama" as const,
|
|
51
|
+
tier: "Local",
|
|
52
|
+
costLabel: "Free",
|
|
53
|
+
}))
|
|
54
|
+
);
|
|
55
|
+
})
|
|
56
|
+
.catch(() => {});
|
|
41
57
|
}, [fetchSettings]);
|
|
42
58
|
|
|
43
59
|
const handleModelChange = async (modelId: string) => {
|
|
@@ -91,6 +107,16 @@ export function ChatSettingsSection() {
|
|
|
91
107
|
))}
|
|
92
108
|
</SelectGroup>
|
|
93
109
|
)}
|
|
110
|
+
{ollamaModels.length > 0 && (
|
|
111
|
+
<SelectGroup>
|
|
112
|
+
<SelectLabel>Ollama (Local)</SelectLabel>
|
|
113
|
+
{ollamaModels.map((m) => (
|
|
114
|
+
<SelectItem key={m.id} value={m.id}>
|
|
115
|
+
{m.label} — {m.tier} ({m.costLabel})
|
|
116
|
+
</SelectItem>
|
|
117
|
+
))}
|
|
118
|
+
</SelectGroup>
|
|
119
|
+
)}
|
|
94
120
|
</SelectContent>
|
|
95
121
|
</Select>
|
|
96
122
|
</FormSectionCard>
|
|
@@ -28,7 +28,7 @@ export function DataManagementSection() {
|
|
|
28
28
|
if (data.success) {
|
|
29
29
|
const d = data.deleted;
|
|
30
30
|
toast.success(
|
|
31
|
-
`Cleared ${d.projects} projects, ${d.tasks} tasks, ${d.workflows} workflows, ${d.schedules} schedules, ${d.documents} documents, ${d.agentLogs} logs, ${d.notifications} notifications, ${d.sampleProfiles} sample profiles, ${d.files} files`
|
|
31
|
+
`Cleared ${d.projects} projects, ${d.tasks} tasks, ${d.workflows} workflows, ${d.schedules} schedules, ${d.documents} documents, ${d.conversations} conversations, ${d.chatMessages} messages, ${d.learnedContext} learned context, ${d.views} views, ${d.agentLogs} logs, ${d.notifications} notifications, ${d.sampleProfiles} sample profiles, ${d.files} files`
|
|
32
32
|
);
|
|
33
33
|
} else {
|
|
34
34
|
toast.error(`Clear failed: ${data.error}`);
|
|
@@ -48,7 +48,7 @@ export function DataManagementSection() {
|
|
|
48
48
|
if (data.success) {
|
|
49
49
|
const s = data.seeded;
|
|
50
50
|
toast.success(
|
|
51
|
-
`Seeded ${s.profiles} profiles, ${s.projects} projects, ${s.tasks} tasks, ${s.workflows} workflows, ${s.schedules} schedules, ${s.documents} documents, ${s.agentLogs} logs, ${s.notifications} notifications`
|
|
51
|
+
`Seeded ${s.profiles} profiles, ${s.projects} projects, ${s.tasks} tasks, ${s.workflows} workflows, ${s.schedules} schedules, ${s.documents} documents, ${s.conversations} conversations, ${s.chatMessages} messages, ${s.learnedContext} learned context, ${s.views} views, ${s.agentLogs} logs, ${s.notifications} notifications`
|
|
52
52
|
);
|
|
53
53
|
} else {
|
|
54
54
|
toast.error(`Seed failed: ${data.error}`);
|
|
@@ -74,6 +74,7 @@ export function DataManagementSection() {
|
|
|
74
74
|
<div className="flex items-center gap-2">
|
|
75
75
|
<p className="text-sm text-muted-foreground">
|
|
76
76
|
Delete all projects, tasks, workflows, schedules, documents,
|
|
77
|
+
conversations, chat messages, learned context, saved views,
|
|
77
78
|
agent logs, notifications, seeded sample profiles, and uploaded
|
|
78
79
|
files. Authentication settings are preserved.
|
|
79
80
|
</p>
|
|
@@ -99,8 +100,9 @@ export function DataManagementSection() {
|
|
|
99
100
|
<p className="text-sm text-muted-foreground">
|
|
100
101
|
Populate with 3 custom profiles, 5 realistic projects, 25 tasks
|
|
101
102
|
across varied statuses, 5 workflows, 4 schedules, 12 documents
|
|
102
|
-
(XLSX, PDF, DOCX, PPTX),
|
|
103
|
-
|
|
103
|
+
(XLSX, PDF, DOCX, PPTX), 3 conversations with chat history,
|
|
104
|
+
learned context, saved views, profile test results, repo imports,
|
|
105
|
+
agent logs, and notifications. Existing data is cleared first.
|
|
104
106
|
</p>
|
|
105
107
|
<Button
|
|
106
108
|
variant="outline"
|
|
@@ -122,7 +124,7 @@ export function DataManagementSection() {
|
|
|
122
124
|
open={clearOpen}
|
|
123
125
|
onOpenChange={setClearOpen}
|
|
124
126
|
title="Clear all data?"
|
|
125
|
-
description="This will permanently delete all projects, tasks, workflows, schedules, documents, agent logs, notifications, seeded sample profiles, and uploaded files. Authentication settings will be preserved. This action cannot be undone."
|
|
127
|
+
description="This will permanently delete all projects, tasks, workflows, schedules, documents, conversations, chat messages, learned context, saved views, agent logs, notifications, seeded sample profiles, and uploaded files. Authentication settings will be preserved. This action cannot be undone."
|
|
126
128
|
confirmLabel="Clear All Data"
|
|
127
129
|
onConfirm={handleClear}
|
|
128
130
|
destructive
|
|
@@ -132,7 +134,7 @@ export function DataManagementSection() {
|
|
|
132
134
|
open={seedOpen}
|
|
133
135
|
onOpenChange={setSeedOpen}
|
|
134
136
|
title="Seed sample data?"
|
|
135
|
-
description="This will clear all existing data first, then populate with 3 custom profiles, 5 projects, 25 tasks, 5 workflows, 4 schedules, 12 documents (XLSX, PDF, DOCX, PPTX), agent logs, and notifications. Any current data will be lost."
|
|
137
|
+
description="This will clear all existing data first, then populate with 3 custom profiles, 5 projects, 25 tasks, 5 workflows, 4 schedules, 12 documents (XLSX, PDF, DOCX, PPTX), 3 conversations with chat history, learned context, saved views, profile test results, repo imports, agent logs, and notifications. Any current data will be lost."
|
|
136
138
|
confirmLabel="Seed Data"
|
|
137
139
|
onConfirm={handleSeed}
|
|
138
140
|
/>
|