@genesislcap/ai-assistant 14.409.0-FUI-2495.2 → 14.409.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/dist/ai-assistant.api.json +1110 -2791
- package/dist/ai-assistant.d.ts +45 -267
- package/dist/dts/channel/ai-activity-channel.d.ts +0 -1
- package/dist/dts/channel/ai-activity-channel.d.ts.map +1 -1
- package/dist/dts/components/chat-driver/chat-driver.d.ts +7 -25
- package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
- package/dist/dts/components/halo-overlay.d.ts +1 -13
- package/dist/dts/components/halo-overlay.d.ts.map +1 -1
- package/dist/dts/config/config.d.ts +15 -43
- package/dist/dts/config/config.d.ts.map +1 -1
- package/dist/dts/config/index.d.ts +0 -1
- package/dist/dts/config/index.d.ts.map +1 -1
- package/dist/dts/index.d.ts +0 -4
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/main/main.d.ts +7 -16
- package/dist/dts/main/main.d.ts.map +1 -1
- package/dist/dts/main/main.styles.d.ts.map +1 -1
- package/dist/dts/main/main.template.d.ts.map +1 -1
- package/dist/esm/components/chat-driver/chat-driver.js +31 -86
- package/dist/esm/components/halo-overlay.js +7 -53
- package/dist/esm/config/index.js +0 -1
- package/dist/esm/index.js +0 -4
- package/dist/esm/main/main.js +45 -103
- package/dist/esm/main/main.styles.js +4 -145
- package/dist/esm/main/main.template.js +61 -97
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +15 -15
- package/src/channel/ai-activity-channel.ts +0 -1
- package/src/components/chat-driver/chat-driver.ts +35 -116
- package/src/components/halo-overlay.ts +7 -45
- package/src/config/config.ts +15 -45
- package/src/config/index.ts +0 -1
- package/src/index.ts +0 -4
- package/src/main/main.styles.ts +4 -145
- package/src/main/main.template.ts +78 -116
- package/src/main/main.ts +50 -105
- package/dist/dts/components/ai-driver/ai-driver.d.ts +0 -38
- package/dist/dts/components/ai-driver/ai-driver.d.ts.map +0 -1
- package/dist/dts/components/ai-driver/index.d.ts +0 -2
- package/dist/dts/components/ai-driver/index.d.ts.map +0 -1
- package/dist/dts/components/orchestrating-driver/index.d.ts +0 -2
- package/dist/dts/components/orchestrating-driver/index.d.ts.map +0 -1
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts +0 -36
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +0 -1
- package/dist/dts/components/popout-manager/index.d.ts +0 -2
- package/dist/dts/components/popout-manager/index.d.ts.map +0 -1
- package/dist/dts/components/popout-manager/popout-manager.d.ts +0 -74
- package/dist/dts/components/popout-manager/popout-manager.d.ts.map +0 -1
- package/dist/dts/config/fallback-agents.d.ts +0 -20
- package/dist/dts/config/fallback-agents.d.ts.map +0 -1
- package/dist/esm/components/ai-driver/ai-driver.js +0 -1
- package/dist/esm/components/ai-driver/index.js +0 -1
- package/dist/esm/components/orchestrating-driver/index.js +0 -1
- package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +0 -229
- package/dist/esm/components/popout-manager/index.js +0 -1
- package/dist/esm/components/popout-manager/popout-manager.js +0 -119
- package/dist/esm/config/fallback-agents.js +0 -26
- package/src/components/ai-driver/ai-driver.ts +0 -42
- package/src/components/ai-driver/index.ts +0 -1
- package/src/components/orchestrating-driver/index.ts +0 -1
- package/src/components/orchestrating-driver/orchestrating-driver.ts +0 -300
- package/src/components/popout-manager/index.ts +0 -1
- package/src/components/popout-manager/popout-manager.ts +0 -144
- package/src/config/fallback-agents.ts +0 -29
|
@@ -6,11 +6,6 @@ import {
|
|
|
6
6
|
AI_COLOUR_VIOLET,
|
|
7
7
|
} from '../styles/ai-colours';
|
|
8
8
|
|
|
9
|
-
const HALO_DEFAULT_SPEED = 1.5;
|
|
10
|
-
const HALO_DEFAULT_BORDER_SIZE = 3;
|
|
11
|
-
const HALO_DEFAULT_GLOW_OPACITY = 0.35;
|
|
12
|
-
const HALO_DEFAULT_GLOW_SPREAD = 70;
|
|
13
|
-
|
|
14
9
|
/**
|
|
15
10
|
* Animated halo overlay — rotating conic-gradient border with an inward glow.
|
|
16
11
|
*
|
|
@@ -51,7 +46,7 @@ const HALO_DEFAULT_GLOW_SPREAD = 70;
|
|
|
51
46
|
position: absolute;
|
|
52
47
|
inset: 0;
|
|
53
48
|
border-radius: inherit;
|
|
54
|
-
padding:
|
|
49
|
+
padding: 3px;
|
|
55
50
|
background: repeating-conic-gradient(
|
|
56
51
|
from var(--halo-angle, 0deg),
|
|
57
52
|
${AI_COLOUR_AMBER},
|
|
@@ -84,47 +79,14 @@ const HALO_DEFAULT_GLOW_SPREAD = 70;
|
|
|
84
79
|
${AI_COLOUR_VIOLET},
|
|
85
80
|
${AI_COLOUR_AMBER}
|
|
86
81
|
);
|
|
87
|
-
opacity:
|
|
88
|
-
-webkit-mask-image: radial-gradient(
|
|
89
|
-
|
|
90
|
-
transparent var(--halo-glow-spread, 70%),
|
|
91
|
-
black 100%
|
|
92
|
-
);
|
|
93
|
-
mask-image: radial-gradient(
|
|
94
|
-
ellipse at center,
|
|
95
|
-
transparent var(--halo-glow-spread, 70%),
|
|
96
|
-
black 100%
|
|
97
|
-
);
|
|
82
|
+
opacity: 0.35;
|
|
83
|
+
-webkit-mask-image: radial-gradient(ellipse at center, transparent 70%, black 100%);
|
|
84
|
+
mask-image: radial-gradient(ellipse at center, transparent 70%, black 100%);
|
|
98
85
|
}
|
|
99
86
|
`,
|
|
100
87
|
})
|
|
101
88
|
export class AiHaloOverlay extends GenesisElement {
|
|
102
89
|
@attr({ mode: 'boolean' }) active: boolean = false;
|
|
103
|
-
/** Rotation speed in degrees per frame. Default: 1.5 (≈ 4 s per full revolution at 60 fps). */
|
|
104
|
-
@attr({ converter: { fromView: Number, toView: String } }) speed: number = HALO_DEFAULT_SPEED;
|
|
105
|
-
/** Rotation direction. Default: 'cw' (clockwise). */
|
|
106
|
-
@attr direction: 'cw' | 'ccw' = 'cw';
|
|
107
|
-
/** Border thickness in px. Default: 3. */
|
|
108
|
-
@attr({ attribute: 'border-size', converter: { fromView: Number, toView: String } })
|
|
109
|
-
borderSize: number = HALO_DEFAULT_BORDER_SIZE;
|
|
110
|
-
/** Glow layer opacity (0–1). Default: 0.35. */
|
|
111
|
-
@attr({ attribute: 'glow-opacity', converter: { fromView: Number, toView: String } })
|
|
112
|
-
glowOpacity: number = HALO_DEFAULT_GLOW_OPACITY;
|
|
113
|
-
/** Transparent stop of the radial glow mask as a percentage (0–100). Higher = less spread. Default: 70. */
|
|
114
|
-
@attr({ attribute: 'glow-spread', converter: { fromView: Number, toView: String } })
|
|
115
|
-
glowSpread: number = HALO_DEFAULT_GLOW_SPREAD;
|
|
116
|
-
|
|
117
|
-
borderSizeChanged() {
|
|
118
|
-
this.style.setProperty('--halo-border-size', `${this.borderSize}px`);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
glowOpacityChanged() {
|
|
122
|
-
this.style.setProperty('--halo-glow-opacity', String(this.glowOpacity));
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
glowSpreadChanged() {
|
|
126
|
-
this.style.setProperty('--halo-glow-spread', `${this.glowSpread}%`);
|
|
127
|
-
}
|
|
128
90
|
|
|
129
91
|
// TODO: The rAF loop is fine for demos but has two drawbacks vs a pure CSS @property animation:
|
|
130
92
|
// 1. It runs on the main thread, so heavy JS work can cause the animation to stutter.
|
|
@@ -132,6 +94,8 @@ export class AiHaloOverlay extends GenesisElement {
|
|
|
132
94
|
// Once @property inside Shadow DOM has solid cross-browser support, consider switching back
|
|
133
95
|
// to a CSS @keyframes approach and removing connectedCallback/disconnectedCallback/tick().
|
|
134
96
|
|
|
97
|
+
// 1.5° per frame @ 60 fps ≈ 4 s per full revolution
|
|
98
|
+
private static readonly DEG_PER_FRAME = 1.5;
|
|
135
99
|
private static readonly FULL_ROTATION_DEG = 360;
|
|
136
100
|
|
|
137
101
|
private angle = 0;
|
|
@@ -150,9 +114,7 @@ export class AiHaloOverlay extends GenesisElement {
|
|
|
150
114
|
}
|
|
151
115
|
|
|
152
116
|
private tick() {
|
|
153
|
-
|
|
154
|
-
this.angle =
|
|
155
|
-
(this.angle + step + AiHaloOverlay.FULL_ROTATION_DEG) % AiHaloOverlay.FULL_ROTATION_DEG;
|
|
117
|
+
this.angle = (this.angle + AiHaloOverlay.DEG_PER_FRAME) % AiHaloOverlay.FULL_ROTATION_DEG;
|
|
156
118
|
this.style.setProperty('--halo-angle', `${this.angle}deg`);
|
|
157
119
|
this.animFrame = requestAnimationFrame(() => this.tick());
|
|
158
120
|
}
|
package/src/config/config.ts
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
import type { ChatMessage, ChatToolDefinition, ChatToolHandlers } from '@genesislcap/foundation-ai';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for a single specialist agent.
|
|
5
|
+
*
|
|
6
|
+
* When multiple agents are provided to `FoundationAiAssistant`, an orchestrating layer
|
|
7
|
+
* will route each user message to the appropriate specialist based on intent. When only
|
|
8
|
+
* one agent is configured, routing is skipped.
|
|
9
|
+
*
|
|
10
|
+
* @beta
|
|
11
|
+
*/
|
|
12
|
+
export interface AgentConfig {
|
|
4
13
|
/**
|
|
5
14
|
* Display name shown in the chat header when this agent is active.
|
|
6
15
|
*/
|
|
7
16
|
name: string;
|
|
17
|
+
/**
|
|
18
|
+
* Plain-language description of what this agent handles.
|
|
19
|
+
* Used by the classifier to auto-generate its routing prompt.
|
|
20
|
+
*/
|
|
21
|
+
description: string;
|
|
8
22
|
/**
|
|
9
23
|
* System prompt injected into every conversation turn for this agent.
|
|
10
24
|
*/
|
|
@@ -23,47 +37,3 @@ interface BaseAgentConfig {
|
|
|
23
37
|
*/
|
|
24
38
|
primerHistory?: ChatMessage[];
|
|
25
39
|
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Configuration for a specialist agent.
|
|
29
|
-
*
|
|
30
|
-
* Specialist agents are offered to the classifier for intent routing. The
|
|
31
|
-
* `description` is used to auto-generate the classifier prompt — no manual
|
|
32
|
-
* routing prompt authoring required.
|
|
33
|
-
*
|
|
34
|
-
* @beta
|
|
35
|
-
*/
|
|
36
|
-
export interface SpecialistAgentConfig extends BaseAgentConfig {
|
|
37
|
-
/**
|
|
38
|
-
* Plain-language description of what this agent handles.
|
|
39
|
-
* Used by the classifier to auto-generate its routing prompt.
|
|
40
|
-
*/
|
|
41
|
-
description: string;
|
|
42
|
-
fallback?: never;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Configuration for a fallback agent.
|
|
47
|
-
*
|
|
48
|
-
* Invoked when the classifier returns no match. Excluded from the classifier
|
|
49
|
-
* prompt. Only one fallback is permitted per agents array.
|
|
50
|
-
*
|
|
51
|
-
* @beta
|
|
52
|
-
*/
|
|
53
|
-
export interface FallbackAgentConfig extends BaseAgentConfig {
|
|
54
|
-
/**
|
|
55
|
-
* Marks this agent as the fallback for unrecognised requests.
|
|
56
|
-
*/
|
|
57
|
-
fallback: true;
|
|
58
|
-
description?: never;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Configuration for an agent passed to `FoundationAiAssistant`.
|
|
63
|
-
*
|
|
64
|
-
* Either a specialist (requires `description`) or a fallback (requires
|
|
65
|
-
* `fallback: true`). Passing both or neither is a compile error.
|
|
66
|
-
*
|
|
67
|
-
* @beta
|
|
68
|
-
*/
|
|
69
|
-
export type AgentConfig = SpecialistAgentConfig | FallbackAgentConfig;
|
package/src/config/index.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
export * from './main/main';
|
|
2
2
|
export * from './main/main.types';
|
|
3
3
|
export * from './main/main.template';
|
|
4
|
-
export * from './components/ai-driver';
|
|
5
4
|
export * from './components/chat-driver';
|
|
6
|
-
export * from './components/orchestrating-driver';
|
|
7
|
-
export * from './components/popout-manager';
|
|
8
5
|
export * from './channel/ai-activity-channel';
|
|
9
6
|
export * from './channel/ai-activity-bus';
|
|
10
7
|
export * from './config/config';
|
|
11
|
-
export * from './config/fallback-agents';
|
|
12
8
|
export type { AiChatWidget } from './types/ai-chat-widget';
|
package/src/main/main.styles.ts
CHANGED
|
@@ -17,7 +17,6 @@ export const styles = css`
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
.chat-wrapper {
|
|
20
|
-
container-type: inline-size;
|
|
21
20
|
position: relative;
|
|
22
21
|
display: flex;
|
|
23
22
|
flex-direction: column;
|
|
@@ -63,140 +62,22 @@ export const styles = css`
|
|
|
63
62
|
font-size: 1.2em;
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
@keyframes settings-slide-in {
|
|
67
|
-
from {
|
|
68
|
-
opacity: 0%;
|
|
69
|
-
transform: translateY(-6px);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
to {
|
|
73
|
-
opacity: 100%;
|
|
74
|
-
transform: translateY(0);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
@keyframes settings-slide-out {
|
|
79
|
-
from {
|
|
80
|
-
opacity: 100%;
|
|
81
|
-
transform: translateY(0);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
to {
|
|
85
|
-
opacity: 0%;
|
|
86
|
-
transform: translateY(-6px);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
65
|
.settings-panel {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
gap: calc(var(--design-unit) *
|
|
66
|
+
display: flex;
|
|
67
|
+
flex-wrap: wrap;
|
|
68
|
+
align-items: center;
|
|
69
|
+
gap: calc(var(--design-unit) * 4px);
|
|
95
70
|
padding: calc(var(--design-unit) * 2px) calc(var(--design-unit) * 3px);
|
|
96
71
|
border-bottom: 1px solid var(--neutral-stroke-rest);
|
|
97
72
|
background-color: var(--neutral-layer-2);
|
|
98
73
|
}
|
|
99
74
|
|
|
100
|
-
.settings-panel.closing {
|
|
101
|
-
animation: settings-slide-out 0.2s ease-in forwards;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
rapid-multiselect::part(root) {
|
|
105
|
-
min-width: 80px;
|
|
106
|
-
width: 300%;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
rapid-multiselect::part(control),
|
|
110
|
-
.settings-panel > [part='download-button'] {
|
|
111
|
-
width: fit-content;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
.settings-panel > [part='toggle-tool-calls'] {
|
|
115
|
-
grid-column: 1;
|
|
116
|
-
grid-row: 1;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
.settings-panel > [part='toggle-thinking'] {
|
|
120
|
-
grid-column: 2;
|
|
121
|
-
grid-row: 1;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
.settings-panel > [part='toggle-agent-switch'] {
|
|
125
|
-
grid-column: 1;
|
|
126
|
-
grid-row: 2;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
.settings-panel > [part='download-button'] {
|
|
130
|
-
grid-column: 2;
|
|
131
|
-
grid-row: 2;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
75
|
.settings-animations {
|
|
135
76
|
display: flex;
|
|
136
77
|
align-items: center;
|
|
137
78
|
gap: calc(var(--design-unit) * 2px);
|
|
138
79
|
}
|
|
139
80
|
|
|
140
|
-
.settings-panel > .settings-animations {
|
|
141
|
-
grid-column: 1/2;
|
|
142
|
-
grid-row: 3;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
@container (min-width: 400px) {
|
|
146
|
-
.settings-panel {
|
|
147
|
-
grid-template-columns: auto 1fr;
|
|
148
|
-
align-items: start;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
.settings-panel > [part='toggle-tool-calls'] {
|
|
152
|
-
grid-column: 1;
|
|
153
|
-
grid-row: 1;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
.settings-panel > [part='toggle-thinking'] {
|
|
157
|
-
grid-column: 1;
|
|
158
|
-
grid-row: 2;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
.settings-panel > [part='toggle-agent-switch'] {
|
|
162
|
-
grid-column: 1;
|
|
163
|
-
grid-row: 3;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
.settings-panel > [part='download-button'],
|
|
167
|
-
.settings-panel > .settings-animations {
|
|
168
|
-
grid-column: 2;
|
|
169
|
-
justify-self: end;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
.settings-panel > [part='download-button'] {
|
|
173
|
-
grid-row: 1;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
.settings-panel > .settings-animations {
|
|
177
|
-
grid-row: 2;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
@container (min-width: 750px) {
|
|
182
|
-
.settings-panel {
|
|
183
|
-
display: flex;
|
|
184
|
-
flex-wrap: nowrap;
|
|
185
|
-
align-items: center;
|
|
186
|
-
gap: calc(var(--design-unit) * 4px);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
.settings-panel > [part='download-button'],
|
|
190
|
-
.settings-panel > .settings-animations {
|
|
191
|
-
justify-self: unset;
|
|
192
|
-
margin-left: auto;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
.settings-panel > [part='download-button'] ~ .settings-animations {
|
|
196
|
-
margin-left: 0;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
81
|
.messages {
|
|
201
82
|
flex: 1;
|
|
202
83
|
overflow-y: auto;
|
|
@@ -242,28 +123,6 @@ export const styles = css`
|
|
|
242
123
|
}
|
|
243
124
|
}
|
|
244
125
|
|
|
245
|
-
.agent-switch-indicator {
|
|
246
|
-
display: flex;
|
|
247
|
-
align-items: center;
|
|
248
|
-
gap: 8px;
|
|
249
|
-
margin: 8px 0;
|
|
250
|
-
color: var(--neutral-foreground-hint, var(--neutral-foreground-rest));
|
|
251
|
-
opacity: 60%;
|
|
252
|
-
font-size: 0.75em;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
.agent-switch-indicator::before,
|
|
256
|
-
.agent-switch-indicator::after {
|
|
257
|
-
content: '';
|
|
258
|
-
flex: 1;
|
|
259
|
-
height: 1px;
|
|
260
|
-
background: currentColor;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
.agent-switch-label {
|
|
264
|
-
white-space: nowrap;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
126
|
.message-row {
|
|
268
127
|
display: flex;
|
|
269
128
|
align-items: flex-start;
|
|
@@ -7,10 +7,6 @@ const animationItemRenderer = (option: any): ViewTemplate => html`
|
|
|
7
7
|
<span part="option-label" title="${() => option.tooltip}">${() => option.label}</span>
|
|
8
8
|
`;
|
|
9
9
|
|
|
10
|
-
const HALO_SPEED_DEFAULT = 1.5;
|
|
11
|
-
const HALO_SPEED_ORCHESTRATING = 0.4;
|
|
12
|
-
const HALO_BORDER_SIZE_DEFAULT = 3;
|
|
13
|
-
|
|
14
10
|
const animationOptions = Object.entries(ANIMATION_DEFS).map(([value, def]) => ({
|
|
15
11
|
value,
|
|
16
12
|
label: def.label,
|
|
@@ -38,8 +34,6 @@ const genesisIconTemplate = html`
|
|
|
38
34
|
*/
|
|
39
35
|
const messageType = (m: ChatMessage): string => {
|
|
40
36
|
switch (true) {
|
|
41
|
-
case m.role === 'system-event':
|
|
42
|
-
return 'agent-switch';
|
|
43
37
|
case m.role === 'user':
|
|
44
38
|
return 'user';
|
|
45
39
|
case !!m.thinking:
|
|
@@ -74,13 +68,13 @@ export const FoundationAiAssistantTemplate = (
|
|
|
74
68
|
return html<FoundationAiAssistant>`
|
|
75
69
|
<div class="chat-wrapper" part="chat-wrapper">
|
|
76
70
|
${when(
|
|
77
|
-
(x) => !!x.chatConfig.
|
|
71
|
+
(x) => !!x.chatConfig.acceptedFiles,
|
|
78
72
|
html<FoundationAiAssistant>`
|
|
79
73
|
<input
|
|
80
74
|
class="file-input"
|
|
81
75
|
type="file"
|
|
82
76
|
multiple
|
|
83
|
-
accept=${(x) => x.chatConfig.
|
|
77
|
+
accept=${(x) => x.chatConfig.acceptedFiles}
|
|
84
78
|
@change=${(x, c) => x.handleFileSelect(c.event)}
|
|
85
79
|
/>
|
|
86
80
|
`,
|
|
@@ -88,21 +82,23 @@ export const FoundationAiAssistantTemplate = (
|
|
|
88
82
|
${when(
|
|
89
83
|
(x) =>
|
|
90
84
|
!!x.popoutMode ||
|
|
91
|
-
x.chatConfig.
|
|
92
|
-
x.chatConfig.
|
|
93
|
-
x.chatConfig.
|
|
94
|
-
x.chatConfig.
|
|
95
|
-
x.chatConfig.ui?.animations != null,
|
|
85
|
+
x.chatConfig.showToolCalls != null ||
|
|
86
|
+
x.chatConfig.showThinkingSteps != null ||
|
|
87
|
+
x.chatConfig.allowDebugDownload === true ||
|
|
88
|
+
x.chatConfig.animations != null,
|
|
96
89
|
html<FoundationAiAssistant>`
|
|
97
90
|
<div
|
|
98
|
-
class="chat-header ${(x) => (x.popoutMode
|
|
91
|
+
class="chat-header ${(x) => (x.popoutMode === 'expand' ? 'draggable' : '')}"
|
|
99
92
|
part="chat-header"
|
|
100
93
|
@mousedown="${(x, c) => x.onChatHeaderMouseDown(c.event as MouseEvent)}"
|
|
101
94
|
>
|
|
102
95
|
${when(
|
|
103
|
-
(x) => !!x.headerTitle,
|
|
96
|
+
(x) => !!(x.headerTitle ?? x.agents?.[0]?.name),
|
|
104
97
|
html<FoundationAiAssistant>`
|
|
105
|
-
|
|
98
|
+
<!-- TODO: multi-agent orchestration — bind to active agent name rather than always agents[0] -->
|
|
99
|
+
<span class="chat-title" part="chat-title">
|
|
100
|
+
${(x) => x.headerTitle ?? x.agents?.[0]?.name}
|
|
101
|
+
</span>
|
|
106
102
|
`,
|
|
107
103
|
)}
|
|
108
104
|
<div class="header-actions" part="header-actions">
|
|
@@ -122,11 +118,10 @@ export const FoundationAiAssistantTemplate = (
|
|
|
122
118
|
)}
|
|
123
119
|
${when(
|
|
124
120
|
(x) =>
|
|
125
|
-
x.chatConfig.
|
|
126
|
-
x.chatConfig.
|
|
127
|
-
x.chatConfig.
|
|
128
|
-
x.chatConfig.
|
|
129
|
-
x.chatConfig.ui?.animations != null,
|
|
121
|
+
x.chatConfig.showToolCalls != null ||
|
|
122
|
+
x.chatConfig.showThinkingSteps != null ||
|
|
123
|
+
x.chatConfig.allowDebugDownload === true ||
|
|
124
|
+
x.chatConfig.animations != null,
|
|
130
125
|
html<FoundationAiAssistant>`
|
|
131
126
|
<${buttonTag}
|
|
132
127
|
class="settings-button"
|
|
@@ -144,7 +139,7 @@ export const FoundationAiAssistantTemplate = (
|
|
|
144
139
|
html<FoundationAiAssistant>`
|
|
145
140
|
<div class="settings-panel" part="settings-panel">
|
|
146
141
|
${when(
|
|
147
|
-
(x) => x.chatConfig.
|
|
142
|
+
(x) => x.chatConfig.showToolCalls != null,
|
|
148
143
|
html<FoundationAiAssistant>`
|
|
149
144
|
<${switchTag}
|
|
150
145
|
part="toggle-tool-calls"
|
|
@@ -154,7 +149,7 @@ export const FoundationAiAssistantTemplate = (
|
|
|
154
149
|
`,
|
|
155
150
|
)}
|
|
156
151
|
${when(
|
|
157
|
-
(x) => x.chatConfig.
|
|
152
|
+
(x) => x.chatConfig.showThinkingSteps != null,
|
|
158
153
|
html<FoundationAiAssistant>`
|
|
159
154
|
<${switchTag}
|
|
160
155
|
part="toggle-thinking"
|
|
@@ -164,27 +159,17 @@ export const FoundationAiAssistantTemplate = (
|
|
|
164
159
|
`,
|
|
165
160
|
)}
|
|
166
161
|
${when(
|
|
167
|
-
(x) => x.chatConfig.
|
|
168
|
-
html<FoundationAiAssistant>`
|
|
169
|
-
<${switchTag}
|
|
170
|
-
part="toggle-agent-switch"
|
|
171
|
-
:checked=${(x) => x.showAgentSwitchIndicator}
|
|
172
|
-
@change=${(x) => x.toggleShowAgentSwitchIndicator()}
|
|
173
|
-
>Agents</${switchTag}>
|
|
174
|
-
`,
|
|
175
|
-
)}
|
|
176
|
-
${when(
|
|
177
|
-
(x) => x.chatConfig.ui?.allowDebugDownload === true,
|
|
162
|
+
(x) => x.chatConfig.allowDebugDownload === true,
|
|
178
163
|
html<FoundationAiAssistant>`
|
|
179
164
|
<${buttonTag}
|
|
180
165
|
part="download-button"
|
|
181
166
|
appearance="stealth"
|
|
182
|
-
@click=${(x) => x.
|
|
183
|
-
>Download
|
|
167
|
+
@click=${(x) => x.downloadHistory()}
|
|
168
|
+
>Download debug state</${buttonTag}>
|
|
184
169
|
`,
|
|
185
170
|
)}
|
|
186
171
|
${when(
|
|
187
|
-
(x) => x.chatConfig.
|
|
172
|
+
(x) => x.chatConfig.animations?.userConfigurable === true,
|
|
188
173
|
html<FoundationAiAssistant>`
|
|
189
174
|
<div class="settings-animations">
|
|
190
175
|
<span class="settings-label">Animations</span>
|
|
@@ -212,91 +197,71 @@ export const FoundationAiAssistantTemplate = (
|
|
|
212
197
|
${repeat(
|
|
213
198
|
(x) => x.visibleMessages,
|
|
214
199
|
html<ChatMessage, FoundationAiAssistant>`
|
|
215
|
-
${
|
|
216
|
-
(
|
|
217
|
-
|
|
218
|
-
<
|
|
219
|
-
<
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
200
|
+
<div class="message-row ${(m) => messageType(m)}">
|
|
201
|
+
${when(
|
|
202
|
+
(m) => m.role !== 'user',
|
|
203
|
+
html<ChatMessage, FoundationAiAssistant>`
|
|
204
|
+
<div class="avatar ${(m) => messageType(m)}">
|
|
205
|
+
${when(
|
|
206
|
+
(m, c) => !!(c.parent as FoundationAiAssistant).imageSrc,
|
|
207
|
+
html<ChatMessage, FoundationAiAssistant>`
|
|
208
|
+
<img
|
|
209
|
+
src="${(m, c) => (c.parent as FoundationAiAssistant).imageSrc}"
|
|
210
|
+
alt="Assistant"
|
|
211
|
+
class="avatar-img"
|
|
212
|
+
/>
|
|
213
|
+
`,
|
|
214
|
+
)}
|
|
215
|
+
${when(
|
|
216
|
+
(m, c) => !(c.parent as FoundationAiAssistant).imageSrc,
|
|
217
|
+
genesisIconTemplate,
|
|
218
|
+
)}
|
|
219
|
+
</div>
|
|
220
|
+
`,
|
|
221
|
+
)}
|
|
222
|
+
<div class="message ${(m) => messageType(m)}">
|
|
223
|
+
<div class="sender">${(m) => senderLabel[messageType(m)]}</div>
|
|
224
|
+
<div class="content">
|
|
227
225
|
${when(
|
|
228
|
-
(m) => m.
|
|
226
|
+
(m) => m.content,
|
|
229
227
|
html<ChatMessage, FoundationAiAssistant>`
|
|
230
|
-
<
|
|
231
|
-
${when(
|
|
232
|
-
(m, c) => !!(c.parent as FoundationAiAssistant).imageSrc,
|
|
233
|
-
html<ChatMessage, FoundationAiAssistant>`
|
|
234
|
-
<img
|
|
235
|
-
src="${(m, c) => (c.parent as FoundationAiAssistant).imageSrc}"
|
|
236
|
-
alt="Assistant"
|
|
237
|
-
class="avatar-img"
|
|
238
|
-
/>
|
|
239
|
-
`,
|
|
240
|
-
)}
|
|
241
|
-
${when(
|
|
242
|
-
(m, c) => !(c.parent as FoundationAiAssistant).imageSrc,
|
|
243
|
-
genesisIconTemplate,
|
|
244
|
-
)}
|
|
245
|
-
</div>
|
|
228
|
+
<ai-chat-markdown :content="${(m) => m.content}"></ai-chat-markdown>
|
|
246
229
|
`,
|
|
247
230
|
)}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
m.
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
</div>
|
|
257
|
-
<div class="content">
|
|
258
|
-
${when(
|
|
259
|
-
(m) => m.content,
|
|
260
|
-
html<ChatMessage, FoundationAiAssistant>`
|
|
261
|
-
<ai-chat-markdown :content="${(m) => m.content}"></ai-chat-markdown>
|
|
262
|
-
`,
|
|
263
|
-
)}
|
|
264
|
-
${when(
|
|
265
|
-
(m) => m.toolCalls,
|
|
266
|
-
html<ChatMessage, FoundationAiAssistant>`
|
|
267
|
-
${repeat(
|
|
268
|
-
(m) => m.toolCalls ?? [],
|
|
269
|
-
html<ChatToolCall>`
|
|
270
|
-
<pre class="payload"><strong>${(tc) => tc.name}</strong>(${(tc) =>
|
|
271
|
-
JSON.stringify(tc.args, null, 2)})</pre>
|
|
272
|
-
`,
|
|
273
|
-
)}
|
|
274
|
-
`,
|
|
275
|
-
)}
|
|
276
|
-
${when(
|
|
277
|
-
(m) => m.interaction,
|
|
278
|
-
html<ChatMessage, FoundationAiAssistant>`
|
|
279
|
-
<ai-chat-interaction-wrapper
|
|
280
|
-
:componentName=${(m) => m.interaction!.componentName}
|
|
281
|
-
:data=${(m) => m.interaction!.data}
|
|
282
|
-
:interactionId=${(m) => m.interaction!.interactionId}
|
|
283
|
-
:resolved=${(m) => !!m.interaction!.resolved}
|
|
284
|
-
@interaction-completed=${(m, c) =>
|
|
285
|
-
c.parent.handleInteractionCompleted(c.event)}
|
|
286
|
-
></ai-chat-interaction-wrapper>
|
|
231
|
+
${when(
|
|
232
|
+
(m) => m.toolCalls,
|
|
233
|
+
html<ChatMessage, FoundationAiAssistant>`
|
|
234
|
+
${repeat(
|
|
235
|
+
(m) => m.toolCalls ?? [],
|
|
236
|
+
html<ChatToolCall>`
|
|
237
|
+
<pre class="payload"><strong>${(tc) => tc.name}</strong>(${(tc) =>
|
|
238
|
+
JSON.stringify(tc.args, null, 2)})</pre>
|
|
287
239
|
`,
|
|
288
240
|
)}
|
|
289
|
-
|
|
290
|
-
|
|
241
|
+
`,
|
|
242
|
+
)}
|
|
243
|
+
${when(
|
|
244
|
+
(m) => m.interaction,
|
|
245
|
+
html<ChatMessage, FoundationAiAssistant>`
|
|
246
|
+
<ai-chat-interaction-wrapper
|
|
247
|
+
:componentName=${(m) => m.interaction!.componentName}
|
|
248
|
+
:data=${(m) => m.interaction!.data}
|
|
249
|
+
:interactionId=${(m) => m.interaction!.interactionId}
|
|
250
|
+
:resolved=${(m) => !!m.interaction!.resolved}
|
|
251
|
+
@interaction-completed=${(m, c) =>
|
|
252
|
+
c.parent.handleInteractionCompleted(c.event)}
|
|
253
|
+
></ai-chat-interaction-wrapper>
|
|
254
|
+
`,
|
|
255
|
+
)}
|
|
291
256
|
</div>
|
|
292
|
-
|
|
293
|
-
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
294
259
|
`,
|
|
295
260
|
)}
|
|
296
261
|
${when(
|
|
297
262
|
(x) =>
|
|
298
263
|
x.showLoadingIndicator &&
|
|
299
|
-
(x.chatConfig.
|
|
264
|
+
(x.chatConfig.animations == null || x.enabledAnimations.includes('loading')),
|
|
300
265
|
html<FoundationAiAssistant>`
|
|
301
266
|
<div class="message-row ai" part="thinking">
|
|
302
267
|
<div class="avatar">
|
|
@@ -359,13 +324,13 @@ export const FoundationAiAssistantTemplate = (
|
|
|
359
324
|
|
|
360
325
|
<div class="input-row" part="input-row">
|
|
361
326
|
${when(
|
|
362
|
-
(x) => !!x.chatConfig.
|
|
327
|
+
(x) => !!x.chatConfig.acceptedFiles,
|
|
363
328
|
html<FoundationAiAssistant>`
|
|
364
329
|
<${buttonTag}
|
|
365
330
|
class="attach-button"
|
|
366
331
|
part="attach-button"
|
|
367
332
|
appearance="stealth"
|
|
368
|
-
title=${(x) => `Attach file (${x.chatConfig.
|
|
333
|
+
title=${(x) => `Attach file (${x.chatConfig.acceptedFiles})`}
|
|
369
334
|
?disabled=${(x) => x.state === 'loading'}
|
|
370
335
|
@click=${(x) => x.triggerFileInput()}
|
|
371
336
|
><${iconTag} name="paperclip"></${iconTag}></${buttonTag}>
|
|
@@ -399,10 +364,7 @@ export const FoundationAiAssistantTemplate = (
|
|
|
399
364
|
</div>
|
|
400
365
|
<ai-halo-overlay
|
|
401
366
|
part="halo-overlay"
|
|
402
|
-
?active=${(x) => x.showHalo
|
|
403
|
-
:speed="${(x) => (x.showHalo === 'orchestrating' ? HALO_SPEED_ORCHESTRATING : HALO_SPEED_DEFAULT)}"
|
|
404
|
-
direction="${(x) => (x.showHalo === 'orchestrating' ? 'ccw' : 'cw')}"
|
|
405
|
-
:borderSize="${(x) => (x.showHalo === 'orchestrating' ? 2 : HALO_BORDER_SIZE_DEFAULT)}"
|
|
367
|
+
?active=${(x) => x.showHalo && x.enabledAnimations.includes('halo')}
|
|
406
368
|
></ai-halo-overlay>
|
|
407
369
|
</div>
|
|
408
370
|
`;
|