stagent 0.1.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/LICENSE +191 -0
- package/README.md +399 -0
- package/components.json +21 -0
- package/dist/cli.js +171 -0
- package/drizzle.config.ts +12 -0
- package/next.config.mjs +15 -0
- package/package.json +114 -0
- package/postcss.config.mjs +8 -0
- package/public/icon-512.png +0 -0
- package/public/icon.svg +13 -0
- package/public/readme/home-workspace.png +0 -0
- package/public/readme/inbox-approvals.png +0 -0
- package/public/readme/workflow-blueprints.png +0 -0
- package/public/stagent-s-128.png +0 -0
- package/public/stagent-s-64.png +0 -0
- package/src/app/api/blueprints/[id]/instantiate/route.ts +27 -0
- package/src/app/api/blueprints/[id]/route.ts +39 -0
- package/src/app/api/blueprints/import/route.ts +68 -0
- package/src/app/api/blueprints/route.ts +29 -0
- package/src/app/api/command-palette/recent/route.ts +31 -0
- package/src/app/api/data/clear/route.ts +22 -0
- package/src/app/api/data/seed/route.ts +22 -0
- package/src/app/api/documents/[id]/file/route.ts +44 -0
- package/src/app/api/documents/[id]/route.ts +123 -0
- package/src/app/api/documents/route.ts +59 -0
- package/src/app/api/logs/stream/route.ts +101 -0
- package/src/app/api/notifications/[id]/route.ts +36 -0
- package/src/app/api/notifications/mark-all-read/route.ts +13 -0
- package/src/app/api/notifications/pending-approvals/route.ts +10 -0
- package/src/app/api/notifications/pending-approvals/stream/route.ts +101 -0
- package/src/app/api/notifications/route.ts +34 -0
- package/src/app/api/permissions/route.ts +46 -0
- package/src/app/api/profiles/[id]/route.ts +79 -0
- package/src/app/api/profiles/[id]/test/route.ts +42 -0
- package/src/app/api/profiles/import/route.ts +108 -0
- package/src/app/api/profiles/route.ts +50 -0
- package/src/app/api/projects/[id]/route.ts +72 -0
- package/src/app/api/projects/route.ts +53 -0
- package/src/app/api/schedules/[id]/route.ts +185 -0
- package/src/app/api/schedules/route.ts +117 -0
- package/src/app/api/settings/budgets/route.ts +24 -0
- package/src/app/api/settings/openai/route.ts +24 -0
- package/src/app/api/settings/route.ts +21 -0
- package/src/app/api/settings/test/route.ts +26 -0
- package/src/app/api/tasks/[id]/cancel/route.ts +21 -0
- package/src/app/api/tasks/[id]/execute/route.ts +90 -0
- package/src/app/api/tasks/[id]/logs/route.ts +95 -0
- package/src/app/api/tasks/[id]/output/route.ts +47 -0
- package/src/app/api/tasks/[id]/respond/route.ts +64 -0
- package/src/app/api/tasks/[id]/resume/route.ts +76 -0
- package/src/app/api/tasks/[id]/route.ts +77 -0
- package/src/app/api/tasks/assist/route.ts +35 -0
- package/src/app/api/tasks/route.ts +82 -0
- package/src/app/api/uploads/[id]/route.ts +81 -0
- package/src/app/api/uploads/cleanup/route.ts +7 -0
- package/src/app/api/uploads/route.ts +66 -0
- package/src/app/api/workflows/[id]/execute/route.ts +82 -0
- package/src/app/api/workflows/[id]/route.ts +133 -0
- package/src/app/api/workflows/[id]/status/route.ts +54 -0
- package/src/app/api/workflows/[id]/steps/[stepId]/retry/route.ts +22 -0
- package/src/app/api/workflows/route.ts +61 -0
- package/src/app/apple-icon.tsx +31 -0
- package/src/app/costs/page.tsx +256 -0
- package/src/app/dashboard/page.tsx +44 -0
- package/src/app/documents/[id]/page.tsx +46 -0
- package/src/app/documents/page.tsx +45 -0
- package/src/app/error.tsx +26 -0
- package/src/app/global-error.tsx +23 -0
- package/src/app/globals.css +733 -0
- package/src/app/icon.tsx +30 -0
- package/src/app/inbox/loading.tsx +15 -0
- package/src/app/inbox/page.tsx +35 -0
- package/src/app/layout.tsx +78 -0
- package/src/app/manifest.ts +32 -0
- package/src/app/monitor/page.tsx +37 -0
- package/src/app/page.tsx +162 -0
- package/src/app/profiles/[id]/edit/page.tsx +39 -0
- package/src/app/profiles/[id]/page.tsx +33 -0
- package/src/app/profiles/new/page.tsx +22 -0
- package/src/app/profiles/page.tsx +19 -0
- package/src/app/projects/[id]/page.tsx +134 -0
- package/src/app/projects/loading.tsx +17 -0
- package/src/app/projects/page.tsx +32 -0
- package/src/app/schedules/[id]/page.tsx +47 -0
- package/src/app/schedules/page.tsx +18 -0
- package/src/app/settings/loading.tsx +24 -0
- package/src/app/settings/page.tsx +27 -0
- package/src/app/tasks/[id]/page.tsx +45 -0
- package/src/app/tasks/new/page.tsx +27 -0
- package/src/app/workflows/[id]/edit/page.tsx +66 -0
- package/src/app/workflows/[id]/page.tsx +37 -0
- package/src/app/workflows/blueprints/[id]/page.tsx +40 -0
- package/src/app/workflows/blueprints/new/page.tsx +20 -0
- package/src/app/workflows/blueprints/page.tsx +11 -0
- package/src/app/workflows/new/page.tsx +36 -0
- package/src/app/workflows/page.tsx +18 -0
- package/src/components/charts/donut-ring.tsx +64 -0
- package/src/components/charts/mini-bar.tsx +75 -0
- package/src/components/charts/sparkline.tsx +107 -0
- package/src/components/costs/cost-dashboard.tsx +877 -0
- package/src/components/costs/cost-filters.tsx +179 -0
- package/src/components/dashboard/activity-feed.tsx +95 -0
- package/src/components/dashboard/greeting.tsx +30 -0
- package/src/components/dashboard/priority-queue.tsx +79 -0
- package/src/components/dashboard/quick-actions.tsx +62 -0
- package/src/components/dashboard/recent-projects.tsx +79 -0
- package/src/components/dashboard/stats-cards.tsx +114 -0
- package/src/components/documents/document-browser.tsx +235 -0
- package/src/components/documents/document-detail-view.tsx +367 -0
- package/src/components/documents/document-grid.tsx +78 -0
- package/src/components/documents/document-preview.tsx +68 -0
- package/src/components/documents/document-table.tsx +119 -0
- package/src/components/documents/document-upload-dialog.tsx +153 -0
- package/src/components/documents/types.ts +6 -0
- package/src/components/documents/utils.ts +57 -0
- package/src/components/monitoring/connection-indicator.tsx +14 -0
- package/src/components/monitoring/log-entry.tsx +79 -0
- package/src/components/monitoring/log-filters.tsx +57 -0
- package/src/components/monitoring/log-stream.tsx +144 -0
- package/src/components/monitoring/monitor-overview-wrapper.tsx +64 -0
- package/src/components/monitoring/monitor-overview.tsx +119 -0
- package/src/components/notifications/failure-action.tsx +38 -0
- package/src/components/notifications/inbox-list.tsx +165 -0
- package/src/components/notifications/message-response.tsx +196 -0
- package/src/components/notifications/notification-item.tsx +250 -0
- package/src/components/notifications/pending-approval-host.tsx +478 -0
- package/src/components/notifications/permission-action.tsx +37 -0
- package/src/components/notifications/permission-response-actions.tsx +126 -0
- package/src/components/notifications/unread-badge.tsx +35 -0
- package/src/components/profiles/profile-browser.tsx +117 -0
- package/src/components/profiles/profile-card.tsx +78 -0
- package/src/components/profiles/profile-detail-view.tsx +564 -0
- package/src/components/profiles/profile-form-view.tsx +480 -0
- package/src/components/profiles/profile-import-dialog.tsx +113 -0
- package/src/components/projects/project-card.tsx +58 -0
- package/src/components/projects/project-create-dialog.tsx +140 -0
- package/src/components/projects/project-detail.tsx +68 -0
- package/src/components/projects/project-edit-dialog.tsx +219 -0
- package/src/components/projects/project-list.tsx +108 -0
- package/src/components/schedules/schedule-create-dialog.tsx +403 -0
- package/src/components/schedules/schedule-detail-view.tsx +274 -0
- package/src/components/schedules/schedule-list.tsx +242 -0
- package/src/components/schedules/schedule-status-badge.tsx +16 -0
- package/src/components/settings/api-key-form.tsx +141 -0
- package/src/components/settings/auth-config-section.tsx +141 -0
- package/src/components/settings/auth-method-selector.tsx +67 -0
- package/src/components/settings/auth-status-badge.tsx +40 -0
- package/src/components/settings/auth-status-dot.tsx +59 -0
- package/src/components/settings/budget-guardrails-section.tsx +842 -0
- package/src/components/settings/data-management-section.tsx +141 -0
- package/src/components/settings/openai-runtime-section.tsx +104 -0
- package/src/components/settings/permissions-section.tsx +91 -0
- package/src/components/shared/app-sidebar.tsx +123 -0
- package/src/components/shared/card-skeleton.tsx +42 -0
- package/src/components/shared/command-palette.tsx +250 -0
- package/src/components/shared/confirm-dialog.tsx +52 -0
- package/src/components/shared/empty-state.tsx +24 -0
- package/src/components/shared/error-state.tsx +32 -0
- package/src/components/shared/form-section-card.tsx +33 -0
- package/src/components/shared/section-heading.tsx +14 -0
- package/src/components/shared/stagent-logo.tsx +21 -0
- package/src/components/shared/theme-toggle.tsx +46 -0
- package/src/components/tasks/ai-assist-panel.tsx +210 -0
- package/src/components/tasks/content-preview.tsx +89 -0
- package/src/components/tasks/empty-board.tsx +12 -0
- package/src/components/tasks/file-upload.tsx +120 -0
- package/src/components/tasks/kanban-board.tsx +275 -0
- package/src/components/tasks/kanban-column.tsx +75 -0
- package/src/components/tasks/skeleton-board.tsx +21 -0
- package/src/components/tasks/task-attachments.tsx +114 -0
- package/src/components/tasks/task-card.tsx +101 -0
- package/src/components/tasks/task-create-panel.tsx +360 -0
- package/src/components/tasks/task-detail-view.tsx +356 -0
- package/src/components/ui/alert-dialog.tsx +196 -0
- package/src/components/ui/badge.tsx +50 -0
- package/src/components/ui/button.tsx +71 -0
- package/src/components/ui/card.tsx +92 -0
- package/src/components/ui/checkbox.tsx +32 -0
- package/src/components/ui/command.tsx +184 -0
- package/src/components/ui/dialog.tsx +158 -0
- package/src/components/ui/dropdown-menu.tsx +257 -0
- package/src/components/ui/form.tsx +167 -0
- package/src/components/ui/input.tsx +21 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/popover.tsx +89 -0
- package/src/components/ui/progress.tsx +31 -0
- package/src/components/ui/radio-group.tsx +45 -0
- package/src/components/ui/scroll-area.tsx +58 -0
- package/src/components/ui/select.tsx +190 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/sheet.tsx +143 -0
- package/src/components/ui/sidebar.tsx +726 -0
- package/src/components/ui/skeleton.tsx +13 -0
- package/src/components/ui/slider.tsx +63 -0
- package/src/components/ui/sonner.tsx +36 -0
- package/src/components/ui/switch.tsx +35 -0
- package/src/components/ui/table.tsx +116 -0
- package/src/components/ui/tabs.tsx +91 -0
- package/src/components/ui/textarea.tsx +18 -0
- package/src/components/ui/tooltip.tsx +57 -0
- package/src/components/workflows/blueprint-editor.tsx +109 -0
- package/src/components/workflows/blueprint-gallery.tsx +155 -0
- package/src/components/workflows/blueprint-preview.tsx +240 -0
- package/src/components/workflows/loop-status-view.tsx +272 -0
- package/src/components/workflows/swarm-dashboard.tsx +185 -0
- package/src/components/workflows/workflow-form-view.tsx +1376 -0
- package/src/components/workflows/workflow-list.tsx +230 -0
- package/src/components/workflows/workflow-status-view.tsx +477 -0
- package/src/hooks/use-mobile.ts +19 -0
- package/src/instrumentation.ts +7 -0
- package/src/lib/agents/claude-agent.ts +737 -0
- package/src/lib/agents/execution-manager.ts +27 -0
- package/src/lib/agents/profiles/assignment-validation.ts +75 -0
- package/src/lib/agents/profiles/builtins/code-reviewer/SKILL.md +21 -0
- package/src/lib/agents/profiles/builtins/code-reviewer/profile.yaml +28 -0
- package/src/lib/agents/profiles/builtins/data-analyst/SKILL.md +25 -0
- package/src/lib/agents/profiles/builtins/data-analyst/profile.yaml +27 -0
- package/src/lib/agents/profiles/builtins/devops-engineer/SKILL.md +34 -0
- package/src/lib/agents/profiles/builtins/devops-engineer/profile.yaml +27 -0
- package/src/lib/agents/profiles/builtins/document-writer/SKILL.md +16 -0
- package/src/lib/agents/profiles/builtins/document-writer/profile.yaml +27 -0
- package/src/lib/agents/profiles/builtins/general/SKILL.md +13 -0
- package/src/lib/agents/profiles/builtins/general/profile.yaml +18 -0
- package/src/lib/agents/profiles/builtins/health-fitness-coach/SKILL.md +34 -0
- package/src/lib/agents/profiles/builtins/health-fitness-coach/profile.yaml +26 -0
- package/src/lib/agents/profiles/builtins/learning-coach/SKILL.md +35 -0
- package/src/lib/agents/profiles/builtins/learning-coach/profile.yaml +26 -0
- package/src/lib/agents/profiles/builtins/project-manager/SKILL.md +26 -0
- package/src/lib/agents/profiles/builtins/project-manager/profile.yaml +26 -0
- package/src/lib/agents/profiles/builtins/researcher/SKILL.md +15 -0
- package/src/lib/agents/profiles/builtins/researcher/profile.yaml +27 -0
- package/src/lib/agents/profiles/builtins/shopping-assistant/SKILL.md +34 -0
- package/src/lib/agents/profiles/builtins/shopping-assistant/profile.yaml +26 -0
- package/src/lib/agents/profiles/builtins/technical-writer/SKILL.md +31 -0
- package/src/lib/agents/profiles/builtins/technical-writer/profile.yaml +29 -0
- package/src/lib/agents/profiles/builtins/travel-planner/SKILL.md +23 -0
- package/src/lib/agents/profiles/builtins/travel-planner/profile.yaml +26 -0
- package/src/lib/agents/profiles/builtins/wealth-manager/SKILL.md +24 -0
- package/src/lib/agents/profiles/builtins/wealth-manager/profile.yaml +26 -0
- package/src/lib/agents/profiles/compatibility.ts +109 -0
- package/src/lib/agents/profiles/registry.ts +293 -0
- package/src/lib/agents/profiles/test-runner.ts +18 -0
- package/src/lib/agents/profiles/test-types.ts +20 -0
- package/src/lib/agents/profiles/types.ts +43 -0
- package/src/lib/agents/router.ts +56 -0
- package/src/lib/agents/runtime/catalog.ts +85 -0
- package/src/lib/agents/runtime/claude-sdk.ts +12 -0
- package/src/lib/agents/runtime/claude.ts +370 -0
- package/src/lib/agents/runtime/codex-app-server-client.ts +289 -0
- package/src/lib/agents/runtime/index.ts +167 -0
- package/src/lib/agents/runtime/openai-codex.ts +1089 -0
- package/src/lib/agents/runtime/task-assist-types.ts +8 -0
- package/src/lib/agents/runtime/types.ts +30 -0
- package/src/lib/constants/settings.ts +13 -0
- package/src/lib/constants/status-colors.ts +44 -0
- package/src/lib/constants/task-status.ts +49 -0
- package/src/lib/data/clear.ts +63 -0
- package/src/lib/data/seed-data/documents.ts +715 -0
- package/src/lib/data/seed-data/logs.ts +195 -0
- package/src/lib/data/seed-data/notifications.ts +141 -0
- package/src/lib/data/seed-data/profiles.ts +175 -0
- package/src/lib/data/seed-data/projects.ts +61 -0
- package/src/lib/data/seed-data/schedules.ts +108 -0
- package/src/lib/data/seed-data/tasks.ts +341 -0
- package/src/lib/data/seed-data/usage-ledger.ts +130 -0
- package/src/lib/data/seed-data/workflows.ts +213 -0
- package/src/lib/data/seed.ts +129 -0
- package/src/lib/db/index.ts +221 -0
- package/src/lib/db/migrations/0000_aromatic_gargoyle.sql +59 -0
- package/src/lib/db/migrations/0001_first_iron_patriot.sql +6 -0
- package/src/lib/db/migrations/0002_add_resume_count.sql +1 -0
- package/src/lib/db/migrations/0003_add_settings.sql +5 -0
- package/src/lib/db/migrations/0004_add_documents.sql +20 -0
- package/src/lib/db/migrations/0005_add_document_preprocessing.sql +4 -0
- package/src/lib/db/migrations/0006_add_agent_profile.sql +2 -0
- package/src/lib/db/migrations/0007_add_usage_metering_ledger.sql +30 -0
- package/src/lib/db/migrations/0008_add_document_version.sql +1 -0
- package/src/lib/db/migrations/meta/0000_snapshot.json +416 -0
- package/src/lib/db/migrations/meta/0001_snapshot.json +461 -0
- package/src/lib/db/migrations/meta/0002_snapshot.json +469 -0
- package/src/lib/db/migrations/meta/_journal.json +27 -0
- package/src/lib/db/schema.ts +227 -0
- package/src/lib/documents/cleanup.ts +50 -0
- package/src/lib/documents/context-builder.ts +75 -0
- package/src/lib/documents/output-scanner.ts +166 -0
- package/src/lib/documents/processor.ts +120 -0
- package/src/lib/documents/processors/image.ts +21 -0
- package/src/lib/documents/processors/office.ts +36 -0
- package/src/lib/documents/processors/pdf.ts +12 -0
- package/src/lib/documents/processors/spreadsheet.ts +18 -0
- package/src/lib/documents/processors/text.ts +8 -0
- package/src/lib/documents/registry.ts +25 -0
- package/src/lib/notifications/actionable.ts +108 -0
- package/src/lib/notifications/permissions.ts +169 -0
- package/src/lib/queries/chart-data.ts +184 -0
- package/src/lib/schedules/interval-parser.ts +110 -0
- package/src/lib/schedules/scheduler.ts +220 -0
- package/src/lib/settings/auth.ts +98 -0
- package/src/lib/settings/budget-guardrails.ts +590 -0
- package/src/lib/settings/helpers.ts +23 -0
- package/src/lib/settings/openai-auth.ts +80 -0
- package/src/lib/settings/permissions.ts +102 -0
- package/src/lib/usage/ledger.ts +489 -0
- package/src/lib/usage/pricing.ts +68 -0
- package/src/lib/utils/crypto.ts +90 -0
- package/src/lib/utils/format-timestamp.ts +46 -0
- package/src/lib/utils/session-cleanup.ts +26 -0
- package/src/lib/utils/stagent-paths.ts +18 -0
- package/src/lib/utils.ts +6 -0
- package/src/lib/validators/blueprint.ts +43 -0
- package/src/lib/validators/profile.ts +64 -0
- package/src/lib/validators/project.ts +17 -0
- package/src/lib/validators/settings.ts +57 -0
- package/src/lib/validators/task.ts +30 -0
- package/src/lib/workflows/blueprints/builtins/code-review-pipeline.yaml +72 -0
- package/src/lib/workflows/blueprints/builtins/documentation-generation.yaml +62 -0
- package/src/lib/workflows/blueprints/builtins/investment-research.yaml +81 -0
- package/src/lib/workflows/blueprints/builtins/meal-planning.yaml +73 -0
- package/src/lib/workflows/blueprints/builtins/product-research.yaml +72 -0
- package/src/lib/workflows/blueprints/builtins/research-report.yaml +77 -0
- package/src/lib/workflows/blueprints/builtins/sprint-planning.yaml +77 -0
- package/src/lib/workflows/blueprints/builtins/travel-planning.yaml +80 -0
- package/src/lib/workflows/blueprints/instantiator.ts +131 -0
- package/src/lib/workflows/blueprints/registry.ts +128 -0
- package/src/lib/workflows/blueprints/template.ts +58 -0
- package/src/lib/workflows/blueprints/types.ts +38 -0
- package/src/lib/workflows/definition-validation.ts +121 -0
- package/src/lib/workflows/engine.ts +1113 -0
- package/src/lib/workflows/loop-executor.ts +270 -0
- package/src/lib/workflows/parallel.ts +55 -0
- package/src/lib/workflows/swarm.ts +97 -0
- package/src/lib/workflows/types.ts +112 -0
- package/tsconfig.json +41 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
export interface LogSeed {
|
|
2
|
+
id: string;
|
|
3
|
+
taskId: string;
|
|
4
|
+
agentType: string;
|
|
5
|
+
event: string;
|
|
6
|
+
payload: string;
|
|
7
|
+
timestamp: Date;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface TasksByStatus {
|
|
11
|
+
completed: string[];
|
|
12
|
+
failed: string[];
|
|
13
|
+
running: string[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function createLogs(taskMap: TasksByStatus): LogSeed[] {
|
|
17
|
+
const logs: LogSeed[] = [];
|
|
18
|
+
const now = Date.now();
|
|
19
|
+
const DAY = 86_400_000;
|
|
20
|
+
|
|
21
|
+
// Completed tasks — 6 log entries each
|
|
22
|
+
taskMap.completed.forEach((taskId, i) => {
|
|
23
|
+
const base = now - (10 - i) * DAY;
|
|
24
|
+
const gap = 3000; // 3s between events
|
|
25
|
+
|
|
26
|
+
logs.push(
|
|
27
|
+
{
|
|
28
|
+
id: crypto.randomUUID(),
|
|
29
|
+
taskId,
|
|
30
|
+
agentType: "claude-agent",
|
|
31
|
+
event: "message_start",
|
|
32
|
+
payload: JSON.stringify({
|
|
33
|
+
model: "claude-sonnet-4-20250514",
|
|
34
|
+
role: "assistant",
|
|
35
|
+
}),
|
|
36
|
+
timestamp: new Date(base),
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: crypto.randomUUID(),
|
|
40
|
+
taskId,
|
|
41
|
+
agentType: "claude-agent",
|
|
42
|
+
event: "content_block_start",
|
|
43
|
+
payload: JSON.stringify({
|
|
44
|
+
type: "thinking",
|
|
45
|
+
text: "Let me analyze the provided information and break down the key components...",
|
|
46
|
+
}),
|
|
47
|
+
timestamp: new Date(base + gap),
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: crypto.randomUUID(),
|
|
51
|
+
taskId,
|
|
52
|
+
agentType: "claude-agent",
|
|
53
|
+
event: "tool_start",
|
|
54
|
+
payload: JSON.stringify({
|
|
55
|
+
tool: "Read",
|
|
56
|
+
input: { file_path: "/attached/document" },
|
|
57
|
+
}),
|
|
58
|
+
timestamp: new Date(base + gap * 2),
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: crypto.randomUUID(),
|
|
62
|
+
taskId,
|
|
63
|
+
agentType: "claude-agent",
|
|
64
|
+
event: "content_block_delta",
|
|
65
|
+
payload: JSON.stringify({
|
|
66
|
+
type: "text",
|
|
67
|
+
text: "Based on my analysis of the provided materials, here are the key findings...",
|
|
68
|
+
}),
|
|
69
|
+
timestamp: new Date(base + gap * 3),
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: crypto.randomUUID(),
|
|
73
|
+
taskId,
|
|
74
|
+
agentType: "claude-agent",
|
|
75
|
+
event: "tool_start",
|
|
76
|
+
payload: JSON.stringify({
|
|
77
|
+
tool: "Write",
|
|
78
|
+
input: { file_path: "/output/result.md" },
|
|
79
|
+
}),
|
|
80
|
+
timestamp: new Date(base + gap * 4),
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
id: crypto.randomUUID(),
|
|
84
|
+
taskId,
|
|
85
|
+
agentType: "claude-agent",
|
|
86
|
+
event: "completed",
|
|
87
|
+
payload: JSON.stringify({
|
|
88
|
+
stop_reason: "end_turn",
|
|
89
|
+
usage: {
|
|
90
|
+
input_tokens: 2400 + i * 300,
|
|
91
|
+
output_tokens: 1200 + i * 150,
|
|
92
|
+
},
|
|
93
|
+
}),
|
|
94
|
+
timestamp: new Date(base + gap * 5),
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Failed tasks — 4 log entries each
|
|
100
|
+
taskMap.failed.forEach((taskId, i) => {
|
|
101
|
+
const base = now - (6 - i) * DAY;
|
|
102
|
+
const gap = 3000;
|
|
103
|
+
|
|
104
|
+
logs.push(
|
|
105
|
+
{
|
|
106
|
+
id: crypto.randomUUID(),
|
|
107
|
+
taskId,
|
|
108
|
+
agentType: "claude-agent",
|
|
109
|
+
event: "message_start",
|
|
110
|
+
payload: JSON.stringify({
|
|
111
|
+
model: "claude-sonnet-4-20250514",
|
|
112
|
+
role: "assistant",
|
|
113
|
+
}),
|
|
114
|
+
timestamp: new Date(base),
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
id: crypto.randomUUID(),
|
|
118
|
+
taskId,
|
|
119
|
+
agentType: "claude-agent",
|
|
120
|
+
event: "content_block_start",
|
|
121
|
+
payload: JSON.stringify({
|
|
122
|
+
type: "thinking",
|
|
123
|
+
text: "I need to enrich the prospect data by querying external APIs...",
|
|
124
|
+
}),
|
|
125
|
+
timestamp: new Date(base + gap),
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: crypto.randomUUID(),
|
|
129
|
+
taskId,
|
|
130
|
+
agentType: "claude-agent",
|
|
131
|
+
event: "tool_start",
|
|
132
|
+
payload: JSON.stringify({
|
|
133
|
+
tool: "WebSearch",
|
|
134
|
+
input: { query: "company enrichment data" },
|
|
135
|
+
}),
|
|
136
|
+
timestamp: new Date(base + gap * 2),
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
id: crypto.randomUUID(),
|
|
140
|
+
taskId,
|
|
141
|
+
agentType: "claude-agent",
|
|
142
|
+
event: "error",
|
|
143
|
+
payload: JSON.stringify({
|
|
144
|
+
error: "Rate limit exceeded — too many requests to enrichment API. Please retry after 60 seconds.",
|
|
145
|
+
code: "rate_limit_error",
|
|
146
|
+
}),
|
|
147
|
+
timestamp: new Date(base + gap * 3),
|
|
148
|
+
}
|
|
149
|
+
);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Running tasks — 3 log entries each (in progress)
|
|
153
|
+
taskMap.running.forEach((taskId, i) => {
|
|
154
|
+
const base = now - (2 + i) * 3600_000; // hours ago
|
|
155
|
+
const gap = 3000;
|
|
156
|
+
|
|
157
|
+
logs.push(
|
|
158
|
+
{
|
|
159
|
+
id: crypto.randomUUID(),
|
|
160
|
+
taskId,
|
|
161
|
+
agentType: "claude-agent",
|
|
162
|
+
event: "message_start",
|
|
163
|
+
payload: JSON.stringify({
|
|
164
|
+
model: "claude-sonnet-4-20250514",
|
|
165
|
+
role: "assistant",
|
|
166
|
+
}),
|
|
167
|
+
timestamp: new Date(base),
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
id: crypto.randomUUID(),
|
|
171
|
+
taskId,
|
|
172
|
+
agentType: "claude-agent",
|
|
173
|
+
event: "content_block_start",
|
|
174
|
+
payload: JSON.stringify({
|
|
175
|
+
type: "thinking",
|
|
176
|
+
text: "Working through the analysis step by step...",
|
|
177
|
+
}),
|
|
178
|
+
timestamp: new Date(base + gap),
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
id: crypto.randomUUID(),
|
|
182
|
+
taskId,
|
|
183
|
+
agentType: "claude-agent",
|
|
184
|
+
event: "tool_start",
|
|
185
|
+
payload: JSON.stringify({
|
|
186
|
+
tool: "Read",
|
|
187
|
+
input: { file_path: "/attached/document" },
|
|
188
|
+
}),
|
|
189
|
+
timestamp: new Date(base + gap * 2),
|
|
190
|
+
}
|
|
191
|
+
);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
return logs;
|
|
195
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
export interface NotificationSeed {
|
|
2
|
+
id: string;
|
|
3
|
+
taskId: string;
|
|
4
|
+
type: "task_completed" | "task_failed" | "permission_required" | "agent_message";
|
|
5
|
+
title: string;
|
|
6
|
+
body: string;
|
|
7
|
+
read: boolean;
|
|
8
|
+
toolName: string | null;
|
|
9
|
+
toolInput: string | null;
|
|
10
|
+
response: string | null;
|
|
11
|
+
respondedAt: Date | null;
|
|
12
|
+
createdAt: Date;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Task title → index mapping (from the tasks array order):
|
|
17
|
+
* 0: Analyze portfolio, 1: Research ETFs, 2: Dividend yield (running)
|
|
18
|
+
* 5: Audit competitors, 6: Write hero copy, 7: Design hero (running)
|
|
19
|
+
* 10: Search LinkedIn, 11: Enrich prospect (failed), 12: Draft outreach (queued)
|
|
20
|
+
* 15: Book flights, 17: Create itinerary
|
|
21
|
+
* 20: Gather W-2s, 21: Categorize deductions (running), 22: Calculate home office (queued)
|
|
22
|
+
*/
|
|
23
|
+
export function createNotifications(taskIds: string[]): NotificationSeed[] {
|
|
24
|
+
const now = Date.now();
|
|
25
|
+
const DAY = 86_400_000;
|
|
26
|
+
const HOUR = 3_600_000;
|
|
27
|
+
|
|
28
|
+
return [
|
|
29
|
+
{
|
|
30
|
+
id: crypto.randomUUID(),
|
|
31
|
+
taskId: taskIds[0], // Analyze portfolio — completed
|
|
32
|
+
type: "task_completed",
|
|
33
|
+
title: "Portfolio analysis complete",
|
|
34
|
+
body: "Analyzed allocation across 15 holdings. Tech exposure at 42% — recommend rebalancing below 35%.",
|
|
35
|
+
read: true,
|
|
36
|
+
toolName: null,
|
|
37
|
+
toolInput: null,
|
|
38
|
+
response: null,
|
|
39
|
+
respondedAt: null,
|
|
40
|
+
createdAt: new Date(now - 12 * DAY),
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: crypto.randomUUID(),
|
|
44
|
+
taskId: taskIds[15], // Book flights — completed
|
|
45
|
+
type: "task_completed",
|
|
46
|
+
title: "Flight booking confirmed",
|
|
47
|
+
body: "Booked United round-trip SFO↔JFK for Mar 15-18. Total: $660, Economy Plus.",
|
|
48
|
+
read: true,
|
|
49
|
+
toolName: null,
|
|
50
|
+
toolInput: null,
|
|
51
|
+
response: null,
|
|
52
|
+
respondedAt: null,
|
|
53
|
+
createdAt: new Date(now - 6 * DAY),
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: crypto.randomUUID(),
|
|
57
|
+
taskId: taskIds[5], // Audit competitors — completed
|
|
58
|
+
type: "task_completed",
|
|
59
|
+
title: "Competitor audit ready for review",
|
|
60
|
+
body: "Analyzed Notion, Linear, Vercel, and Stripe landing pages. Key opportunity: dynamic hero personalization.",
|
|
61
|
+
read: false,
|
|
62
|
+
toolName: null,
|
|
63
|
+
toolInput: null,
|
|
64
|
+
response: null,
|
|
65
|
+
respondedAt: null,
|
|
66
|
+
createdAt: new Date(now - 9 * DAY),
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: crypto.randomUUID(),
|
|
70
|
+
taskId: taskIds[11], // Enrich prospect data — failed
|
|
71
|
+
type: "task_failed",
|
|
72
|
+
title: "Prospect enrichment failed",
|
|
73
|
+
body: "Rate limit exceeded when querying enrichment API. 0 of 15 prospects enriched. Retry recommended after cooldown period.",
|
|
74
|
+
read: false,
|
|
75
|
+
toolName: null,
|
|
76
|
+
toolInput: null,
|
|
77
|
+
response: null,
|
|
78
|
+
respondedAt: null,
|
|
79
|
+
createdAt: new Date(now - 6 * DAY),
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: crypto.randomUUID(),
|
|
83
|
+
taskId: taskIds[12], // Draft outreach — queued
|
|
84
|
+
type: "permission_required",
|
|
85
|
+
title: "Permission to send outreach emails",
|
|
86
|
+
body: "Agent wants to send personalized emails to 12 prospects using drafted templates.",
|
|
87
|
+
read: false,
|
|
88
|
+
toolName: "SendEmail",
|
|
89
|
+
toolInput: JSON.stringify({
|
|
90
|
+
recipients: 12,
|
|
91
|
+
template: "pain-point-hook",
|
|
92
|
+
subject: "{Company}'s engineering velocity — quick question",
|
|
93
|
+
}),
|
|
94
|
+
response: null,
|
|
95
|
+
respondedAt: null,
|
|
96
|
+
createdAt: new Date(now - 4 * DAY),
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: crypto.randomUUID(),
|
|
100
|
+
taskId: taskIds[21], // Categorize deductions — running
|
|
101
|
+
type: "permission_required",
|
|
102
|
+
title: "Permission to write expense categorization",
|
|
103
|
+
body: "Agent categorized 25 expenses into IRS-recognized deduction categories. Ready to save results.",
|
|
104
|
+
read: true,
|
|
105
|
+
toolName: "Write",
|
|
106
|
+
toolInput: JSON.stringify({
|
|
107
|
+
file_path: "categorized-expenses.csv",
|
|
108
|
+
description: "Categorized deductible expenses with IRS categories",
|
|
109
|
+
}),
|
|
110
|
+
response: "approved",
|
|
111
|
+
respondedAt: new Date(now - 2 * HOUR),
|
|
112
|
+
createdAt: new Date(now - 3 * HOUR),
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
id: crypto.randomUUID(),
|
|
116
|
+
taskId: taskIds[7], // Design hero component — running
|
|
117
|
+
type: "agent_message",
|
|
118
|
+
title: "Need clarification on brand color palette",
|
|
119
|
+
body: "The design brief specifies OKLCH hue 250, but the existing codebase uses hue 220 in some components. Should I use 250 consistently, or match the existing 220?",
|
|
120
|
+
read: false,
|
|
121
|
+
toolName: null,
|
|
122
|
+
toolInput: null,
|
|
123
|
+
response: null,
|
|
124
|
+
respondedAt: null,
|
|
125
|
+
createdAt: new Date(now - 1 * HOUR),
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: crypto.randomUUID(),
|
|
129
|
+
taskId: taskIds[22], // Calculate home office — queued
|
|
130
|
+
type: "agent_message",
|
|
131
|
+
title: "Found 3 potential deduction methods",
|
|
132
|
+
body: "Simplified method ($5/sq ft, max $1,500), actual expense method (pro-rata utilities + depreciation), or Section 280A election. Simplified gives $750, actual estimate is $2,100. Which method should I apply?",
|
|
133
|
+
read: false,
|
|
134
|
+
toolName: null,
|
|
135
|
+
toolInput: null,
|
|
136
|
+
response: null,
|
|
137
|
+
respondedAt: null,
|
|
138
|
+
createdAt: new Date(now - 30 * 60_000),
|
|
139
|
+
},
|
|
140
|
+
];
|
|
141
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import type { ProfileConfig } from "@/lib/validators/profile";
|
|
2
|
+
import {
|
|
3
|
+
createProfile,
|
|
4
|
+
deleteProfile,
|
|
5
|
+
getProfile,
|
|
6
|
+
isBuiltin,
|
|
7
|
+
updateProfile,
|
|
8
|
+
} from "@/lib/agents/profiles/registry";
|
|
9
|
+
|
|
10
|
+
export interface SampleProfileSeed {
|
|
11
|
+
config: ProfileConfig;
|
|
12
|
+
skillMd: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const SAMPLE_PROFILE_AUTHOR = "Stagent Sample Data";
|
|
16
|
+
const SAMPLE_PROFILE_SOURCE = "https://example.com/stagent/sample-data";
|
|
17
|
+
|
|
18
|
+
export const SAMPLE_PROFILE_IDS = [
|
|
19
|
+
"stagent-sample-revenue-ops-analyst",
|
|
20
|
+
"stagent-sample-launch-copy-chief",
|
|
21
|
+
"stagent-sample-portfolio-coach",
|
|
22
|
+
] as const;
|
|
23
|
+
|
|
24
|
+
export function getSampleProfiles(): SampleProfileSeed[] {
|
|
25
|
+
return [
|
|
26
|
+
{
|
|
27
|
+
config: {
|
|
28
|
+
id: SAMPLE_PROFILE_IDS[0],
|
|
29
|
+
name: "Revenue Operations Analyst",
|
|
30
|
+
version: "1.0.0",
|
|
31
|
+
domain: "work",
|
|
32
|
+
tags: ["pipeline", "forecasting", "sales-ops", "reporting"],
|
|
33
|
+
allowedTools: ["Read", "Write", "Grep", "Bash"],
|
|
34
|
+
canUseToolPolicy: {
|
|
35
|
+
autoApprove: ["Read", "Grep"],
|
|
36
|
+
},
|
|
37
|
+
temperature: 0.3,
|
|
38
|
+
maxTurns: 18,
|
|
39
|
+
outputFormat: "Weekly operating note with metrics, risks, and next actions.",
|
|
40
|
+
author: SAMPLE_PROFILE_AUTHOR,
|
|
41
|
+
source: SAMPLE_PROFILE_SOURCE,
|
|
42
|
+
tests: [
|
|
43
|
+
{
|
|
44
|
+
task: "Summarize weekly pipeline movement and highlight follow-ups.",
|
|
45
|
+
expectedKeywords: ["pipeline", "risks", "next actions"],
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
skillMd: `---
|
|
50
|
+
name: Revenue Operations Analyst
|
|
51
|
+
description: Turns pipeline changes into a concise operating note for GTM teams.
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
# Revenue Operations Analyst
|
|
55
|
+
|
|
56
|
+
You review pipeline movement, funnel risk, and rep follow-ups with a bias toward clear operating decisions.
|
|
57
|
+
|
|
58
|
+
## Default workflow
|
|
59
|
+
|
|
60
|
+
1. Summarize changes in qualified pipeline, stage movement, and forecast confidence.
|
|
61
|
+
2. Call out deals that need executive unblockers or tighter next steps.
|
|
62
|
+
3. End with the three highest-leverage actions for this week.
|
|
63
|
+
`,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
config: {
|
|
67
|
+
id: SAMPLE_PROFILE_IDS[1],
|
|
68
|
+
name: "Launch Copy Chief",
|
|
69
|
+
version: "1.0.0",
|
|
70
|
+
domain: "work",
|
|
71
|
+
tags: ["copywriting", "launches", "messaging", "experiments"],
|
|
72
|
+
allowedTools: ["Read", "Write", "Grep"],
|
|
73
|
+
canUseToolPolicy: {
|
|
74
|
+
autoApprove: ["Read"],
|
|
75
|
+
},
|
|
76
|
+
temperature: 0.6,
|
|
77
|
+
maxTurns: 16,
|
|
78
|
+
outputFormat: "Experiment summary with winning message angles and next tests.",
|
|
79
|
+
author: SAMPLE_PROFILE_AUTHOR,
|
|
80
|
+
source: SAMPLE_PROFILE_SOURCE,
|
|
81
|
+
tests: [
|
|
82
|
+
{
|
|
83
|
+
task: "Review yesterday's landing page experiment results and propose the next headline test.",
|
|
84
|
+
expectedKeywords: ["headline", "conversion", "next test"],
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
skillMd: `---
|
|
89
|
+
name: Launch Copy Chief
|
|
90
|
+
description: Refines launch messaging based on conversion signals and customer language.
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
# Launch Copy Chief
|
|
94
|
+
|
|
95
|
+
You turn campaign performance and research inputs into sharper launch messaging.
|
|
96
|
+
|
|
97
|
+
## Default workflow
|
|
98
|
+
|
|
99
|
+
1. Compare message variants against performance data and qualitative feedback.
|
|
100
|
+
2. Identify the angle that best fits buyer pain, urgency, and proof.
|
|
101
|
+
3. Recommend one next test with a concrete success metric.
|
|
102
|
+
`,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
config: {
|
|
106
|
+
id: SAMPLE_PROFILE_IDS[2],
|
|
107
|
+
name: "Portfolio Review Coach",
|
|
108
|
+
version: "1.0.0",
|
|
109
|
+
domain: "personal",
|
|
110
|
+
tags: ["investing", "portfolio", "risk", "habits"],
|
|
111
|
+
allowedTools: ["Read", "Write"],
|
|
112
|
+
temperature: 0.25,
|
|
113
|
+
maxTurns: 14,
|
|
114
|
+
outputFormat: "Short investor brief with posture, risk notes, and watchlist changes.",
|
|
115
|
+
author: SAMPLE_PROFILE_AUTHOR,
|
|
116
|
+
source: SAMPLE_PROFILE_SOURCE,
|
|
117
|
+
tests: [
|
|
118
|
+
{
|
|
119
|
+
task: "Create a weekday digest for a concentrated growth portfolio.",
|
|
120
|
+
expectedKeywords: ["allocation", "risk", "watchlist"],
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
},
|
|
124
|
+
skillMd: `---
|
|
125
|
+
name: Portfolio Review Coach
|
|
126
|
+
description: Produces disciplined portfolio check-ins focused on risk and watchlist decisions.
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
# Portfolio Review Coach
|
|
130
|
+
|
|
131
|
+
You write practical investing reviews that stay grounded in allocation, concentration risk, and upcoming watchlist decisions.
|
|
132
|
+
|
|
133
|
+
## Default workflow
|
|
134
|
+
|
|
135
|
+
1. Start with what changed in the portfolio and why it matters.
|
|
136
|
+
2. Separate signal from noise by focusing on exposure and downside risk.
|
|
137
|
+
3. Finish with watchlist actions instead of speculative predictions.
|
|
138
|
+
`,
|
|
139
|
+
},
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function upsertSampleProfiles(): number {
|
|
144
|
+
const seeds = getSampleProfiles();
|
|
145
|
+
|
|
146
|
+
for (const seed of seeds) {
|
|
147
|
+
const existing = getProfile(seed.config.id);
|
|
148
|
+
if (!existing) {
|
|
149
|
+
createProfile(seed.config, seed.skillMd);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (isBuiltin(seed.config.id)) {
|
|
154
|
+
throw new Error(`Sample profile id "${seed.config.id}" collides with a built-in profile`);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
updateProfile(seed.config.id, seed.config, seed.skillMd);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return seeds.length;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function clearSampleProfiles(): number {
|
|
164
|
+
let deleted = 0;
|
|
165
|
+
|
|
166
|
+
for (const id of SAMPLE_PROFILE_IDS) {
|
|
167
|
+
const existing = getProfile(id);
|
|
168
|
+
if (!existing || isBuiltin(id)) continue;
|
|
169
|
+
|
|
170
|
+
deleteProfile(id);
|
|
171
|
+
deleted++;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return deleted;
|
|
175
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export interface ProjectSeed {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
status: "active" | "completed";
|
|
6
|
+
createdAt: Date;
|
|
7
|
+
updatedAt: Date;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function createProjects(): ProjectSeed[] {
|
|
11
|
+
const now = Date.now();
|
|
12
|
+
const DAY = 86_400_000;
|
|
13
|
+
|
|
14
|
+
return [
|
|
15
|
+
{
|
|
16
|
+
id: crypto.randomUUID(),
|
|
17
|
+
name: "Investment Portfolio Analysis",
|
|
18
|
+
description:
|
|
19
|
+
"Retail investor research — analyze holdings, research ETFs, track performance",
|
|
20
|
+
status: "active",
|
|
21
|
+
createdAt: new Date(now - 14 * DAY),
|
|
22
|
+
updatedAt: new Date(now - 1 * DAY),
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: crypto.randomUUID(),
|
|
26
|
+
name: "SaaS Landing Page Redesign",
|
|
27
|
+
description:
|
|
28
|
+
"Design and build a high-converting landing page for a B2B SaaS product",
|
|
29
|
+
status: "active",
|
|
30
|
+
createdAt: new Date(now - 12 * DAY),
|
|
31
|
+
updatedAt: new Date(now - 1 * DAY),
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: crypto.randomUUID(),
|
|
35
|
+
name: "LinkedIn Lead Generation",
|
|
36
|
+
description:
|
|
37
|
+
"Find and qualify decision-makers at target companies via social media",
|
|
38
|
+
status: "active",
|
|
39
|
+
createdAt: new Date(now - 10 * DAY),
|
|
40
|
+
updatedAt: new Date(now - 2 * DAY),
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: crypto.randomUUID(),
|
|
44
|
+
name: "Q2 Business Trip — NYC",
|
|
45
|
+
description:
|
|
46
|
+
"Plan end-to-end business travel: flights, hotels, meetings, expenses",
|
|
47
|
+
status: "completed",
|
|
48
|
+
createdAt: new Date(now - 8 * DAY),
|
|
49
|
+
updatedAt: new Date(now - 3 * DAY),
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: crypto.randomUUID(),
|
|
53
|
+
name: "2025 Tax Filing Preparation",
|
|
54
|
+
description:
|
|
55
|
+
"Organize documents, calculate deductions, prepare for CPA review",
|
|
56
|
+
status: "active",
|
|
57
|
+
createdAt: new Date(now - 6 * DAY),
|
|
58
|
+
updatedAt: new Date(now - 1 * DAY),
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { computeNextFireTime } from "@/lib/schedules/interval-parser";
|
|
2
|
+
import { SAMPLE_PROFILE_IDS } from "./profiles";
|
|
3
|
+
|
|
4
|
+
export interface ScheduleSeed {
|
|
5
|
+
id: string;
|
|
6
|
+
projectId: string;
|
|
7
|
+
name: string;
|
|
8
|
+
prompt: string;
|
|
9
|
+
cronExpression: string;
|
|
10
|
+
agentProfile: string | null;
|
|
11
|
+
recurs: boolean;
|
|
12
|
+
status: "active" | "paused" | "expired";
|
|
13
|
+
maxFirings: number | null;
|
|
14
|
+
firingCount: number;
|
|
15
|
+
expiresAt: Date | null;
|
|
16
|
+
lastFiredAt: Date | null;
|
|
17
|
+
nextFireAt: Date | null;
|
|
18
|
+
createdAt: Date;
|
|
19
|
+
updatedAt: Date;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function createSchedules(projectIds: string[]): ScheduleSeed[] {
|
|
23
|
+
const now = Date.now();
|
|
24
|
+
const DAY = 86_400_000;
|
|
25
|
+
const HOUR = 3_600_000;
|
|
26
|
+
const [investmentProject, launchProject, leadGenProject, , taxProject] =
|
|
27
|
+
projectIds;
|
|
28
|
+
|
|
29
|
+
const weekdayPortfolioCron = "0 9 * * 1-5";
|
|
30
|
+
const dailyLaunchCron = "0 9 * * *";
|
|
31
|
+
const everySixHoursCron = "0 */6 * * *";
|
|
32
|
+
const taxReminderCron = "0 9 * * *";
|
|
33
|
+
|
|
34
|
+
return [
|
|
35
|
+
{
|
|
36
|
+
id: crypto.randomUUID(),
|
|
37
|
+
projectId: investmentProject,
|
|
38
|
+
name: "Weekday Portfolio Digest",
|
|
39
|
+
prompt:
|
|
40
|
+
"Before market open, summarize allocation drift, overnight movers, and any watchlist actions for the investment portfolio.",
|
|
41
|
+
cronExpression: weekdayPortfolioCron,
|
|
42
|
+
agentProfile: SAMPLE_PROFILE_IDS[2],
|
|
43
|
+
recurs: true,
|
|
44
|
+
status: "active",
|
|
45
|
+
maxFirings: null,
|
|
46
|
+
firingCount: 0,
|
|
47
|
+
expiresAt: null,
|
|
48
|
+
lastFiredAt: null,
|
|
49
|
+
nextFireAt: computeNextFireTime(weekdayPortfolioCron, new Date(now)),
|
|
50
|
+
createdAt: new Date(now - 10 * DAY),
|
|
51
|
+
updatedAt: new Date(now - 2 * HOUR),
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: crypto.randomUUID(),
|
|
55
|
+
projectId: launchProject,
|
|
56
|
+
name: "CTA Experiment Check-In",
|
|
57
|
+
prompt:
|
|
58
|
+
"Each morning, compare yesterday's CTA variant performance and suggest the next headline or proof point to test on the landing page.",
|
|
59
|
+
cronExpression: dailyLaunchCron,
|
|
60
|
+
agentProfile: SAMPLE_PROFILE_IDS[1],
|
|
61
|
+
recurs: true,
|
|
62
|
+
status: "paused",
|
|
63
|
+
maxFirings: null,
|
|
64
|
+
firingCount: 0,
|
|
65
|
+
expiresAt: null,
|
|
66
|
+
lastFiredAt: null,
|
|
67
|
+
nextFireAt: null,
|
|
68
|
+
createdAt: new Date(now - 6 * DAY),
|
|
69
|
+
updatedAt: new Date(now - 1 * DAY),
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: crypto.randomUUID(),
|
|
73
|
+
projectId: leadGenProject,
|
|
74
|
+
name: "Prospect Pipeline Pulse",
|
|
75
|
+
prompt:
|
|
76
|
+
"Every six hours, roll up new prospects, stalled outreach, and reply-rate changes into a short GTM update with owner follow-ups.",
|
|
77
|
+
cronExpression: everySixHoursCron,
|
|
78
|
+
agentProfile: SAMPLE_PROFILE_IDS[0],
|
|
79
|
+
recurs: true,
|
|
80
|
+
status: "active",
|
|
81
|
+
maxFirings: null,
|
|
82
|
+
firingCount: 0,
|
|
83
|
+
expiresAt: null,
|
|
84
|
+
lastFiredAt: null,
|
|
85
|
+
nextFireAt: computeNextFireTime(everySixHoursCron, new Date(now)),
|
|
86
|
+
createdAt: new Date(now - 5 * DAY),
|
|
87
|
+
updatedAt: new Date(now - 90 * 60_000),
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: crypto.randomUUID(),
|
|
91
|
+
projectId: taxProject,
|
|
92
|
+
name: "Missing Tax Form Reminder",
|
|
93
|
+
prompt:
|
|
94
|
+
"Send a one-time reminder to chase any missing tax documents, update the checklist, and flag anything that could block the CPA handoff.",
|
|
95
|
+
cronExpression: taxReminderCron,
|
|
96
|
+
agentProfile: "project-manager",
|
|
97
|
+
recurs: false,
|
|
98
|
+
status: "expired",
|
|
99
|
+
maxFirings: 1,
|
|
100
|
+
firingCount: 0,
|
|
101
|
+
expiresAt: new Date(now - 1 * DAY),
|
|
102
|
+
lastFiredAt: null,
|
|
103
|
+
nextFireAt: null,
|
|
104
|
+
createdAt: new Date(now - 4 * DAY),
|
|
105
|
+
updatedAt: new Date(now - 1 * DAY),
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
}
|