@happyvertical/smrt-agents 0.30.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.
Files changed (94) hide show
  1. package/AGENTS.md +96 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +7 -0
  4. package/README.md +139 -0
  5. package/dist/__smrt-register__.d.ts +2 -0
  6. package/dist/__smrt-register__.d.ts.map +1 -0
  7. package/dist/agent.d.ts +545 -0
  8. package/dist/agent.d.ts.map +1 -0
  9. package/dist/ai-config.d.ts +27 -0
  10. package/dist/ai-config.d.ts.map +1 -0
  11. package/dist/chunks/config-BYbOxt24.js +179 -0
  12. package/dist/chunks/config-BYbOxt24.js.map +1 -0
  13. package/dist/chunks/manifest-utils-DLXfTOq0.js +69 -0
  14. package/dist/chunks/manifest-utils-DLXfTOq0.js.map +1 -0
  15. package/dist/config.d.ts +117 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/identity.d.ts +19 -0
  18. package/dist/identity.d.ts.map +1 -0
  19. package/dist/index.d.ts +13 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +1477 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/interests.d.ts +291 -0
  24. package/dist/interests.d.ts.map +1 -0
  25. package/dist/manifest.json +2012 -0
  26. package/dist/playground.d.ts +2 -0
  27. package/dist/playground.d.ts.map +1 -0
  28. package/dist/playground.js +156 -0
  29. package/dist/playground.js.map +1 -0
  30. package/dist/schedule.d.ts +168 -0
  31. package/dist/schedule.d.ts.map +1 -0
  32. package/dist/server/action-types.d.ts +65 -0
  33. package/dist/server/action-types.d.ts.map +1 -0
  34. package/dist/server/action-types.js +2 -0
  35. package/dist/server/action-types.js.map +1 -0
  36. package/dist/server/api-routes.d.ts +57 -0
  37. package/dist/server/api-routes.d.ts.map +1 -0
  38. package/dist/server/config-loader.d.ts +17 -0
  39. package/dist/server/config-loader.d.ts.map +1 -0
  40. package/dist/server/index.d.ts +34 -0
  41. package/dist/server/index.d.ts.map +1 -0
  42. package/dist/server/manifest-utils.d.ts +63 -0
  43. package/dist/server/manifest-utils.d.ts.map +1 -0
  44. package/dist/server/serialization.d.ts +58 -0
  45. package/dist/server/serialization.d.ts.map +1 -0
  46. package/dist/server.js +105 -0
  47. package/dist/server.js.map +1 -0
  48. package/dist/smrt-knowledge.json +983 -0
  49. package/dist/summary-article.d.ts +30 -0
  50. package/dist/summary-article.d.ts.map +1 -0
  51. package/dist/summary-article.js +2 -0
  52. package/dist/summary-article.js.map +1 -0
  53. package/dist/svelte/components/AgentDashboard.svelte +250 -0
  54. package/dist/svelte/components/AgentDashboard.svelte.d.ts +21 -0
  55. package/dist/svelte/components/AgentDashboard.svelte.d.ts.map +1 -0
  56. package/dist/svelte/components/AgentRunHistory.svelte +225 -0
  57. package/dist/svelte/components/AgentRunHistory.svelte.d.ts +16 -0
  58. package/dist/svelte/components/AgentRunHistory.svelte.d.ts.map +1 -0
  59. package/dist/svelte/components/AgentScheduleForm.svelte +381 -0
  60. package/dist/svelte/components/AgentScheduleForm.svelte.d.ts +19 -0
  61. package/dist/svelte/components/AgentScheduleForm.svelte.d.ts.map +1 -0
  62. package/dist/svelte/components/AgentScheduleList.svelte +370 -0
  63. package/dist/svelte/components/AgentScheduleList.svelte.d.ts +24 -0
  64. package/dist/svelte/components/AgentScheduleList.svelte.d.ts.map +1 -0
  65. package/dist/svelte/components/ScheduleStatusBadge.svelte +23 -0
  66. package/dist/svelte/components/ScheduleStatusBadge.svelte.d.ts +9 -0
  67. package/dist/svelte/components/ScheduleStatusBadge.svelte.d.ts.map +1 -0
  68. package/dist/svelte/i18n.d.ts +33 -0
  69. package/dist/svelte/i18n.d.ts.map +1 -0
  70. package/dist/svelte/i18n.js +37 -0
  71. package/dist/svelte/index.d.ts +23 -0
  72. package/dist/svelte/index.d.ts.map +1 -0
  73. package/dist/svelte/index.js +26 -0
  74. package/dist/svelte/playground.d.ts +196 -0
  75. package/dist/svelte/playground.d.ts.map +1 -0
  76. package/dist/svelte/playground.js +151 -0
  77. package/dist/svelte/types.d.ts +155 -0
  78. package/dist/svelte/types.d.ts.map +1 -0
  79. package/dist/svelte/types.js +116 -0
  80. package/dist/tenant-agent.d.ts +106 -0
  81. package/dist/tenant-agent.d.ts.map +1 -0
  82. package/dist/types.d.ts +5 -0
  83. package/dist/types.d.ts.map +1 -0
  84. package/dist/types.js +2 -0
  85. package/dist/types.js.map +1 -0
  86. package/dist/ui.d.ts +298 -0
  87. package/dist/ui.d.ts.map +1 -0
  88. package/dist/ui.js +133 -0
  89. package/dist/ui.js.map +1 -0
  90. package/dist/vite-plugin.d.ts +61 -0
  91. package/dist/vite-plugin.d.ts.map +1 -0
  92. package/dist/vite-plugin.js +173 -0
  93. package/dist/vite-plugin.js.map +1 -0
  94. package/package.json +104 -0
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Canonical types for agent summary article generation.
3
+ * All agents that implement summaryArticle() must return SummaryArticleResult.
4
+ */
5
+ export interface SummaryArticleImage {
6
+ url: string;
7
+ alt?: string;
8
+ caption?: string;
9
+ }
10
+ export interface SummaryArticleResult {
11
+ title: string;
12
+ summary: string;
13
+ body: string;
14
+ /** ISO 8601 date strings for the covered period */
15
+ dateRange: {
16
+ start: Date | string;
17
+ end: Date | string;
18
+ };
19
+ images?: SummaryArticleImage[];
20
+ scope?: Partial<Record<string, string | number>>;
21
+ stats?: Record<string, number>;
22
+ }
23
+ export interface SummaryArticleOptions {
24
+ startDate: Date | string;
25
+ endDate: Date | string;
26
+ filters?: Record<string, string>;
27
+ style?: string;
28
+ tone?: string;
29
+ }
30
+ //# sourceMappingURL=summary-article.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary-article.d.ts","sourceRoot":"","sources":["../src/summary-article.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,SAAS,EAAE;QAAE,KAAK,EAAE,IAAI,GAAG,MAAM,CAAC;QAAC,GAAG,EAAE,IAAI,GAAG,MAAM,CAAA;KAAE,CAAC;IACxD,MAAM,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,IAAI,GAAG,MAAM,CAAC;IACzB,OAAO,EAAE,IAAI,GAAG,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=summary-article.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary-article.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,250 @@
1
+ <script lang="ts">
2
+ /**
3
+ * AgentDashboard - Combined overview panel for agent schedules
4
+ */
5
+
6
+ import { useI18n } from '@happyvertical/smrt-ui/i18n';
7
+ import { Button, Card } from '@happyvertical/smrt-ui/ui';
8
+ import { M } from '../i18n.js';
9
+ import type { AgentRunHistoryEntry, AgentScheduleData } from '../types.js';
10
+ import AgentRunHistory from './AgentRunHistory.svelte';
11
+ import AgentScheduleList from './AgentScheduleList.svelte';
12
+
13
+ const { t } = useI18n();
14
+
15
+ export interface Props {
16
+ /** All schedules */
17
+ schedules: AgentScheduleData[];
18
+ /** Recent run history */
19
+ recentHistory?: AgentRunHistoryEntry[];
20
+ /** Loading state */
21
+ loading?: boolean;
22
+ /** Callbacks */
23
+ onScheduleClick?: (schedule: AgentScheduleData) => void;
24
+ onEnable?: (schedule: AgentScheduleData) => void;
25
+ onDisable?: (schedule: AgentScheduleData) => void;
26
+ onDelete?: (schedule: AgentScheduleData) => void;
27
+ onRunNow?: (schedule: AgentScheduleData) => void;
28
+ onCreateSchedule?: () => void;
29
+ onHistoryEntryClick?: (entry: AgentRunHistoryEntry) => void;
30
+ }
31
+
32
+ let {
33
+ schedules = [],
34
+ recentHistory = [],
35
+ loading = false,
36
+ onScheduleClick,
37
+ onEnable,
38
+ onDisable,
39
+ onDelete,
40
+ onRunNow,
41
+ onCreateSchedule,
42
+ onHistoryEntryClick,
43
+ }: Props = $props();
44
+
45
+ // Computed stats
46
+ const stats = $derived.by(() => {
47
+ const active = schedules.filter((s) => s.status === 'active').length;
48
+ const paused = schedules.filter((s) => s.status === 'paused').length;
49
+ const disabled = schedules.filter((s) => s.status === 'disabled').length;
50
+ const error = schedules.filter((s) => s.status === 'error').length;
51
+ const running = schedules.reduce((sum, s) => sum + s.runningCount, 0);
52
+ const totalRuns = schedules.reduce((sum, s) => sum + s.runCount, 0);
53
+ const totalSuccesses = schedules.reduce((sum, s) => sum + s.successCount, 0);
54
+ const successRate = totalRuns > 0 ? totalSuccesses / totalRuns : null;
55
+
56
+ return { active, paused, disabled, error, running, totalRuns, successRate };
57
+ });
58
+ </script>
59
+
60
+ <div class="agent-dashboard" class:loading>
61
+ <!-- Stats Overview -->
62
+ <section class="agent-dashboard__stats">
63
+ <div class="stats-grid">
64
+ <Card padding="sm">
65
+ <div class="stat-card">
66
+ <div class="stat-card__value">{schedules.length}</div>
67
+ <div class="stat-card__label">{t(M['agents.dashboard.total_schedules'])}</div>
68
+ </div>
69
+ </Card>
70
+
71
+ <Card padding="sm">
72
+ <div class="stat-card stat-card--active">
73
+ <div class="stat-card__value">{stats.active}</div>
74
+ <div class="stat-card__label">Active</div>
75
+ </div>
76
+ </Card>
77
+
78
+ <Card padding="sm">
79
+ <div class="stat-card stat-card--running">
80
+ <div class="stat-card__value">{stats.running}</div>
81
+ <div class="stat-card__label">{t(M['agents.dashboard.running_now'])}</div>
82
+ </div>
83
+ </Card>
84
+
85
+ <Card padding="sm">
86
+ <div class="stat-card">
87
+ <div class="stat-card__value">{stats.totalRuns.toLocaleString()}</div>
88
+ <div class="stat-card__label">{t(M['agents.dashboard.total_runs'])}</div>
89
+ </div>
90
+ </Card>
91
+
92
+ <Card padding="sm">
93
+ <div class="stat-card">
94
+ <div class="stat-card__value">
95
+ {stats.successRate !== null
96
+ ? `${(stats.successRate * 100).toFixed(1)}%`
97
+ : '-'}
98
+ </div>
99
+ <div class="stat-card__label">{t(M['agents.dashboard.success_rate'])}</div>
100
+ </div>
101
+ </Card>
102
+
103
+ {#if stats.error > 0}
104
+ <Card padding="sm">
105
+ <div class="stat-card stat-card--error">
106
+ <div class="stat-card__value">{stats.error}</div>
107
+ <div class="stat-card__label">Errors</div>
108
+ </div>
109
+ </Card>
110
+ {/if}
111
+ </div>
112
+ </section>
113
+
114
+ <!-- Schedules List -->
115
+ <section class="agent-dashboard__section">
116
+ <Card>
117
+ {#snippet header()}
118
+ <div class="panel-header">
119
+ <h2>{t(M['agents.dashboard.scheduled_agents'])}</h2>
120
+ {#if onCreateSchedule}
121
+ <Button variant="primary" size="sm" onclick={onCreateSchedule}>
122
+ {t(M['agents.dashboard.new_schedule'])}
123
+ </Button>
124
+ {/if}
125
+ </div>
126
+ {/snippet}
127
+
128
+ <AgentScheduleList
129
+ {schedules}
130
+ {loading}
131
+ {onScheduleClick}
132
+ {onEnable}
133
+ {onDisable}
134
+ {onRunNow}
135
+ >
136
+ {#snippet empty()}
137
+ <div class="empty-state">
138
+ <p>{t(M['agents.dashboard.no_scheduled_agents'])}</p>
139
+ {#if onCreateSchedule}
140
+ <Button variant="secondary" onclick={onCreateSchedule}>
141
+ {t(M['agents.dashboard.create_first_schedule'])}
142
+ </Button>
143
+ {/if}
144
+ </div>
145
+ {/snippet}
146
+ </AgentScheduleList>
147
+ </Card>
148
+ </section>
149
+
150
+ <!-- Recent Run History -->
151
+ {#if recentHistory.length > 0}
152
+ <section class="agent-dashboard__section">
153
+ <Card>
154
+ {#snippet header()}
155
+ <div class="panel-header">
156
+ <h2>{t(M['agents.dashboard.recent_runs'])}</h2>
157
+ </div>
158
+ {/snippet}
159
+
160
+ <AgentRunHistory
161
+ history={recentHistory}
162
+ {loading}
163
+ onEntryClick={onHistoryEntryClick}
164
+ />
165
+ </Card>
166
+ </section>
167
+ {/if}
168
+ </div>
169
+
170
+ <style>
171
+ .agent-dashboard {
172
+ width: 100%;
173
+ display: flex;
174
+ flex-direction: column;
175
+ gap: var(--smrt-spacing-lg, 1.5rem);
176
+ }
177
+
178
+ .agent-dashboard.loading {
179
+ opacity: 0.7;
180
+ pointer-events: none;
181
+ }
182
+
183
+ @media (prefers-reduced-motion: reduce) {
184
+ .agent-dashboard.loading {
185
+ transition: none;
186
+ }
187
+ }
188
+
189
+ .agent-dashboard__stats {
190
+ width: 100%;
191
+ }
192
+
193
+ .stats-grid {
194
+ display: grid;
195
+ grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
196
+ gap: var(--smrt-spacing-md, 1rem);
197
+ }
198
+
199
+ .stat-card {
200
+ text-align: center;
201
+ padding: var(--smrt-spacing-xs, 0.25rem);
202
+ }
203
+
204
+ .stat-card__value {
205
+ font: var(--smrt-typography-headline-small-font, 700 1.5rem / 1.2 sans-serif);
206
+ }
207
+
208
+ .stat-card__label {
209
+ font: var(--smrt-typography-body-small-font, 0.875rem / 1.25 sans-serif);
210
+ color: var(--smrt-color-on-surface-variant, #43474e);
211
+ margin-top: var(--smrt-spacing-xs, 0.25rem);
212
+ }
213
+
214
+ .stat-card--active .stat-card__value {
215
+ color: var(--smrt-color-tertiary, #006c4f);
216
+ }
217
+
218
+ .stat-card--running .stat-card__value {
219
+ color: var(--smrt-color-primary, #005ac1);
220
+ }
221
+
222
+ .stat-card--error .stat-card__value {
223
+ color: var(--smrt-color-error, #ba1a1a);
224
+ }
225
+
226
+ .agent-dashboard__section {
227
+ width: 100%;
228
+ }
229
+
230
+ .panel-header {
231
+ display: flex;
232
+ justify-content: space-between;
233
+ align-items: center;
234
+ }
235
+
236
+ .panel-header h2 {
237
+ margin: 0;
238
+ font: var(--smrt-typography-title-medium-font, 600 1rem / 1.5 sans-serif);
239
+ }
240
+
241
+ .empty-state {
242
+ padding: var(--smrt-spacing-lg, 1.5rem);
243
+ text-align: center;
244
+ color: var(--smrt-color-on-surface-variant, #43474e);
245
+ }
246
+
247
+ .empty-state p {
248
+ margin: 0 0 var(--smrt-spacing-md, 1rem) 0;
249
+ }
250
+ </style>
@@ -0,0 +1,21 @@
1
+ import type { AgentRunHistoryEntry, AgentScheduleData } from '../types.js';
2
+ export interface Props {
3
+ /** All schedules */
4
+ schedules: AgentScheduleData[];
5
+ /** Recent run history */
6
+ recentHistory?: AgentRunHistoryEntry[];
7
+ /** Loading state */
8
+ loading?: boolean;
9
+ /** Callbacks */
10
+ onScheduleClick?: (schedule: AgentScheduleData) => void;
11
+ onEnable?: (schedule: AgentScheduleData) => void;
12
+ onDisable?: (schedule: AgentScheduleData) => void;
13
+ onDelete?: (schedule: AgentScheduleData) => void;
14
+ onRunNow?: (schedule: AgentScheduleData) => void;
15
+ onCreateSchedule?: () => void;
16
+ onHistoryEntryClick?: (entry: AgentRunHistoryEntry) => void;
17
+ }
18
+ declare const AgentDashboard: import("svelte").Component<Props, {}, "">;
19
+ type AgentDashboard = ReturnType<typeof AgentDashboard>;
20
+ export default AgentDashboard;
21
+ //# sourceMappingURL=AgentDashboard.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentDashboard.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/AgentDashboard.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAK3E,MAAM,WAAW,KAAK;IACpB,oBAAoB;IACpB,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,yBAAyB;IACzB,aAAa,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACvC,oBAAoB;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB;IAChB,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjD,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAClD,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjD,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAC7D;AAiJD,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -0,0 +1,225 @@
1
+ <script lang="ts">
2
+ /**
3
+ * AgentRunHistory - Display run history for an agent
4
+ */
5
+
6
+ import { useI18n } from '@happyvertical/smrt-ui/i18n';
7
+ import { Badge } from '@happyvertical/smrt-ui/ui';
8
+ import type { Snippet } from 'svelte';
9
+ import { M } from '../i18n.js';
10
+ import type { AgentRunHistoryEntry } from '../types.js';
11
+ import {
12
+ formatDuration,
13
+ formatRelativeTime,
14
+ getRunStatusVariant,
15
+ } from '../types.js';
16
+
17
+ const { t } = useI18n();
18
+
19
+ export interface Props {
20
+ /** Run history entries */
21
+ history: AgentRunHistoryEntry[];
22
+ /** Loading state */
23
+ loading?: boolean;
24
+ /** Callback when entry is clicked */
25
+ onEntryClick?: (entry: AgentRunHistoryEntry) => void;
26
+ /** Empty state snippet */
27
+ empty?: Snippet;
28
+ }
29
+
30
+ let { history = [], loading = false, onEntryClick, empty }: Props = $props();
31
+
32
+ function handleEntryClick(entry: AgentRunHistoryEntry) {
33
+ onEntryClick?.(entry);
34
+ }
35
+ </script>
36
+
37
+ <div class="run-history-container">
38
+ <table class="run-history" class:loading>
39
+ <thead class="run-history__head">
40
+ <tr>
41
+ <th class="run-history__cell">Status</th>
42
+ <th class="run-history__cell">Agent</th>
43
+ <th class="run-history__cell">Started</th>
44
+ <th class="run-history__cell">Duration</th>
45
+ <th class="run-history__cell">Error</th>
46
+ </tr>
47
+ </thead>
48
+
49
+ <tbody class="run-history__body">
50
+ {#if loading}
51
+ <tr class="run-history__row run-history__row--loading">
52
+ <td class="run-history__cell run-history__cell--loading" colspan="5">
53
+ <div class="run-history__loading">
54
+ <span class="run-history__spinner"></span>
55
+ <span>{t(M['agents.run_history.loading_history'])}</span>
56
+ </div>
57
+ </td>
58
+ </tr>
59
+ {:else if history.length === 0}
60
+ <tr class="run-history__row run-history__row--empty">
61
+ <td class="run-history__cell run-history__cell--empty" colspan="5">
62
+ {#if empty}
63
+ {@render empty()}
64
+ {:else}
65
+ <div class="run-history__empty">
66
+ <span>{t(M['agents.run_history.no_run_history'])}</span>
67
+ </div>
68
+ {/if}
69
+ </td>
70
+ </tr>
71
+ {:else}
72
+ {#each history as entry (entry.id)}
73
+ <tr
74
+ class="run-history__row"
75
+ onclick={() => handleEntryClick(entry)}
76
+ role={onEntryClick ? 'button' : undefined}
77
+ tabindex={onEntryClick ? 0 : undefined}
78
+ >
79
+ <td class="run-history__cell">
80
+ <Badge variant={getRunStatusVariant(entry.status)} size="sm">
81
+ {entry.status === 'success' ? 'Success' : 'Failed'}
82
+ </Badge>
83
+ </td>
84
+ <td class="run-history__cell run-history__cell--agent">
85
+ {entry.agentType}
86
+ </td>
87
+ <td class="run-history__cell run-history__cell--date">
88
+ {formatRelativeTime(entry.startedAt)}
89
+ </td>
90
+ <td class="run-history__cell run-history__cell--duration">
91
+ {formatDuration(entry.duration)}
92
+ </td>
93
+ <td class="run-history__cell run-history__cell--error">
94
+ {#if entry.error}
95
+ <span class="error-text" title={entry.error}>
96
+ {entry.error.length > 50 ? entry.error.slice(0, 50) + '...' : entry.error}
97
+ </span>
98
+ {:else}
99
+ <span class="no-error">-</span>
100
+ {/if}
101
+ </td>
102
+ </tr>
103
+ {/each}
104
+ {/if}
105
+ </tbody>
106
+ </table>
107
+ </div>
108
+
109
+ <style>
110
+ .run-history-container {
111
+ width: 100%;
112
+ overflow-x: auto;
113
+ }
114
+
115
+ .run-history {
116
+ width: 100%;
117
+ border-collapse: collapse;
118
+ border-spacing: 0;
119
+ font: var(--smrt-typography-body-medium-font, 0.875rem / 1.25 sans-serif);
120
+ background: var(--smrt-color-surface, #ffffff);
121
+ }
122
+
123
+ .run-history.loading {
124
+ opacity: 0.7;
125
+ pointer-events: none;
126
+ }
127
+
128
+ .run-history__head {
129
+ background: var(--smrt-color-surface-container, #f3f4f6);
130
+ }
131
+
132
+ .run-history__head th {
133
+ padding: var(--smrt-spacing-sm, 0.5rem) var(--smrt-spacing-md, 1rem);
134
+ font-weight: var(--smrt-typography-weight-semibold, 600);
135
+ text-align: left;
136
+ white-space: nowrap;
137
+ border-bottom: 1px solid var(--smrt-color-outline-variant, #c4c6cf);
138
+ }
139
+
140
+ .run-history__body tr {
141
+ border-bottom: 1px solid var(--smrt-color-outline-variant, #c4c6cf);
142
+ transition: background-color var(--smrt-duration-short2, 150ms) var(--smrt-easing-standard, ease);
143
+ }
144
+
145
+ .run-history__body tr:hover:not(.run-history__row--loading):not(.run-history__row--empty) {
146
+ background: var(--smrt-color-surface-container-low, #f9fafb);
147
+ cursor: pointer;
148
+ }
149
+
150
+ @media (prefers-reduced-motion: reduce) {
151
+ .run-history__body tr {
152
+ transition: none;
153
+ }
154
+
155
+ .run-history__spinner {
156
+ animation: none;
157
+ }
158
+ }
159
+
160
+ .run-history__cell {
161
+ padding: var(--smrt-spacing-sm, 0.5rem) var(--smrt-spacing-md, 1rem);
162
+ vertical-align: middle;
163
+ }
164
+
165
+ .run-history__cell--agent {
166
+ font-weight: var(--smrt-typography-weight-medium, 500);
167
+ }
168
+
169
+ .run-history__cell--date {
170
+ color: var(--smrt-color-on-surface-variant, #43474e);
171
+ white-space: nowrap;
172
+ }
173
+
174
+ .run-history__cell--duration {
175
+ font-family: var(--smrt-font-family-mono, ui-monospace, monospace);
176
+ text-align: center;
177
+ }
178
+
179
+ .run-history__cell--error {
180
+ max-width: 300px;
181
+ }
182
+
183
+ .error-text {
184
+ color: var(--smrt-color-error, #ba1a1a);
185
+ font: var(--smrt-typography-body-small-font, 0.75rem / 1.25 sans-serif);
186
+ cursor: help;
187
+ }
188
+
189
+ .no-error {
190
+ color: var(--smrt-color-on-surface-variant, #43474e);
191
+ }
192
+
193
+ .run-history__cell--loading,
194
+ .run-history__cell--empty {
195
+ padding: var(--smrt-spacing-xl, 2rem);
196
+ text-align: center;
197
+ }
198
+
199
+ .run-history__loading {
200
+ display: flex;
201
+ align-items: center;
202
+ justify-content: center;
203
+ gap: var(--smrt-spacing-sm, 0.5rem);
204
+ color: var(--smrt-color-on-surface-variant, #43474e);
205
+ }
206
+
207
+ .run-history__spinner {
208
+ width: 20px;
209
+ height: 20px;
210
+ border: 2px solid var(--smrt-color-outline-variant, #c4c6cf);
211
+ border-top-color: var(--smrt-color-primary, #005ac1);
212
+ border-radius: var(--smrt-radius-full, 9999px);
213
+ animation: spin 0.8s linear infinite;
214
+ }
215
+
216
+ @keyframes spin {
217
+ to {
218
+ transform: rotate(360deg);
219
+ }
220
+ }
221
+
222
+ .run-history__empty {
223
+ color: var(--smrt-color-on-surface-variant, #43474e);
224
+ }
225
+ </style>
@@ -0,0 +1,16 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { AgentRunHistoryEntry } from '../types.js';
3
+ export interface Props {
4
+ /** Run history entries */
5
+ history: AgentRunHistoryEntry[];
6
+ /** Loading state */
7
+ loading?: boolean;
8
+ /** Callback when entry is clicked */
9
+ onEntryClick?: (entry: AgentRunHistoryEntry) => void;
10
+ /** Empty state snippet */
11
+ empty?: Snippet;
12
+ }
13
+ declare const AgentRunHistory: import("svelte").Component<Props, {}, "">;
14
+ type AgentRunHistory = ReturnType<typeof AgentRunHistory>;
15
+ export default AgentRunHistory;
16
+ //# sourceMappingURL=AgentRunHistory.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentRunHistory.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/AgentRunHistory.svelte.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAQxD,MAAM,WAAW,KAAK;IACpB,0BAA0B;IAC1B,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAChC,oBAAoB;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qCAAqC;IACrC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACrD,0BAA0B;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA4FD,QAAA,MAAM,eAAe,2CAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}