@burdenoff/microfe-movethewheels 2026.716.2 → 2026.719.2

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.
@@ -387,13 +387,6 @@ export type GetMovethewheelsDashboardQueryVariables = Types.Exact<{ [key: string
387
387
 
388
388
  export type GetMovethewheelsDashboardQuery = { __typename?: 'Query', dashboardMetrics: { __typename?: 'DashboardMetrics', totalOrders: number, activeDeliveries: number, availableDrivers: number, activeVehicles: number, lowStockItems: number, totalRevenue: number, recentOrders: Array<{ __typename?: 'MovethewheelsOrder', id: string, orderNumber: string, orderType: Types.OrderType, status: Types.OrderStatus, priority: Types.OrderPriority, customerId: string, trackingNumber?: string | null, pickupAddress: Record<string, unknown>, deliveryAddress: Record<string, unknown>, items: Record<string, unknown>, pricing?: Record<string, unknown> | null, scheduledDelivery?: string | null, vehicleId?: string | null, driverId?: string | null, createdAt: string, updatedAt: string }> }, orderStats: { __typename?: 'OrderStats', total: number, pending: number, inTransit: number, delivered: number, cancelled: number, failed: number }, fleetStats: { __typename?: 'FleetStats', totalVehicles: number, activeVehicles: number, inTransitVehicles: number, maintenanceVehicles: number, totalDrivers: number, availableDrivers: number, onDeliveryDrivers: number }, financeMetrics: { __typename?: 'FinanceMetrics', fuelCost: number, openInvoices: number, revenue: { __typename?: 'RevenueMetrics', totalRevenue: number, averageOrderValue: number, deliveredRevenue: number } }, analytics: { __typename?: 'AnalyticsSeries', deliveryTrend: Array<{ __typename?: 'AnalyticsPoint', label: string, value: number }>, orderTrend: Array<{ __typename?: 'AnalyticsPoint', label: string, value: number }>, revenueTrend: Array<{ __typename?: 'AnalyticsPoint', label: string, value: number }> } };
389
389
 
390
- export type GetAssistantInsightsQueryVariables = Types.Exact<{
391
- question: Types.Scalars['String']['input'];
392
- }>;
393
-
394
-
395
- export type GetAssistantInsightsQuery = { __typename?: 'Query', assistantInsights: { __typename?: 'AssistantInsights', question: string, answer: string, generatedAt: string } };
396
-
397
390
  export type ListCustomersQueryVariables = Types.Exact<{
398
391
  filter?: Types.InputMaybe<Types.CustomerFilterInput>;
399
392
  pagination?: Types.InputMaybe<Types.PaginationInput>;
@@ -2466,51 +2459,6 @@ export type GetMovethewheelsDashboardQueryHookResult = ReturnType<typeof useGetM
2466
2459
  export type GetMovethewheelsDashboardLazyQueryHookResult = ReturnType<typeof useGetMovethewheelsDashboardLazyQuery>;
2467
2460
  export type GetMovethewheelsDashboardSuspenseQueryHookResult = ReturnType<typeof useGetMovethewheelsDashboardSuspenseQuery>;
2468
2461
  export type GetMovethewheelsDashboardQueryResult = Apollo.QueryResult<Types.GetMovethewheelsDashboardQuery, Types.GetMovethewheelsDashboardQueryVariables>;
2469
- export const GetAssistantInsightsDocument = gql`
2470
- query GetAssistantInsights($question: String!) {
2471
- assistantInsights(question: $question) {
2472
- question
2473
- answer
2474
- generatedAt
2475
- }
2476
- }
2477
- `;
2478
-
2479
- /**
2480
- * __useGetAssistantInsightsQuery__
2481
- *
2482
- * To run a query within a React component, call `useGetAssistantInsightsQuery` and pass it any options that fit your needs.
2483
- * When your component renders, `useGetAssistantInsightsQuery` returns an object from Apollo Client that contains loading, error, and data properties
2484
- * you can use to render your UI.
2485
- *
2486
- * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
2487
- *
2488
- * @example
2489
- * const { data, loading, error } = useGetAssistantInsightsQuery({
2490
- * variables: {
2491
- * question: // value for 'question'
2492
- * },
2493
- * });
2494
- */
2495
- export function useGetAssistantInsightsQuery(baseOptions: ApolloReactHooks.QueryHookOptions<Types.GetAssistantInsightsQuery, Types.GetAssistantInsightsQueryVariables> & ({ variables: Types.GetAssistantInsightsQueryVariables; skip?: boolean; } | { skip: boolean; }) ) {
2496
- const options = {...defaultOptions, ...baseOptions}
2497
- return ApolloReactHooks.useQuery<Types.GetAssistantInsightsQuery, Types.GetAssistantInsightsQueryVariables>(GetAssistantInsightsDocument, options);
2498
- }
2499
- export function useGetAssistantInsightsLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions<Types.GetAssistantInsightsQuery, Types.GetAssistantInsightsQueryVariables>) {
2500
- const options = {...defaultOptions, ...baseOptions}
2501
- return ApolloReactHooks.useLazyQuery<Types.GetAssistantInsightsQuery, Types.GetAssistantInsightsQueryVariables>(GetAssistantInsightsDocument, options);
2502
- }
2503
- // @ts-ignore
2504
- export function useGetAssistantInsightsSuspenseQuery(baseOptions?: ApolloReactHooks.SuspenseQueryHookOptions<Types.GetAssistantInsightsQuery, Types.GetAssistantInsightsQueryVariables>): ApolloReactHooks.UseSuspenseQueryResult<Types.GetAssistantInsightsQuery, Types.GetAssistantInsightsQueryVariables>;
2505
- export function useGetAssistantInsightsSuspenseQuery(baseOptions?: ApolloReactHooks.SkipToken | ApolloReactHooks.SuspenseQueryHookOptions<Types.GetAssistantInsightsQuery, Types.GetAssistantInsightsQueryVariables>): ApolloReactHooks.UseSuspenseQueryResult<Types.GetAssistantInsightsQuery | undefined, Types.GetAssistantInsightsQueryVariables>;
2506
- export function useGetAssistantInsightsSuspenseQuery(baseOptions?: ApolloReactHooks.SkipToken | ApolloReactHooks.SuspenseQueryHookOptions<Types.GetAssistantInsightsQuery, Types.GetAssistantInsightsQueryVariables>) {
2507
- const options = baseOptions === ApolloReactHooks.skipToken ? baseOptions : {...defaultOptions, ...baseOptions}
2508
- return ApolloReactHooks.useSuspenseQuery<Types.GetAssistantInsightsQuery, Types.GetAssistantInsightsQueryVariables>(GetAssistantInsightsDocument, options);
2509
- }
2510
- export type GetAssistantInsightsQueryHookResult = ReturnType<typeof useGetAssistantInsightsQuery>;
2511
- export type GetAssistantInsightsLazyQueryHookResult = ReturnType<typeof useGetAssistantInsightsLazyQuery>;
2512
- export type GetAssistantInsightsSuspenseQueryHookResult = ReturnType<typeof useGetAssistantInsightsSuspenseQuery>;
2513
- export type GetAssistantInsightsQueryResult = Apollo.QueryResult<Types.GetAssistantInsightsQuery, Types.GetAssistantInsightsQueryVariables>;
2514
2462
  export const ListCustomersDocument = gql`
2515
2463
  query ListCustomers($filter: CustomerFilterInput, $pagination: PaginationInput) {
2516
2464
  customers(filter: $filter, pagination: $pagination) {
@@ -13,14 +13,7 @@ export const OSM_ATTRIBUTION =
13
13
  '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors';
14
14
 
15
15
  export type MapMarkerStatus =
16
- | 'active'
17
- | 'in_transit'
18
- | 'idle'
19
- | 'delayed'
20
- | 'delivered'
21
- | 'origin'
22
- | 'destination'
23
- | 'default';
16
+ 'active' | 'in_transit' | 'idle' | 'delayed' | 'delivered' | 'origin' | 'destination' | 'default';
24
17
 
25
18
  /**
26
19
  * A coordinate is "real" only when it is finite and not the null-island (0,0)
@@ -56,9 +56,6 @@ export {
56
56
  useGeofence,
57
57
  } from './useTracking';
58
58
 
59
- // Assistant
60
- export { useAssistant } from './useAssistant';
61
-
62
59
  // Reports
63
60
  export { useReports } from './useReports';
64
61
 
@@ -34,7 +34,7 @@ const ANALYTICS_QUERY = `
34
34
  }
35
35
  }
