@nextsparkjs/theme-default 0.1.0-beta.1
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/about/business.md +49 -0
- package/about/features.json +302 -0
- package/about/team.md +79 -0
- package/api/ai/chat/stream/route.ts +212 -0
- package/api/ai/orchestrator/route.ts +226 -0
- package/api/ai/single-agent/route.ts +291 -0
- package/api/ai/usage/route.ts +122 -0
- package/blocks/benefits/component.tsx +100 -0
- package/blocks/benefits/config.ts +11 -0
- package/blocks/benefits/examples.ts +85 -0
- package/blocks/benefits/fields.ts +156 -0
- package/blocks/benefits/schema.ts +33 -0
- package/blocks/cta-section/component.tsx +100 -0
- package/blocks/cta-section/config.ts +11 -0
- package/blocks/cta-section/examples.ts +41 -0
- package/blocks/cta-section/fields.ts +89 -0
- package/blocks/cta-section/index.ts +6 -0
- package/blocks/cta-section/schema.ts +32 -0
- package/blocks/cta-section/thumbnail.png +1 -0
- package/blocks/faq-accordion/component.tsx +156 -0
- package/blocks/faq-accordion/config.ts +11 -0
- package/blocks/faq-accordion/examples.ts +77 -0
- package/blocks/faq-accordion/fields.ts +119 -0
- package/blocks/faq-accordion/index.ts +6 -0
- package/blocks/faq-accordion/schema.ts +45 -0
- package/blocks/features-grid/component.tsx +112 -0
- package/blocks/features-grid/config.ts +11 -0
- package/blocks/features-grid/examples.ts +63 -0
- package/blocks/features-grid/fields.ts +97 -0
- package/blocks/features-grid/index.ts +6 -0
- package/blocks/features-grid/schema.ts +40 -0
- package/blocks/features-grid/thumbnail.png +1 -0
- package/blocks/hero/component.tsx +100 -0
- package/blocks/hero/config.ts +11 -0
- package/blocks/hero/examples.ts +35 -0
- package/blocks/hero/fields.ts +60 -0
- package/blocks/hero/index.ts +6 -0
- package/blocks/hero/schema.ts +32 -0
- package/blocks/hero/thumbnail.png +1 -0
- package/blocks/hero/thumbnail.png.txt +6 -0
- package/blocks/hero-with-form/component.tsx +232 -0
- package/blocks/hero-with-form/config.ts +11 -0
- package/blocks/hero-with-form/examples.ts +16 -0
- package/blocks/hero-with-form/fields.ts +207 -0
- package/blocks/hero-with-form/index.ts +6 -0
- package/blocks/hero-with-form/schema.ts +54 -0
- package/blocks/jumbotron/component.tsx +136 -0
- package/blocks/jumbotron/config.ts +11 -0
- package/blocks/jumbotron/examples.ts +36 -0
- package/blocks/jumbotron/fields.ts +202 -0
- package/blocks/jumbotron/index.ts +6 -0
- package/blocks/jumbotron/schema.ts +55 -0
- package/blocks/logo-cloud/component.tsx +154 -0
- package/blocks/logo-cloud/config.ts +11 -0
- package/blocks/logo-cloud/examples.ts +34 -0
- package/blocks/logo-cloud/fields.ts +133 -0
- package/blocks/logo-cloud/index.ts +6 -0
- package/blocks/logo-cloud/schema.ts +46 -0
- package/blocks/post-content/component.tsx +197 -0
- package/blocks/post-content/config.ts +11 -0
- package/blocks/post-content/examples.ts +33 -0
- package/blocks/post-content/fields.ts +165 -0
- package/blocks/post-content/index.ts +4 -0
- package/blocks/post-content/schema.ts +46 -0
- package/blocks/pricing-table/component.tsx +154 -0
- package/blocks/pricing-table/config.ts +11 -0
- package/blocks/pricing-table/examples.ts +96 -0
- package/blocks/pricing-table/fields.ts +161 -0
- package/blocks/pricing-table/index.ts +4 -0
- package/blocks/pricing-table/schema.ts +50 -0
- package/blocks/split-content/component.tsx +135 -0
- package/blocks/split-content/config.ts +11 -0
- package/blocks/split-content/examples.ts +38 -0
- package/blocks/split-content/fields.ts +198 -0
- package/blocks/split-content/index.ts +6 -0
- package/blocks/split-content/schema.ts +67 -0
- package/blocks/stats-counter/component.tsx +124 -0
- package/blocks/stats-counter/config.ts +11 -0
- package/blocks/stats-counter/examples.ts +61 -0
- package/blocks/stats-counter/fields.ts +134 -0
- package/blocks/stats-counter/index.ts +6 -0
- package/blocks/stats-counter/schema.ts +47 -0
- package/blocks/testimonials/component.tsx +114 -0
- package/blocks/testimonials/config.ts +11 -0
- package/blocks/testimonials/examples.ts +65 -0
- package/blocks/testimonials/fields.ts +105 -0
- package/blocks/testimonials/index.ts +6 -0
- package/blocks/testimonials/schema.ts +41 -0
- package/blocks/testimonials/thumbnail.png +1 -0
- package/blocks/text-content/component.tsx +97 -0
- package/blocks/text-content/config.ts +11 -0
- package/blocks/text-content/examples.ts +30 -0
- package/blocks/text-content/fields.ts +88 -0
- package/blocks/text-content/index.ts +6 -0
- package/blocks/text-content/schema.ts +30 -0
- package/blocks/text-content/thumbnail.png +1 -0
- package/blocks/timeline/component.tsx +267 -0
- package/blocks/timeline/config.ts +11 -0
- package/blocks/timeline/examples.ts +68 -0
- package/blocks/timeline/fields.ts +147 -0
- package/blocks/timeline/index.ts +6 -0
- package/blocks/timeline/schema.ts +49 -0
- package/blocks/video-hero/component.tsx +270 -0
- package/blocks/video-hero/config.ts +11 -0
- package/blocks/video-hero/examples.ts +24 -0
- package/blocks/video-hero/fields.ts +98 -0
- package/blocks/video-hero/index.ts +6 -0
- package/blocks/video-hero/schema.ts +39 -0
- package/components/ai-chat/ChatPanel.tsx +575 -0
- package/components/ai-chat/ConversationItem.tsx +266 -0
- package/components/ai-chat/ConversationSidebar.tsx +99 -0
- package/components/ai-chat/MarkdownRenderer.tsx +15 -0
- package/components/ai-chat/Message.tsx +42 -0
- package/components/ai-chat/MessageInput.tsx +49 -0
- package/components/ai-chat/MessageList.tsx +46 -0
- package/components/ai-chat/TypingIndicator.tsx +11 -0
- package/config/app.config.ts +367 -0
- package/config/billing.config.ts +349 -0
- package/config/dashboard.config.ts +506 -0
- package/config/dev.config.ts +104 -0
- package/config/features.config.ts +203 -0
- package/config/flows.config.ts +129 -0
- package/config/permissions.config.ts +245 -0
- package/config/theme.config.ts +74 -0
- package/docs/01-overview/01-introduction.md +335 -0
- package/docs/01-overview/02-customization.md +671 -0
- package/docs/02-features/01-components.md +155 -0
- package/docs/02-features/02-styling.md +139 -0
- package/docs/02-features/03-tasks-entity.md +407 -0
- package/docs/03-ai/01-overview.md +211 -0
- package/docs/03-ai/02-customization.md +436 -0
- package/entities/customers/customers.config.ts +75 -0
- package/entities/customers/customers.fields.ts +165 -0
- package/entities/customers/customers.service.ts +516 -0
- package/entities/customers/customers.types.ts +83 -0
- package/entities/customers/messages/en.json +66 -0
- package/entities/customers/messages/es.json +66 -0
- package/entities/customers/migrations/001_customers_table.sql +102 -0
- package/entities/customers/migrations/002_customers_metas.sql +92 -0
- package/entities/pages/messages/en.json +41 -0
- package/entities/pages/messages/es.json +41 -0
- package/entities/pages/migrations/001_pages_table.sql +112 -0
- package/entities/pages/migrations/002_pages_metas.sql +56 -0
- package/entities/pages/migrations/003_add_status.sql +50 -0
- package/entities/pages/pages-management.service.ts +610 -0
- package/entities/pages/pages.config.ts +94 -0
- package/entities/pages/pages.fields.ts +101 -0
- package/entities/pages/pages.service.ts +290 -0
- package/entities/pages/pages.types.ts +124 -0
- package/entities/posts/components/post-header.tsx +97 -0
- package/entities/posts/messages/en.json +55 -0
- package/entities/posts/messages/es.json +55 -0
- package/entities/posts/migrations/001_posts_table.sql +115 -0
- package/entities/posts/migrations/003_add_status.sql +44 -0
- package/entities/posts/migrations/004_entity_taxonomy_relations.sql +129 -0
- package/entities/posts/migrations/006_posts_metas.sql +56 -0
- package/entities/posts/posts.config.ts +101 -0
- package/entities/posts/posts.fields.ts +116 -0
- package/entities/posts/posts.service.ts +376 -0
- package/entities/posts/posts.types.ts +74 -0
- package/entities/tasks/messages/en.json +204 -0
- package/entities/tasks/messages/es.json +204 -0
- package/entities/tasks/migrations/001_tasks_table.sql +105 -0
- package/entities/tasks/migrations/002_task_metas.sql +85 -0
- package/entities/tasks/migrations/sample_data.json +77 -0
- package/entities/tasks/tasks.config.ts +79 -0
- package/entities/tasks/tasks.fields.ts +196 -0
- package/entities/tasks/tasks.service.ts +541 -0
- package/entities/tasks/tasks.types.ts +56 -0
- package/lib/hooks/useAiChat.ts +114 -0
- package/lib/hooks/useConversations.ts +376 -0
- package/lib/hooks/useOrchestratorChat.ts +122 -0
- package/lib/hooks/usePersistentChat.ts +315 -0
- package/lib/hooks/useStreamingChat.ts +127 -0
- package/lib/hooks/useTokenUsage.ts +63 -0
- package/lib/langchain/agents/customer-assistant.md +69 -0
- package/lib/langchain/agents/index.ts +61 -0
- package/lib/langchain/agents/orchestrator.md +59 -0
- package/lib/langchain/agents/page-assistant.md +85 -0
- package/lib/langchain/agents/single-agent.md +46 -0
- package/lib/langchain/agents/task-assistant.md +55 -0
- package/lib/langchain/config.ts +45 -0
- package/lib/langchain/handlers/customer-handler.ts +338 -0
- package/lib/langchain/handlers/page-handler.ts +232 -0
- package/lib/langchain/handlers/task-handler.ts +323 -0
- package/lib/langchain/langchain.config.ts +223 -0
- package/lib/langchain/observability.config.ts +30 -0
- package/lib/langchain/orchestrator.ts +562 -0
- package/lib/langchain/tools/customers.ts +176 -0
- package/lib/langchain/tools/index.ts +10 -0
- package/lib/langchain/tools/orchestrator.ts +92 -0
- package/lib/langchain/tools/pages.ts +289 -0
- package/lib/langchain/tools/tasks.ts +167 -0
- package/lib/scheduled-actions/billing.ts +149 -0
- package/lib/scheduled-actions/index.ts +170 -0
- package/lib/scheduled-actions/webhook.ts +231 -0
- package/lib/selectors.ts +197 -0
- package/messages/de/admin.json +219 -0
- package/messages/de/aiUsage.json +36 -0
- package/messages/de/buttons.json +19 -0
- package/messages/de/categories.json +35 -0
- package/messages/de/common.json +16 -0
- package/messages/de/dev.json +101 -0
- package/messages/de/docs.json +27 -0
- package/messages/de/entities.json +7 -0
- package/messages/de/features.json +119 -0
- package/messages/de/footer.json +22 -0
- package/messages/de/home.json +57 -0
- package/messages/de/index.ts +39 -0
- package/messages/de/mobileNav.json +13 -0
- package/messages/de/navigation.json +8 -0
- package/messages/de/observability.json +74 -0
- package/messages/de/posts.json +54 -0
- package/messages/de/pricing.json +102 -0
- package/messages/de/support.json +9 -0
- package/messages/de/teams.json +8 -0
- package/messages/en/admin.json +219 -0
- package/messages/en/aiUsage.json +36 -0
- package/messages/en/buttons.json +19 -0
- package/messages/en/categories.json +35 -0
- package/messages/en/common.json +16 -0
- package/messages/en/dev.json +106 -0
- package/messages/en/docs.json +27 -0
- package/messages/en/entities.json +7 -0
- package/messages/en/features.json +119 -0
- package/messages/en/footer.json +22 -0
- package/messages/en/home.json +57 -0
- package/messages/en/index.ts +39 -0
- package/messages/en/mobileNav.json +13 -0
- package/messages/en/navigation.json +8 -0
- package/messages/en/observability.json +74 -0
- package/messages/en/posts.json +54 -0
- package/messages/en/pricing.json +102 -0
- package/messages/en/support.json +9 -0
- package/messages/en/teams.json +8 -0
- package/messages/es/admin.json +219 -0
- package/messages/es/aiUsage.json +36 -0
- package/messages/es/buttons.json +19 -0
- package/messages/es/categories.json +35 -0
- package/messages/es/common.json +16 -0
- package/messages/es/dev.json +101 -0
- package/messages/es/docs.json +27 -0
- package/messages/es/entities.json +7 -0
- package/messages/es/features.json +119 -0
- package/messages/es/footer.json +22 -0
- package/messages/es/home.json +57 -0
- package/messages/es/index.ts +39 -0
- package/messages/es/mobileNav.json +13 -0
- package/messages/es/navigation.json +8 -0
- package/messages/es/observability.json +74 -0
- package/messages/es/posts.json +54 -0
- package/messages/es/pricing.json +102 -0
- package/messages/es/support.json +9 -0
- package/messages/es/teams.json +8 -0
- package/messages/fr/admin.json +219 -0
- package/messages/fr/aiUsage.json +36 -0
- package/messages/fr/buttons.json +19 -0
- package/messages/fr/categories.json +35 -0
- package/messages/fr/common.json +16 -0
- package/messages/fr/dev.json +101 -0
- package/messages/fr/docs.json +27 -0
- package/messages/fr/entities.json +7 -0
- package/messages/fr/features.json +119 -0
- package/messages/fr/footer.json +22 -0
- package/messages/fr/home.json +57 -0
- package/messages/fr/index.ts +39 -0
- package/messages/fr/mobileNav.json +13 -0
- package/messages/fr/navigation.json +8 -0
- package/messages/fr/observability.json +74 -0
- package/messages/fr/posts.json +54 -0
- package/messages/fr/pricing.json +102 -0
- package/messages/fr/support.json +9 -0
- package/messages/fr/teams.json +8 -0
- package/messages/it/admin.json +219 -0
- package/messages/it/aiUsage.json +36 -0
- package/messages/it/buttons.json +19 -0
- package/messages/it/categories.json +35 -0
- package/messages/it/common.json +16 -0
- package/messages/it/dev.json +101 -0
- package/messages/it/docs.json +27 -0
- package/messages/it/entities.json +7 -0
- package/messages/it/features.json +119 -0
- package/messages/it/footer.json +22 -0
- package/messages/it/home.json +57 -0
- package/messages/it/index.ts +39 -0
- package/messages/it/mobileNav.json +13 -0
- package/messages/it/navigation.json +8 -0
- package/messages/it/observability.json +74 -0
- package/messages/it/posts.json +54 -0
- package/messages/it/pricing.json +102 -0
- package/messages/it/support.json +9 -0
- package/messages/it/teams.json +8 -0
- package/messages/pt/admin.json +219 -0
- package/messages/pt/aiUsage.json +36 -0
- package/messages/pt/buttons.json +19 -0
- package/messages/pt/categories.json +35 -0
- package/messages/pt/common.json +16 -0
- package/messages/pt/dev.json +101 -0
- package/messages/pt/docs.json +27 -0
- package/messages/pt/entities.json +7 -0
- package/messages/pt/features.json +119 -0
- package/messages/pt/footer.json +22 -0
- package/messages/pt/home.json +57 -0
- package/messages/pt/index.ts +39 -0
- package/messages/pt/mobileNav.json +13 -0
- package/messages/pt/navigation.json +8 -0
- package/messages/pt/observability.json +74 -0
- package/messages/pt/posts.json +54 -0
- package/messages/pt/pricing.json +102 -0
- package/messages/pt/support.json +9 -0
- package/messages/pt/teams.json +8 -0
- package/migrations/089_add_editor_team_role.sql +39 -0
- package/migrations/090_demo_users_teams.sql +540 -0
- package/migrations/091_greek_teams_billing.sql +523 -0
- package/migrations/092_billing_sample_data.sql +774 -0
- package/migrations/093_pages_sample_data.sql +1158 -0
- package/migrations/094_posts_sample_data.sql +278 -0
- package/migrations/095_tasks_sample_data.sql +440 -0
- package/migrations/096_customers_sample_data.sql +358 -0
- package/migrations/097_scheduled_actions_sample_data.sql +111 -0
- package/package.json +22 -0
- package/public/docs/desktop-layout-example.png +0 -0
- package/styles/components.css +11 -0
- package/styles/globals.css +179 -0
- package/templates/(public)/blog/[slug]/page.tsx +65 -0
- package/templates/(public)/layout.tsx +25 -0
- package/templates/(public)/page.tsx +200 -0
- package/templates/(public)/support/page.tsx +321 -0
- package/templates/dashboard/(main)/agent-multi/page.tsx +63 -0
- package/templates/dashboard/(main)/agent-single/page.tsx +142 -0
- package/templates/dashboard/(main)/settings/ai-usage/page.tsx +157 -0
- package/templates/superadmin/ai-observability/[traceId]/page.tsx +27 -0
- package/templates/superadmin/ai-observability/page.tsx +17 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
You are a page and content management AI assistant for the Boilerplate application.
|
|
2
|
+
|
|
3
|
+
## CRITICAL RULE - MUST FOLLOW
|
|
4
|
+
|
|
5
|
+
**YOU MUST ALWAYS USE TOOLS TO GET DATA. NEVER FABRICATE OR IMAGINE PAGE INFORMATION.**
|
|
6
|
+
|
|
7
|
+
Before responding with ANY page or block information, you MUST:
|
|
8
|
+
1. Call the appropriate tool (list_pages, get_page, list_available_blocks)
|
|
9
|
+
2. Wait for the tool result
|
|
10
|
+
3. ONLY THEN respond based on the REAL data from the tool
|
|
11
|
+
|
|
12
|
+
If a tool returns an error or empty results, tell the user honestly - NEVER make up fake pages.
|
|
13
|
+
|
|
14
|
+
## Your Capabilities
|
|
15
|
+
- List, view, create, update, and delete pages (using tools)
|
|
16
|
+
- Add, update, remove, and reorder blocks within pages
|
|
17
|
+
- Publish and unpublish pages
|
|
18
|
+
- Understand and suggest appropriate block types
|
|
19
|
+
|
|
20
|
+
## Available Block Types (16 total)
|
|
21
|
+
|
|
22
|
+
### Hero Blocks
|
|
23
|
+
- **hero**: Full-width hero with title, subtitle, CTA button, and background image
|
|
24
|
+
- **hero-with-form**: Hero section with a lead capture form on the right side
|
|
25
|
+
- **jumbotron**: Large attention-grabbing hero, can be fullscreen
|
|
26
|
+
- **video-hero**: Hero with embedded video background (YouTube/Vimeo)
|
|
27
|
+
|
|
28
|
+
### Content Blocks
|
|
29
|
+
- **text-content**: Rich text paragraphs and formatted content
|
|
30
|
+
- **post-content**: Long-form blog post content with editorial styling
|
|
31
|
+
- **split-content**: Two-column layout with image on one side and text on the other
|
|
32
|
+
- **features-grid**: Grid layout showcasing features with icons, titles, and descriptions
|
|
33
|
+
- **timeline**: Chronological events or process steps in a vertical timeline
|
|
34
|
+
- **logo-cloud**: Grid or row of client/partner logos
|
|
35
|
+
|
|
36
|
+
### Conversion Blocks
|
|
37
|
+
- **cta-section**: Call-to-action section with title, description, and buttons
|
|
38
|
+
- **pricing-table**: Pricing plans comparison with features and CTAs
|
|
39
|
+
- **benefits**: Three-column grid highlighting key benefits with colored top borders
|
|
40
|
+
- **faq-accordion**: Expandable FAQ section with questions and answers
|
|
41
|
+
- **stats-counter**: Key metrics and statistics display with animated counters
|
|
42
|
+
- **testimonials**: Customer quotes, reviews, and social proof
|
|
43
|
+
|
|
44
|
+
## Available Tools - USE THEM
|
|
45
|
+
|
|
46
|
+
| Tool | When to use |
|
|
47
|
+
|------|-------------|
|
|
48
|
+
| **list_pages** | User asks to see pages |
|
|
49
|
+
| **get_page** | User asks about a specific page |
|
|
50
|
+
| **create_page** | User wants to create a new page |
|
|
51
|
+
| **update_page** | User wants to modify page metadata |
|
|
52
|
+
| **delete_page** | User wants to remove a page |
|
|
53
|
+
| **add_block** | User wants to add content to a page |
|
|
54
|
+
| **update_block** | User wants to modify a block |
|
|
55
|
+
| **remove_block** | User wants to remove a block |
|
|
56
|
+
| **reorder_blocks** | User wants to change block order |
|
|
57
|
+
| **publish_page** | User wants to make a page live |
|
|
58
|
+
| **unpublish_page** | User wants to hide a page |
|
|
59
|
+
| **list_available_blocks** | User asks what blocks are available |
|
|
60
|
+
|
|
61
|
+
## Correct Workflow
|
|
62
|
+
|
|
63
|
+
1. User: "Show me all pages"
|
|
64
|
+
2. YOU: Call list_pages tool
|
|
65
|
+
3. Tool returns: [{id: "1", title: "Home", slug: "home", status: "published"}, ...]
|
|
66
|
+
4. YOU: Format and show the REAL pages from the tool result
|
|
67
|
+
|
|
68
|
+
## Page Fields
|
|
69
|
+
- **title**: Page title (required)
|
|
70
|
+
- **slug**: URL-friendly identifier (required, lowercase with hyphens)
|
|
71
|
+
- **status**: draft or published
|
|
72
|
+
- **locale**: Language code (default: 'en')
|
|
73
|
+
- **seoTitle**: SEO meta title (optional)
|
|
74
|
+
- **seoDescription**: SEO meta description (optional)
|
|
75
|
+
|
|
76
|
+
## Response Format
|
|
77
|
+
- Use Spanish when the user writes in Spanish, English otherwise
|
|
78
|
+
- After creating or updating pages, provide a preview link: [Page Title](/p/{slug})
|
|
79
|
+
- When listing pages, show title, status, and block count
|
|
80
|
+
- Suggest appropriate blocks based on user needs
|
|
81
|
+
|
|
82
|
+
## What NOT to do
|
|
83
|
+
- NEVER respond with example/fake page data
|
|
84
|
+
- NEVER imagine what pages the user might have
|
|
85
|
+
- NEVER skip calling tools before responding about pages
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
You are a helpful AI assistant that can manage tasks, customers, and pages.
|
|
2
|
+
|
|
3
|
+
## CRITICAL RULE
|
|
4
|
+
|
|
5
|
+
**ALWAYS USE TOOLS TO GET DATA. NEVER FABRICATE INFORMATION.**
|
|
6
|
+
|
|
7
|
+
Before responding with ANY data, you MUST:
|
|
8
|
+
1. Call the appropriate tool
|
|
9
|
+
2. Wait for the result
|
|
10
|
+
3. Respond based on REAL data only
|
|
11
|
+
|
|
12
|
+
## Available Tools
|
|
13
|
+
|
|
14
|
+
### Tasks
|
|
15
|
+
- list_tasks: Show all tasks (optionally filter by status/priority)
|
|
16
|
+
- search_tasks: Find tasks by keyword
|
|
17
|
+
- get_task_details: Get full details of a task
|
|
18
|
+
- create_task: Create a new task
|
|
19
|
+
- update_task: Modify an existing task
|
|
20
|
+
|
|
21
|
+
### Customers
|
|
22
|
+
- list_customers: Show all customers
|
|
23
|
+
- search_customers: Find customers by keyword
|
|
24
|
+
- get_customer_details: Get full customer info
|
|
25
|
+
- create_customer: Create a new customer
|
|
26
|
+
- update_customer: Modify customer data
|
|
27
|
+
|
|
28
|
+
### Pages
|
|
29
|
+
- list_pages: Show all pages
|
|
30
|
+
- get_page_details: Get page with blocks
|
|
31
|
+
- create_page: Create a new page
|
|
32
|
+
- update_page: Modify page content/blocks
|
|
33
|
+
|
|
34
|
+
## Response Guidelines
|
|
35
|
+
|
|
36
|
+
- Match the user's language (Spanish/English)
|
|
37
|
+
- Be concise and helpful
|
|
38
|
+
- Format lists clearly
|
|
39
|
+
- Provide links: [Item Name](/dashboard/[entity]/{id})
|
|
40
|
+
- Confirm successful operations
|
|
41
|
+
|
|
42
|
+
## What NOT to do
|
|
43
|
+
|
|
44
|
+
- NEVER respond with example/fake data
|
|
45
|
+
- NEVER imagine what data the user might have
|
|
46
|
+
- NEVER skip calling tools before responding about data
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
You are a task management AI assistant for the Boilerplate application.
|
|
2
|
+
|
|
3
|
+
## CRITICAL RULE - MUST FOLLOW
|
|
4
|
+
|
|
5
|
+
**YOU MUST ALWAYS USE TOOLS TO GET DATA. NEVER FABRICATE OR IMAGINE TASK INFORMATION.**
|
|
6
|
+
|
|
7
|
+
Before responding with ANY task information, you MUST:
|
|
8
|
+
1. Call the appropriate tool (list_tasks, search_tasks, get_task_details)
|
|
9
|
+
2. Wait for the tool result
|
|
10
|
+
3. ONLY THEN respond based on the REAL data from the tool
|
|
11
|
+
|
|
12
|
+
If a tool returns an error or empty results, tell the user honestly - NEVER make up fake tasks.
|
|
13
|
+
|
|
14
|
+
## Your Capabilities
|
|
15
|
+
- List, search, and view tasks (using tools)
|
|
16
|
+
- Create new tasks with title, description, priority, and due dates
|
|
17
|
+
- Update existing tasks (status, priority, details)
|
|
18
|
+
- Suggest ideas, recipes, lists, or content to ADD to tasks when asked
|
|
19
|
+
|
|
20
|
+
## Handling Suggestions + Task Updates
|
|
21
|
+
|
|
22
|
+
When the user asks you to "suggest X for task Y" or "add recommendations to task":
|
|
23
|
+
1. First, find the task using search_tasks or get_task_details
|
|
24
|
+
2. Generate your suggestions (recipes, ideas, items, etc.) using your knowledge
|
|
25
|
+
3. Update the task with the suggestions using update_task
|
|
26
|
+
4. Confirm what you added
|
|
27
|
+
|
|
28
|
+
## Available Tools - USE THEM
|
|
29
|
+
|
|
30
|
+
| Tool | When to use |
|
|
31
|
+
|------|-------------|
|
|
32
|
+
| **list_tasks** | User asks to see tasks, pending items, todo list |
|
|
33
|
+
| **search_tasks** | User wants to find specific tasks by keyword |
|
|
34
|
+
| **get_task_details** | User asks about a specific task |
|
|
35
|
+
| **create_task** | User wants to create a new task |
|
|
36
|
+
| **update_task** | User wants to modify an existing task |
|
|
37
|
+
|
|
38
|
+
## Correct Workflow
|
|
39
|
+
|
|
40
|
+
1. User: "Show me my tasks"
|
|
41
|
+
2. YOU: Call list_tasks tool
|
|
42
|
+
3. Tool returns: [{id: "1", title: "Review report", status: "todo"}, ...]
|
|
43
|
+
4. YOU: Format and show the REAL tasks from the tool result
|
|
44
|
+
|
|
45
|
+
## Response Format
|
|
46
|
+
- Use Spanish when the user writes in Spanish, English when they write in English
|
|
47
|
+
- Be concise but helpful
|
|
48
|
+
- Use bullet points for task lists
|
|
49
|
+
- When a task is created or updated, provide a link: [Task Title](/dashboard/tasks/{id})
|
|
50
|
+
- If no tasks found, say so honestly - don't invent them
|
|
51
|
+
|
|
52
|
+
## What NOT to do
|
|
53
|
+
- ❌ NEVER respond with example/fake tasks like "Task 1: Description..."
|
|
54
|
+
- ❌ NEVER imagine what tasks the user might have
|
|
55
|
+
- ❌ NEVER skip calling tools before responding about tasks
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LangChain Orchestrator Configuration for Default Theme
|
|
3
|
+
*
|
|
4
|
+
* This file configures the tools available to the graph-based orchestrator.
|
|
5
|
+
* Each tool represents an entity or capability the AI can work with.
|
|
6
|
+
*
|
|
7
|
+
* ARCHITECTURE:
|
|
8
|
+
* - Theme defines tools and their handlers
|
|
9
|
+
* - Plugin orchestrates based on this configuration
|
|
10
|
+
* - No hardcoded entity knowledge in plugin
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { OrchestratorConfig } from '@/plugins/langchain/lib/graph/types'
|
|
14
|
+
|
|
15
|
+
// Import handler implementations
|
|
16
|
+
import { taskHandlerNode } from './handlers/task-handler'
|
|
17
|
+
import { customerHandlerNode } from './handlers/customer-handler'
|
|
18
|
+
import { pageHandlerNode } from './handlers/page-handler'
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Orchestrator configuration with all registered tools
|
|
22
|
+
*/
|
|
23
|
+
export const orchestratorConfig: OrchestratorConfig = {
|
|
24
|
+
tools: [
|
|
25
|
+
{
|
|
26
|
+
name: 'task',
|
|
27
|
+
description: 'Task/todo management (list, create, update, delete)',
|
|
28
|
+
handler: taskHandlerNode,
|
|
29
|
+
exampleParameters: 'title, description, priority (low/medium/high/urgent), status (todo/in-progress/review/done/blocked), dueDate',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'customer',
|
|
33
|
+
description: 'Customer/contact management (list, create, update, delete, search)',
|
|
34
|
+
handler: customerHandlerNode,
|
|
35
|
+
exampleParameters: 'query, name, email, phone, accountNumber, fields to retrieve',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'page',
|
|
39
|
+
description: 'Page/content management (list, create, update, delete)',
|
|
40
|
+
handler: pageHandlerNode,
|
|
41
|
+
exampleParameters: 'title, slug, status (draft/published), content',
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
systemIntents: ['greeting', 'clarification'],
|
|
45
|
+
}
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customer Handler Node
|
|
3
|
+
*
|
|
4
|
+
* Executes customer operations directly without additional LLM calls.
|
|
5
|
+
* Uses the CustomersService to perform CRUD operations.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { CustomersService } from '@/themes/default/entities/customers/customers.service'
|
|
9
|
+
import { tracer } from '@/plugins/langchain/lib/tracer'
|
|
10
|
+
import { config as pluginConfig } from '@/plugins/langchain/plugin.config'
|
|
11
|
+
import { createAgentLogger } from '@/plugins/langchain/lib/logger'
|
|
12
|
+
import type { OrchestratorState, CustomerHandlerResult, CustomerData, IntentType } from '@/plugins/langchain/lib/graph/types'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Transform Customer entity to CustomerData for handler result
|
|
16
|
+
*/
|
|
17
|
+
function toCustomerData(customer: any): CustomerData {
|
|
18
|
+
return {
|
|
19
|
+
id: customer.id,
|
|
20
|
+
name: customer.name,
|
|
21
|
+
email: customer.email,
|
|
22
|
+
phone: customer.phone,
|
|
23
|
+
accountNumber: customer.account?.toString(),
|
|
24
|
+
office: customer.office,
|
|
25
|
+
salesRep: customer.salesRep,
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Execute customer operation based on intent
|
|
31
|
+
*/
|
|
32
|
+
async function executeCustomerOperation(
|
|
33
|
+
action: string,
|
|
34
|
+
parameters: Record<string, unknown>,
|
|
35
|
+
context: { userId: string; teamId: string }
|
|
36
|
+
): Promise<CustomerHandlerResult> {
|
|
37
|
+
const { userId, teamId } = context
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
switch (action) {
|
|
41
|
+
case 'list': {
|
|
42
|
+
const { customers, total } = await CustomersService.list(userId, {
|
|
43
|
+
limit: 50,
|
|
44
|
+
orderBy: 'name',
|
|
45
|
+
orderDir: 'asc',
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
success: true,
|
|
50
|
+
operation: 'list',
|
|
51
|
+
data: customers.map(toCustomerData),
|
|
52
|
+
count: total,
|
|
53
|
+
message: `Found ${total} customer(s)`,
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
case 'get': {
|
|
58
|
+
const id = parameters.id as string
|
|
59
|
+
if (!id) {
|
|
60
|
+
return {
|
|
61
|
+
success: false,
|
|
62
|
+
operation: 'get',
|
|
63
|
+
data: null,
|
|
64
|
+
message: 'Customer ID is required',
|
|
65
|
+
error: 'Missing customer ID',
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const customer = await CustomersService.getById(id, userId)
|
|
70
|
+
if (!customer) {
|
|
71
|
+
return {
|
|
72
|
+
success: false,
|
|
73
|
+
operation: 'get',
|
|
74
|
+
data: null,
|
|
75
|
+
message: 'Customer not found',
|
|
76
|
+
error: 'Customer not found',
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
success: true,
|
|
82
|
+
operation: 'get',
|
|
83
|
+
data: toCustomerData(customer),
|
|
84
|
+
message: `Found customer: ${customer.name}`,
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
case 'search': {
|
|
89
|
+
const query = parameters.query as string
|
|
90
|
+
if (!query) {
|
|
91
|
+
return {
|
|
92
|
+
success: false,
|
|
93
|
+
operation: 'search',
|
|
94
|
+
data: null,
|
|
95
|
+
message: 'Search query is required',
|
|
96
|
+
error: 'Missing search query',
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const customers = await CustomersService.search(userId, {
|
|
101
|
+
query,
|
|
102
|
+
limit: 20,
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
// If user asked for specific fields, include them in message
|
|
106
|
+
const fields = parameters.fields as string[] | undefined
|
|
107
|
+
let fieldInfo = ''
|
|
108
|
+
if (fields && fields.length > 0 && customers.length > 0) {
|
|
109
|
+
const customer = customers[0]
|
|
110
|
+
const values = fields.map((f) => {
|
|
111
|
+
if (f === 'accountNumber' || f === 'account') {
|
|
112
|
+
return `account: ${customer.account}`
|
|
113
|
+
}
|
|
114
|
+
if (f === 'phone') {
|
|
115
|
+
return `phone: ${customer.phone || 'N/A'}`
|
|
116
|
+
}
|
|
117
|
+
return null
|
|
118
|
+
}).filter(Boolean)
|
|
119
|
+
if (values.length > 0) {
|
|
120
|
+
fieldInfo = ` (${values.join(', ')})`
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
success: true,
|
|
126
|
+
operation: 'search',
|
|
127
|
+
data: customers.map(toCustomerData),
|
|
128
|
+
count: customers.length,
|
|
129
|
+
message: `Found ${customers.length} customer(s) matching "${query}"${fieldInfo}`,
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
case 'create': {
|
|
134
|
+
const name = parameters.name as string
|
|
135
|
+
if (!name) {
|
|
136
|
+
return {
|
|
137
|
+
success: false,
|
|
138
|
+
operation: 'create',
|
|
139
|
+
data: null,
|
|
140
|
+
message: 'Customer name is required',
|
|
141
|
+
error: 'Missing name',
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const account = parameters.account as number || Math.floor(Math.random() * 100000)
|
|
146
|
+
const office = parameters.office as string || 'Main'
|
|
147
|
+
|
|
148
|
+
const customer = await CustomersService.create(userId, {
|
|
149
|
+
name,
|
|
150
|
+
account,
|
|
151
|
+
office,
|
|
152
|
+
phone: parameters.phone as string | undefined,
|
|
153
|
+
salesRep: parameters.salesRep as string | undefined,
|
|
154
|
+
teamId,
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
success: true,
|
|
159
|
+
operation: 'create',
|
|
160
|
+
data: toCustomerData(customer),
|
|
161
|
+
message: `Created customer: ${customer.name}`,
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
case 'update': {
|
|
166
|
+
const id = parameters.id as string
|
|
167
|
+
if (!id) {
|
|
168
|
+
return {
|
|
169
|
+
success: false,
|
|
170
|
+
operation: 'update',
|
|
171
|
+
data: null,
|
|
172
|
+
message: 'Customer ID is required',
|
|
173
|
+
error: 'Missing customer ID',
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const updateData: Record<string, unknown> = {}
|
|
178
|
+
if (parameters.name) updateData.name = parameters.name
|
|
179
|
+
if (parameters.account !== undefined) updateData.account = parameters.account
|
|
180
|
+
if (parameters.office) updateData.office = parameters.office
|
|
181
|
+
if (parameters.phone !== undefined) updateData.phone = parameters.phone
|
|
182
|
+
if (parameters.salesRep !== undefined) updateData.salesRep = parameters.salesRep
|
|
183
|
+
|
|
184
|
+
const customer = await CustomersService.update(userId, id, updateData)
|
|
185
|
+
|
|
186
|
+
return {
|
|
187
|
+
success: true,
|
|
188
|
+
operation: 'update',
|
|
189
|
+
data: toCustomerData(customer),
|
|
190
|
+
message: `Updated customer: ${customer.name}`,
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
case 'delete': {
|
|
195
|
+
const id = parameters.id as string
|
|
196
|
+
if (!id) {
|
|
197
|
+
return {
|
|
198
|
+
success: false,
|
|
199
|
+
operation: 'delete',
|
|
200
|
+
data: null,
|
|
201
|
+
message: 'Customer ID is required',
|
|
202
|
+
error: 'Missing customer ID',
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const success = await CustomersService.delete(userId, id)
|
|
207
|
+
if (!success) {
|
|
208
|
+
return {
|
|
209
|
+
success: false,
|
|
210
|
+
operation: 'delete',
|
|
211
|
+
data: null,
|
|
212
|
+
message: 'Failed to delete customer',
|
|
213
|
+
error: 'Delete operation failed',
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
success: true,
|
|
219
|
+
operation: 'delete',
|
|
220
|
+
data: null,
|
|
221
|
+
message: 'Customer deleted successfully',
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
default:
|
|
226
|
+
return {
|
|
227
|
+
success: false,
|
|
228
|
+
operation: 'unknown',
|
|
229
|
+
data: null,
|
|
230
|
+
message: `Unknown action: ${action}`,
|
|
231
|
+
error: `Unsupported action: ${action}`,
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
} catch (error) {
|
|
235
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error'
|
|
236
|
+
return {
|
|
237
|
+
success: false,
|
|
238
|
+
operation: action as any,
|
|
239
|
+
data: null,
|
|
240
|
+
message: `Failed to execute ${action}: ${errorMessage}`,
|
|
241
|
+
error: errorMessage,
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Customer handler node
|
|
248
|
+
*
|
|
249
|
+
* Executes customer operations without additional LLM calls.
|
|
250
|
+
* Returns JSON result for combiner to format.
|
|
251
|
+
*/
|
|
252
|
+
export async function customerHandlerNode(
|
|
253
|
+
state: OrchestratorState
|
|
254
|
+
): Promise<Partial<OrchestratorState>> {
|
|
255
|
+
const { context, traceId, loggerTimestamp } = state
|
|
256
|
+
const logger = createAgentLogger({
|
|
257
|
+
agentName: 'graph-orchestrator',
|
|
258
|
+
userName: (context.userName as string) || 'system',
|
|
259
|
+
timestamp: loggerTimestamp,
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
// Find customer intent
|
|
263
|
+
const customerIntent = state.intents.find((i) => i.type === 'customer')
|
|
264
|
+
|
|
265
|
+
if (!customerIntent) {
|
|
266
|
+
// No customer intent, skip
|
|
267
|
+
return {
|
|
268
|
+
completedHandlers: [...state.completedHandlers, 'customer' as IntentType],
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Start span for customer handler
|
|
273
|
+
const spanContext = traceId
|
|
274
|
+
? await tracer.startSpan(
|
|
275
|
+
{ userId: context.userId, teamId: context.teamId },
|
|
276
|
+
traceId,
|
|
277
|
+
{
|
|
278
|
+
name: 'customer-handler',
|
|
279
|
+
type: 'tool',
|
|
280
|
+
toolName: `customer_${customerIntent.action}`,
|
|
281
|
+
input: customerIntent.parameters,
|
|
282
|
+
}
|
|
283
|
+
)
|
|
284
|
+
: null
|
|
285
|
+
|
|
286
|
+
await logger.info('CUSTOMER_HANDLER_INPUT', {
|
|
287
|
+
action: customerIntent.action,
|
|
288
|
+
parameters: customerIntent.parameters,
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
if (pluginConfig.debug) {
|
|
292
|
+
console.log('[CustomerHandler] Executing:', customerIntent.action, customerIntent.parameters)
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const result = await executeCustomerOperation(
|
|
296
|
+
customerIntent.action,
|
|
297
|
+
customerIntent.parameters,
|
|
298
|
+
{
|
|
299
|
+
userId: state.context.userId,
|
|
300
|
+
teamId: state.context.teamId as string,
|
|
301
|
+
}
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
await logger.info('CUSTOMER_HANDLER_OUTPUT', {
|
|
305
|
+
success: result.success,
|
|
306
|
+
operation: result.operation,
|
|
307
|
+
message: result.message,
|
|
308
|
+
count: result.count,
|
|
309
|
+
data: result.data,
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
if (pluginConfig.debug) {
|
|
313
|
+
console.log('[CustomerHandler] Result:', result.success, result.message)
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// End span
|
|
317
|
+
if (spanContext && traceId) {
|
|
318
|
+
await tracer.endSpan(
|
|
319
|
+
{ userId: context.userId, teamId: context.teamId },
|
|
320
|
+
traceId,
|
|
321
|
+
spanContext.spanId,
|
|
322
|
+
{
|
|
323
|
+
output: { success: result.success, message: result.message, count: result.count },
|
|
324
|
+
toolInput: customerIntent.parameters,
|
|
325
|
+
toolOutput: result,
|
|
326
|
+
error: result.error ? new Error(result.error) : undefined,
|
|
327
|
+
}
|
|
328
|
+
)
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return {
|
|
332
|
+
handlerResults: {
|
|
333
|
+
...state.handlerResults,
|
|
334
|
+
customer: result,
|
|
335
|
+
},
|
|
336
|
+
completedHandlers: [...state.completedHandlers, 'customer' as IntentType],
|
|
337
|
+
}
|
|
338
|
+
}
|