36
36
  dashboardMetrics {
37
- totalOrders
37
+ totalDeliveryJobs
38
38
  activeDeliveries
39
39
  availableDrivers
40
40
  activeVehicles
@@ -55,7 +55,7 @@ const ANALYTICS_QUERY = `
55
55
  const DASHBOARD_QUERY = `
56
56
  query GetDashboardMetrics {
57
57
  dashboardMetrics {
58
- totalOrders
58
+ totalDeliveryJobs
59
59
  activeDeliveries
60
60
  availableDrivers
61
61
  activeVehicles
@@ -64,7 +64,7 @@ const DASHBOARD_QUERY = `
64
64
  onTimeDeliveryRate
65
65
  customerSatisfaction
66
66
  }
67
- orderStats {
67
+ deliveryJobStats {
68
68
  total
69
69
  pending
70
70
  inTransit
@@ -92,7 +92,7 @@ const DASHBOARD_QUERY = `
92
92
 
93
93
  const ORDER_ANALYTICS_QUERY = `
94
94
  query GetOrderAnalytics {
95
- orderStats {
95
+ deliveryJobStats {
96
96
  pending
97
97
  inTransit
98
98
  delivered
@@ -169,7 +169,7 @@ export function useAnalytics(_options: UseAnalyticsOptions = {}): UseAnalyticsRe
169
169
  revenueTrend: Array<{ label: string; value: number }>;
170
170
  };
171
171
  dashboardMetrics: {
172
- totalOrders: number;
172
+ totalDeliveryJobs: number;
173
173
  totalRevenue: number;
174
174
  activeVehicles: number;
175
175
  onTimeDeliveryRate: number;
@@ -185,7 +185,7 @@ export function useAnalytics(_options: UseAnalyticsOptions = {}): UseAnalyticsRe
185
185
 
186
186
  setAnalytics({
187
187
  overview: {
188
- totalOrders: data.dashboardMetrics.totalOrders,
188
+ totalOrders: data.dashboardMetrics.totalDeliveryJobs,
189
189
  totalRevenue: data.dashboardMetrics.totalRevenue,
190
190
  activeVehicles: data.dashboardMetrics.activeVehicles,
191
191
  onTimeDeliveryRate: data.dashboardMetrics.onTimeDeliveryRate,
@@ -304,7 +304,7 @@ export function useDashboardMetrics() {
304
304
  onTimeDeliveryRate: number;
305
305
  customerSatisfaction: number;
306
306
  };
307
- orderStats: {
307
+ deliveryJobStats: {
308
308
  total: number;
309
309
  pending: number;
310
310
  inTransit: number;
@@ -327,10 +327,10 @@ export function useDashboardMetrics() {
327
327
 
328
328
  setMetrics({
329
329
  orders: {
330
- total: data.orderStats.total,
331
- pending: data.orderStats.pending,
332
- inTransit: data.orderStats.inTransit,
333
- delivered: data.orderStats.delivered,
330
+ total: data.deliveryJobStats.total,
331
+ pending: data.deliveryJobStats.pending,
332
+ inTransit: data.deliveryJobStats.inTransit,
333
+ delivered: data.deliveryJobStats.delivered,
334
334
  today: 0,
335
335
  },
336
336
  fleet: {
@@ -414,7 +414,7 @@ export function useOrderAnalytics() {
414
414
  setError(null);
415
415
  try {
416
416
  const data = await executeGraphQL<{
417
- orderStats: {
417
+ deliveryJobStats: {
418
418
  pending: number;
419
419
  inTransit: number;
420
420
  delivered: number;
@@ -428,11 +428,11 @@ export function useOrderAnalytics() {
428
428
 
429
429
  setOrderData({
430
430
  byStatus: [
431
- { status: 'pending', count: data.orderStats.pending },
432
- { status: 'in_transit', count: data.orderStats.inTransit },
433
- { status: 'delivered', count: data.orderStats.delivered },
434
- { status: 'cancelled', count: data.orderStats.cancelled },
435
- { status: 'failed', count: data.orderStats.failed },
431
+ { status: 'pending', count: data.deliveryJobStats.pending },
432
+ { status: 'in_transit', count: data.deliveryJobStats.inTransit },
433
+ { status: 'delivered', count: data.deliveryJobStats.delivered },
434
+ { status: 'cancelled', count: data.deliveryJobStats.cancelled },
435
+ { status: 'failed', count: data.deliveryJobStats.failed },
436
436
  ],
437
437
  byType: [],
438
438
  byPriority: [],
@@ -61,7 +61,7 @@ export type {
61
61
  export { useMoveTheWheels, useMoveTheWheelsNavigate } from './providers/MoveTheWheelsProvider';
62
62
  export { useMoveTheWheelsStore } from './store/movethewheelsStore';
63
63
 
64
- // Transport adapter for the shared fe-libs AssistantWidget (workspace assistantInsights query).
64
+ // Transport adapter for the shared fe-libs AssistantWidget.
65
65
  // Consumers import it from the dedicated subpath
66
66
  // `@burdenoff/microfe-movethewheels/services/createSandboxAssistantTransport`
67
67
  // (see package.json exports) — that path has a clean, self-contained `.d.ts`.
@@ -1,206 +1,102 @@
1
1
  /**
2
- * AI Assistant Page
2
+ * AI Operations Page
3
+ *
4
+ * This page previously shipped a second, fabricated chat surface
5
+ * (`useAssistant` → `Query.assistantInsights`) whose "capabilities" list
6
+ * advertised route optimization, demand forecasting, fleet analysis, cost
7
+ * optimization and natural-language queries — none of which the backend
8
+ * implemented; every question routed to a fixed template built from four
9
+ * Prisma counts. See BOFF-3897.
10
+ *
11
+ * The real conversational assistant is the shared `AssistantWidget`, already
12
+ * mounted globally in the app shell (`AppShell.tsx`) on the sandbox
13
+ * transport — this page must never contain a second chat box.
14
+ *
15
+ * The full "AI Operations" surface this page is meant to become — a model
16
+ * picker, an agent-activity feed reading the shared AgentRun ledger,
17
+ * accept/reject decision cards for AI dispatch proposals, and per-workspace
18
+ * AI credit visibility — depends on the shared multi-model AI gateway
19
+ * (BOFF-3601), which has not landed yet. Until it does, this page shows an
20
+ * honest roadmap state instead of fabricating any of that content.
3
21
  */
4
22
 
5
- import { useState } from 'react';
6
- import { Bot, Send, Sparkles, Lightbulb, TrendingUp, Route, AlertCircle } from 'lucide-react';
7
- import { PageLayout } from '../components/PageLayout';
8
- import {
9
- Card,
10
- CardContent,
11
- CardHeader,
12
- CardTitle,
13
- Button,
14
- Input,
15
- Badge,
16
- ScrollArea,
17
- } from '../components/ui';
23
+ import { Bot, MessageCircle, Activity, ShieldCheck, Wallet } from 'lucide-react';
24
+ import { PageLayout, EmptyState } from '../components/PageLayout';
25
+ import { Card, CardContent, CardHeader, CardTitle } from '../components/ui';
18
26
  import { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';
19
- import { useAssistant } from '../hooks/useAssistant';
20
27
 
21
- interface ChatMessage {
22
- role: 'assistant' | 'user';
23
- content: string;
24
- isError?: boolean;
25
- }
28
+ const roadmapItems = [
29
+ {
30
+ icon: Activity,
31
+ title: 'Agent activity feed',
32
+ description:
33
+ 'A live log of what the AI decided, on which shipments, with trigger, model, latency and cost — so an autonomous run is never a black box.',
34
+ },
35
+ {
36
+ icon: ShieldCheck,
37
+ title: 'Dispatch decision cards',
38
+ description:
39
+ 'Proposed driver/vehicle assignments and carrier recommendations with rationale and confidence, requiring an explicit accept or reject before anything is written.',
40
+ },
41
+ {
42
+ icon: Wallet,
43
+ title: 'AI credit visibility',
44
+ description: 'Per-workspace AI spend for admins, so cost is visible before the invoice.',
45
+ },
46
+ ];
26
47
 
27
48
  export default function AIAssistantPage() {
28
- const { ask, isLoading } = useAssistant();
29
- const [message, setMessage] = useState('');
30
- const [messages, setMessages] = useState<ChatMessage[]>([
31
- {
32
- role: 'assistant',
33
- content:
34
- "Hello! I'm your logistics assistant. Ask me about your orders, deliveries, fleet or inventory and I'll answer from your live operational data.",
35
- },
36
- ]);
37
-
38
- const suggestions = [
39
- { icon: Route, text: "Optimize today's delivery routes", category: 'Route Planning' },
40
- { icon: TrendingUp, text: 'Show demand forecast for next week', category: 'Analytics' },
41
- { icon: AlertCircle, text: 'Identify potential delivery delays', category: 'Alerts' },
42
- { icon: Lightbulb, text: 'Suggest fleet efficiency improvements', category: 'Insights' },
43
- ];
44
-
45
- const capabilities = [
46
- 'Route Optimization - Find the most efficient delivery routes',
47
- 'Demand Forecasting - Predict order volumes and trends',
48
- 'Fleet Analysis - Insights on vehicle and driver performance',
49
- 'Cost Optimization - Identify ways to reduce operational costs',
50
- 'Natural Language Queries - Ask questions in plain English',
51
- ];
52
-
53
- const submit = async (question: string) => {
54
- const trimmed = question.trim();
55
- if (!trimmed || isLoading) return;
56
- setMessage('');
57
- setMessages((previous) => [...previous, { role: 'user', content: trimmed }]);
58
- try {
59
- const result = await ask(trimmed);
60
- setMessages((previous) => [...previous, { role: 'assistant', content: result.answer }]);
61
- } catch (fetchError) {
62
- setMessages((previous) => [
63
- ...previous,
64
- {
65
- role: 'assistant',
66
- content:
67
- fetchError instanceof Error
68
- ? `Sorry, I couldn't answer that: ${fetchError.message}`
69
- : "Sorry, I couldn't reach the assistant. Please try again.",
70
- isError: true,
71
- },
72
- ]);
73
- }
74
- };
75
-
76
- const handleSend = () => {
77
- void submit(message);
78
- };
79
-
80
49
  return (
81
50
  <PageLayout
82
- title="AI Assistant"
83
- subtitle="Intelligent logistics support"
51
+ title="AI Operations"
52
+ subtitle="What the AI is doing on your workspace, and why"
84
53
  icon={<Bot size={24} />}
85
54
  >
86
55
  <PagePurpose icon={<Bot size={18} />}>
87
- Ask plain-English questions about your operation and get answers backed by your own data.
88
- Use it to optimize routes, forecast demand, spot likely delays, and run what-if scenarios
89
- (e.g. &ldquo;what if I add two vehicles?&rdquo;) — like having a logistics analyst on call.
56
+ This page will surface AI-driven dispatch decisions and their outcomes once the shared AI
57
+ runtime lands. It does not host a chat box — chat with your live operational data is always
58
+ available from the assistant icon anywhere in the app.
90
59
  </PagePurpose>
91
60
 
92
- <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
93
- <div className="lg:col-span-2 space-y-4">
94
- {/* Chat — the page's single emphasis zone */}
95
- <GlassCard treatment="glass" glow className="h-[600px] flex flex-col">
96
- <CardHeader className="border-b border-border-seam">
97
- <CardTitle className="flex items-center gap-2">
98
- <Sparkles size={18} className="text-primary" /> Chat with AI
99
- </CardTitle>
100
- </CardHeader>
101
- <ScrollArea className="flex-1 p-4">
102
- <div className="space-y-4">
103
- {messages.map((msg, i) => (
104
- <div
105
- key={i}
106
- className={`flex ${msg.role === 'user' ? 'justify-end' : 'justify-start'}`}
107
- >
108
- <div
109
- className={`max-w-[80%] p-3 rounded-lg ${
110
- msg.role === 'user'
111
- ? 'bg-action-primary-bg text-action-primary-text'
112
- : msg.isError
113
- ? 'bg-status-error-bg-subtle text-status-error-text'
114
- : 'bg-bg-sunken'
115
- }`}
116
- >
117
- <p className="whitespace-pre-line text-sm">{msg.content}</p>
118
- </div>
119
- </div>
120
- ))}
121
- {isLoading && (
122
- <div className="flex justify-start" aria-live="polite">
123
- <div className="max-w-[80%] p-3 rounded-lg bg-bg-sunken flex items-center gap-2">
124
- <Sparkles size={14} className="text-primary motion-safe:animate-pulse" />
125
- <span className="text-sm text-text-secondary">Analyzing your data…</span>
126
- </div>
127
- </div>
128
- )}
129
- </div>
130
- </ScrollArea>
131
- <div className="p-4 border-t">
132
- <div className="flex gap-2">
133
- <Input
134
- value={message}
135
- onChange={(e) => setMessage(e.target.value)}
136
- placeholder="Ask me anything about your logistics operations..."
137
- disabled={isLoading}
138
- onKeyPress={(e) => e.key === 'Enter' && handleSend()}
139
- />
140
- <Button onClick={handleSend} disabled={isLoading || !message.trim()}>
141
- <Send size={16} />
142
- </Button>
143
- </div>
144
- </div>
145
- </GlassCard>
61
+ <GlassCard treatment="glass" className="p-4">
62
+ <div className="flex items-start gap-3">
63
+ <MessageCircle size={20} className="text-primary flex-shrink-0 mt-0.5" />
64
+ <div>
65
+ <p className="text-sm font-medium text-text-primary">
66
+ Looking to ask a question about your operations?
67
+ </p>
68
+ <p className="text-sm text-text-secondary mt-1">
69
+ Open the assistant from its icon in the corner of the screen — it answers from your
70
+ live orders, shipments, fleet and inventory data, and it is the only chat surface in
71
+ this product.
72
+ </p>
73
+ </div>
146
74
  </div>
75
+ </GlassCard>
147
76
 
148
- <div className="space-y-6">
149
- <Card>
150
- <CardHeader>
151
- <CardTitle>Quick Actions</CardTitle>
152
- </CardHeader>
153
- <CardContent className="space-y-2">
154
- {suggestions.map((s, i) => (
155
- <Button
156
- key={i}
157
- variant="outline"
158
- className="w-full justify-start text-left h-auto py-3"
159
- disabled={isLoading}
160
- onClick={() => void submit(s.text)}
161
- >
162
- <s.icon size={16} className="mr-2 flex-shrink-0" />
163
- <span className="flex-1">{s.text}</span>
164
- <Badge variant="secondary" className="text-xs">
165
- {s.category}
166
- </Badge>
167
- </Button>
168
- ))}
169
- </CardContent>
170
- </Card>
171
-
172
- <Card>
173
- <CardHeader>
174
- <CardTitle>Capabilities</CardTitle>
175
- </CardHeader>
176
- <CardContent>
177
- <ul className="space-y-2 text-sm">
178
- {capabilities.map((cap, i) => (
179
- <li key={i} className="flex items-start gap-2">
180
- <Sparkles size={14} className="text-primary mt-0.5 flex-shrink-0" />
181
- <span>{cap}</span>
182
- </li>
183
- ))}
184
- </ul>
185
- </CardContent>
186
- </Card>
187
-
188
- <Card className="bg-action-primary-bg/5 border-primary/20">
189
- <CardContent className="p-4">
190
- <div className="flex items-start gap-3">
191
- <Lightbulb size={20} className="text-primary flex-shrink-0" />
77
+ <Card>
78
+ <CardHeader>
79
+ <CardTitle>On the roadmap</CardTitle>
80
+ </CardHeader>
81
+ <CardContent>
82
+ <EmptyState
83
+ illustration="empty-agents"
84
+ title="Autonomous dispatch operations aren't live yet"
85
+ description="These capabilities depend on the shared multi-model AI gateway and agent-run ledger (BOFF-3601), which hasn't shipped across the platform yet. Nothing below is available today."
86
+ />
87
+ <ul className="mt-4 space-y-4">
88
+ {roadmapItems.map((item) => (
89
+ <li key={item.title} className="flex items-start gap-3">
90
+ <item.icon size={18} className="text-text-secondary flex-shrink-0 mt-0.5" />
192
91
  <div>
193
- <p className="font-medium text-sm">Pro Tip</p>
194
- <p className="text-xs text-text-secondary">
195
- You can ask complex questions like "What would happen if I added 2 more vehicles
196
- to my fleet?" for scenario analysis.
197
- </p>
92
+ <p className="text-sm font-medium text-text-primary">{item.title}</p>
93
+ <p className="text-xs text-text-secondary">{item.description}</p>
198
94
  </div>
199
- </div>
200
- </CardContent>
201
- </Card>
202
- </div>
203
- </div>
95
+ </li>
96
+ ))}
97
+ </ul>
98
+ </CardContent>
99
+ </Card>
204
100
  </PageLayout>
205
101
  );
206
102
  }
@@ -10,7 +10,6 @@
10
10
 
11
11
  import { useSandboxAssistantTransport as useSharedTransport } from '@burdenoff/fe-libs/shared/assistant';
12
12
 
13
-
14
13
  interface AssistantSendArgs {
15
14
  prompt: string;
16
15
  onProgress: (partialText: string) => void;
@@ -26,7 +25,7 @@ export interface AssistantTransport {
26
25
  export function useSandboxAssistantTransport(): AssistantTransport {
27
26
  return useSharedTransport({
28
27
  product: 'movethewheels',
29
-
28
+
30
29
  enableCredits: true,
31
30
  });
32
31
  }
@@ -51,11 +51,3 @@ query GetMovethewheelsDashboard {
51
51
  }
52
52
  }
53
53
  }
54
-
55
- query GetAssistantInsights($question: String!) {
56
- assistantInsights(question: $question) {
57
- question
58
- answer
59
- generatedAt
60
- }
61
- }
@@ -1,39 +0,0 @@
1
- import { useMoveTheWheels as e } from "../providers/MoveTheWheelsProvider.js";
2
- import { executeGraphQL as t } from "../utils/graphqlClient.js";
3
- import { useCallback as n, useMemo as r, useState as i } from "react";
4
- //#region src/movethewheels/hooks/useAssistant.ts
5
- var a = "\n query MovethewheelsAssistantInsights($question: String!) {\n assistantInsights(question: $question) {\n answer\n generatedAt\n question\n }\n }\n";
6
- function o() {
7
- let { apiGatewayUrl: o, authToken: s, workspaceToken: c, workspaceId: l, tenantId: u, currentUser: d } = e(), [f, p] = i(!1), [m, h] = i(null), g = r(() => ({
8
- apiGatewayUrl: o,
9
- authToken: s,
10
- workspaceToken: c,
11
- workspaceId: l,
12
- tenantId: u,
13
- actorId: d?.id
14
- }), [
15
- o,
16
- s,
17
- c,
18
- l,
19
- u,
20
- d?.id
21
- ]);
22
- return {
23
- ask: n(async (e) => {
24
- p(!0), h(null);
25
- try {
26
- return (await t(g, a, { question: e })).assistantInsights;
27
- } catch (e) {
28
- let t = e instanceof Error ? e : /* @__PURE__ */ Error("Failed to get assistant response");
29
- throw h(t), t;
30
- } finally {
31
- p(!1);
32
- }
33
- }, [g]),
34
- isLoading: f,
35
- error: m
36
- };
37
- }
38
- //#endregion
39
- export { o as useAssistant };
@@ -1,17 +0,0 @@
1
- export interface AssistantAnswer {
2
- answer: string;
3
- generatedAt: string;
4
- question: string;
5
- }
6
- interface UseAssistantResult {
7
- ask: (question: string) => Promise<AssistantAnswer>;
8
- isLoading: boolean;
9
- error: Error | null;
10
- }
11
- /**
12
- * useAssistant — queries the real logistics assistant (Query.assistantInsights).
13
- * The backend answers from the caller's own operational data; there is no
14
- * client-side canned response.
15
- */
16
- export declare function useAssistant(): UseAssistantResult;
17
- export {};
@@ -1,18 +0,0 @@
1
- import { createLucideIcon as e } from "../createLucideIcon.js";
2
- //#region node_modules/lucide-react/dist/esm/icons/lightbulb.js
3
- var t = e("Lightbulb", [
4
- ["path", {
5
- d: "M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5",
6
- key: "1gvzjb"
7
- }],
8
- ["path", {
9
- d: "M9 18h6",
10
- key: "x1upvd"
11
- }],
12
- ["path", {
13
- d: "M10 22h4",
14
- key: "ceow96"
15
- }]
16
- ]);
17
- //#endregion
18
- export { t as Lightbulb };
@@ -1,11 +0,0 @@
1
- import { createLucideIcon as e } from "../createLucideIcon.js";
2
- //#region node_modules/lucide-react/dist/esm/icons/send.js
3
- var t = e("Send", [["path", {
4
- d: "M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",
5
- key: "1ffxy3"
6
- }], ["path", {
7
- d: "m21.854 2.147-10.94 10.939",
8
- key: "12cjpa"
9
- }]]);
10
- //#endregion
11
- export { t as Send };
@@ -1,26 +0,0 @@
1
- import { createLucideIcon as e } from "../createLucideIcon.js";
2
- //#region node_modules/lucide-react/dist/esm/icons/sparkles.js
3
- var t = e("Sparkles", [
4
- ["path", {
5
- d: "M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z",
6
- key: "4pj2yx"
7
- }],
8
- ["path", {
9
- d: "M20 3v4",
10
- key: "1olli1"
11
- }],
12
- ["path", {
13
- d: "M22 5h-4",
14
- key: "1gvqau"
15
- }],
16
- ["path", {
17
- d: "M4 17v2",
18
- key: "vumght"
19
- }],
20
- ["path", {
21
- d: "M5 18H3",
22
- key: "zchphs"
23
- }]
24
- ]);
25
- //#endregion
26
- export { t as Sparkles };