@genesislcap/ai-assistant 15.61.0 → 15.63.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-assistant.api.json +18231 -11171
- package/dist/ai-assistant.d.ts +1235 -9
- package/dist/chat-driver.cjs +658 -50
- package/dist/chat-driver.cjs.map +4 -4
- package/dist/chat-driver.mjs +657 -50
- package/dist/chat-driver.mjs.map +4 -4
- package/dist/custom-elements.json +4759 -717
- package/dist/dts/autopilot/autopilot-driver.d.ts +278 -0
- package/dist/dts/autopilot/autopilot-driver.d.ts.map +1 -0
- package/dist/dts/autopilot/autopilot-session.d.ts +163 -0
- package/dist/dts/autopilot/autopilot-session.d.ts.map +1 -0
- package/dist/dts/autopilot/autopilot-tools.d.ts +15 -0
- package/dist/dts/autopilot/autopilot-tools.d.ts.map +1 -0
- package/dist/dts/autopilot/decision-message.d.ts +62 -0
- package/dist/dts/autopilot/decision-message.d.ts.map +1 -0
- package/dist/dts/autopilot/hand-back/hand-back.controller.d.ts +69 -0
- package/dist/dts/autopilot/hand-back/hand-back.controller.d.ts.map +1 -0
- package/dist/dts/autopilot/hand-back/hand-back.d.ts +22 -0
- package/dist/dts/autopilot/hand-back/hand-back.d.ts.map +1 -0
- package/dist/dts/autopilot/index.d.ts +4 -0
- package/dist/dts/autopilot/index.d.ts.map +1 -0
- package/dist/dts/channel/ai-activity-bus.d.ts.map +1 -1
- package/dist/dts/channel/ai-activity-channel.d.ts +17 -0
- package/dist/dts/channel/ai-activity-channel.d.ts.map +1 -1
- package/dist/dts/channel/autopilot-needs-user.d.ts +8 -0
- package/dist/dts/channel/autopilot-needs-user.d.ts.map +1 -0
- package/dist/dts/components/agent-picker/agent-picker.constants.d.ts +10 -0
- package/dist/dts/components/agent-picker/agent-picker.constants.d.ts.map +1 -1
- package/dist/dts/components/agent-picker/agent-picker.d.ts +4 -0
- package/dist/dts/components/agent-picker/agent-picker.d.ts.map +1 -1
- package/dist/dts/components/agent-picker/agent-picker.template.d.ts.map +1 -1
- package/dist/dts/components/ai-driver/ai-driver.d.ts +34 -1
- package/dist/dts/components/ai-driver/ai-driver.d.ts.map +1 -1
- package/dist/dts/components/ai-driver/base-driver-decorator.d.ts +3 -1
- package/dist/dts/components/ai-driver/base-driver-decorator.d.ts.map +1 -1
- package/dist/dts/components/chat-bubble/chat-bubble.d.ts +21 -0
- package/dist/dts/components/chat-bubble/chat-bubble.d.ts.map +1 -1
- package/dist/dts/components/chat-bubble/chat-bubble.styles.d.ts.map +1 -1
- package/dist/dts/components/chat-bubble/chat-bubble.template.d.ts.map +1 -1
- package/dist/dts/components/chat-driver/chat-driver.d.ts +5 -1
- package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
- package/dist/dts/components/chat-driver/interaction-controller.d.ts +27 -3
- package/dist/dts/components/chat-driver/interaction-controller.d.ts.map +1 -1
- package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.d.ts +10 -2
- package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.d.ts.map +1 -1
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts +9 -1
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
- package/dist/dts/config/config.d.ts +183 -0
- package/dist/dts/config/config.d.ts.map +1 -1
- package/dist/dts/config/define-stateful-agent.d.ts +31 -1
- package/dist/dts/config/define-stateful-agent.d.ts.map +1 -1
- package/dist/dts/genesis/write-commit.d.ts +17 -7
- package/dist/dts/genesis/write-commit.d.ts.map +1 -1
- package/dist/dts/index.d.ts +7 -3
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/main/main.d.ts +128 -5
- 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 +2 -2
- package/dist/dts/main/main.template.d.ts.map +1 -1
- package/dist/dts/react.d.ts +10 -0
- package/dist/dts/state/debug-event-log.d.ts +1 -1
- package/dist/dts/state/debug-event-log.d.ts.map +1 -1
- package/dist/dts/state/decision-surface.d.ts +46 -0
- package/dist/dts/state/decision-surface.d.ts.map +1 -0
- package/dist/dts/state/interaction-context.d.ts +21 -1
- package/dist/dts/state/interaction-context.d.ts.map +1 -1
- package/dist/dts/state/interaction-registry.d.ts +63 -0
- package/dist/dts/state/interaction-registry.d.ts.map +1 -0
- package/dist/dts/state/persistence/session-persister.d.ts.map +1 -1
- package/dist/dts/state/persistence/session-snapshot.d.ts +21 -0
- package/dist/dts/state/persistence/session-snapshot.d.ts.map +1 -1
- package/dist/dts/state/run-steps.d.ts +66 -0
- package/dist/dts/state/run-steps.d.ts.map +1 -0
- package/dist/dts/types/ai-chat-widget.d.ts +7 -1
- package/dist/dts/types/ai-chat-widget.d.ts.map +1 -1
- package/dist/dts/types/interaction-context.d.ts +66 -1
- package/dist/dts/types/interaction-context.d.ts.map +1 -1
- package/dist/dts/types/interaction-interceptor.d.ts +60 -2
- package/dist/dts/types/interaction-interceptor.d.ts.map +1 -1
- package/dist/dts/types/interaction-surface.d.ts +195 -0
- package/dist/dts/types/interaction-surface.d.ts.map +1 -0
- package/dist/dts/utils/context-tokens.d.ts +6 -0
- package/dist/dts/utils/context-tokens.d.ts.map +1 -1
- package/dist/dts/utils/delegated-message.d.ts +13 -0
- package/dist/dts/utils/delegated-message.d.ts.map +1 -1
- package/dist/dts/utils/history-transform.d.ts.map +1 -1
- package/dist/dts/utils/preserved-user-messages.d.ts +21 -0
- package/dist/dts/utils/preserved-user-messages.d.ts.map +1 -0
- package/dist/esm/autopilot/autopilot-driver.js +906 -0
- package/dist/esm/autopilot/autopilot-session.js +449 -0
- package/dist/esm/autopilot/autopilot-tools.js +68 -0
- package/dist/esm/autopilot/decision-message.js +206 -0
- package/dist/esm/autopilot/hand-back/hand-back.controller.js +47 -0
- package/dist/esm/autopilot/hand-back/hand-back.js +129 -0
- package/dist/esm/autopilot/index.js +4 -0
- package/dist/esm/channel/ai-activity-bus.js +7 -0
- package/dist/esm/channel/autopilot-needs-user.js +26 -0
- package/dist/esm/components/agent-picker/agent-picker.constants.js +10 -0
- package/dist/esm/components/agent-picker/agent-picker.js +11 -1
- package/dist/esm/components/agent-picker/agent-picker.template.js +2 -4
- package/dist/esm/components/ai-driver/ai-driver.js +2 -0
- package/dist/esm/components/ai-driver/base-driver-decorator.js +8 -0
- package/dist/esm/components/chat-bubble/chat-bubble.js +45 -0
- package/dist/esm/components/chat-bubble/chat-bubble.styles.js +26 -0
- package/dist/esm/components/chat-bubble/chat-bubble.template.js +13 -0
- package/dist/esm/components/chat-driver/chat-driver.js +53 -18
- package/dist/esm/components/chat-driver/interaction-controller.js +297 -12
- package/dist/esm/components/chat-interaction-wrapper/chat-interaction-wrapper.js +16 -2
- package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +28 -11
- package/dist/esm/config/define-stateful-agent.js +34 -29
- package/dist/esm/genesis/write-outcome.js +2 -2
- package/dist/esm/index.js +3 -0
- package/dist/esm/main/main.js +334 -15
- package/dist/esm/main/main.styles.js +126 -0
- package/dist/esm/main/main.template.js +116 -11
- package/dist/esm/state/debug-event-log.js +28 -1
- package/dist/esm/state/decision-surface.js +209 -0
- package/dist/esm/state/interaction-context.js +89 -1
- package/dist/esm/state/interaction-registry.js +33 -0
- package/dist/esm/state/persistence/session-persister.js +23 -11
- package/dist/esm/state/persistence/session-snapshot.js +1 -1
- package/dist/esm/state/run-steps.js +77 -0
- package/dist/esm/types/interaction-surface.js +1 -0
- package/dist/esm/utils/context-tokens.js +23 -9
- package/dist/esm/utils/delegated-message.js +15 -0
- package/dist/esm/utils/history-transform.js +18 -7
- package/dist/esm/utils/preserved-user-messages.js +31 -0
- package/dist/react.cjs +7 -0
- package/dist/react.mjs +6 -0
- package/docs/styling.md +1 -1
- package/package.json +17 -17
- package/sandbox/README.md +38 -2
- package/sandbox/autopilot.ts +358 -0
- package/sandbox/controls.ts +24 -1
- package/sandbox/fixtures.ts +2 -0
- package/sandbox/sandbox.ts +188 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { freshUserMessages, verbatimUserMessagesBlock } from './preserved-user-messages';
|
|
1
2
|
/**
|
|
2
3
|
* Context-window accounting (GENC-1567) — estimating how much of the model's
|
|
3
4
|
* context each message occupies, so compaction can be sized in the unit that
|
|
@@ -191,27 +192,32 @@ const TEXT_ATTACHMENT_FRAMING_CHARS = 9;
|
|
|
191
192
|
* `toolCall.subAgentTrace` is deliberately not counted either — it hangs off the
|
|
192
193
|
* tool call for the UI's benefit and is never sent, so counting it would
|
|
193
194
|
* attribute a whole sub-agent transcript to the parent's context.
|
|
195
|
+
*
|
|
196
|
+
* A compaction summary's kept user messages ARE counted: `normalizeForProvider`
|
|
197
|
+
* sends them, word for word, after the summary (GENC-1660, C2), and they can be
|
|
198
|
+
* the larger part of it — a pasted spec, every answer sent on the user's behalf.
|
|
194
199
|
*/
|
|
195
200
|
function wireChars(m) {
|
|
196
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
197
|
-
let chars = (_b = (_a = m.content) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0
|
|
198
|
-
|
|
201
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
202
|
+
let chars = ((_b = (_a = m.content) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) +
|
|
203
|
+
verbatimUserMessagesBlock((_c = m.compaction) === null || _c === void 0 ? void 0 : _c.preservedUserMessages).length;
|
|
204
|
+
for (const attachment of (_d = m.attachments) !== null && _d !== void 0 ? _d : []) {
|
|
199
205
|
if (attachment.kind === 'image')
|
|
200
206
|
continue;
|
|
201
207
|
chars +=
|
|
202
|
-
TEXT_ATTACHMENT_FRAMING_CHARS + attachment.name.length + ((
|
|
208
|
+
TEXT_ATTACHMENT_FRAMING_CHARS + attachment.name.length + ((_f = (_e = attachment.content) === null || _e === void 0 ? void 0 : _e.length) !== null && _f !== void 0 ? _f : 0);
|
|
203
209
|
}
|
|
204
|
-
for (const tc of (
|
|
210
|
+
for (const tc of (_g = m.toolCalls) !== null && _g !== void 0 ? _g : []) {
|
|
205
211
|
chars += tc.name.length;
|
|
206
212
|
try {
|
|
207
|
-
chars += JSON.stringify((
|
|
213
|
+
chars += JSON.stringify((_h = tc.args) !== null && _h !== void 0 ? _h : {}).length;
|
|
208
214
|
}
|
|
209
|
-
catch (
|
|
215
|
+
catch (_m) {
|
|
210
216
|
// Circular or otherwise unserializable args: skip rather than throw. The
|
|
211
217
|
// framing allowance below still counts the call itself.
|
|
212
218
|
}
|
|
213
219
|
}
|
|
214
|
-
chars += (
|
|
220
|
+
chars += (_l = (_k = (_j = m.toolResult) === null || _j === void 0 ? void 0 : _j.content) === null || _k === void 0 ? void 0 : _k.length) !== null && _l !== void 0 ? _l : 0;
|
|
215
221
|
return chars;
|
|
216
222
|
}
|
|
217
223
|
/** Char-derived token estimate for one message, before any measured calibration. */
|
|
@@ -567,6 +573,12 @@ export function estimateRequestTokens(storedHistory, requestHistory, preambleTok
|
|
|
567
573
|
*
|
|
568
574
|
* The system preamble is carried across unchanged: compaction removes messages,
|
|
569
575
|
* never the system prompt or the tool definitions.
|
|
576
|
+
*
|
|
577
|
+
* Besides the summary allowance, the summary carries the covered range's own user
|
|
578
|
+
* messages word for word (GENC-1660, C2), so those are priced too: a range that
|
|
579
|
+
* is mostly the user's own pastes reclaims far less than its size suggests. An
|
|
580
|
+
* earlier summary's kept messages are not carried forward (they fold into the new
|
|
581
|
+
* paraphrase), so they are reclaimed with the rest of the range.
|
|
570
582
|
*/
|
|
571
583
|
export function projectCompaction(history, cut, summaryTokens = COMPACTION_SUMMARY_TOKEN_ESTIMATE, preambleTokens) {
|
|
572
584
|
// One calibration for both figures, so `tokensBefore` is the same number the
|
|
@@ -576,8 +588,10 @@ export function projectCompaction(history, cut, summaryTokens = COMPACTION_SUMMA
|
|
|
576
588
|
let tail = 0;
|
|
577
589
|
for (let i = cut; i < estimates.length; i += 1)
|
|
578
590
|
tail += estimates[i];
|
|
591
|
+
const kept = Math.ceil(verbatimUserMessagesBlock(freshUserMessages(history.slice(0, cut))).length /
|
|
592
|
+
APPROX_CHARS_PER_TOKEN);
|
|
579
593
|
const tokensBefore = total;
|
|
580
|
-
const tokensAfter = overhead + summaryTokens + tail;
|
|
594
|
+
const tokensAfter = overhead + summaryTokens + kept + tail;
|
|
581
595
|
return {
|
|
582
596
|
cut,
|
|
583
597
|
compactedCount: cut,
|
|
@@ -12,6 +12,21 @@ export const isDelegated = (message) => !!message.delegate;
|
|
|
12
12
|
* @beta
|
|
13
13
|
*/
|
|
14
14
|
export const DEFAULT_DELEGATE_FRAMING = "Sent on the user's behalf.";
|
|
15
|
+
/**
|
|
16
|
+
* The fields a delegated `user` message is stored with, from the options it was sent with: who sent
|
|
17
|
+
* it, the framing the model reads, and what writing it cost. Empty for the person's own message.
|
|
18
|
+
*
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export function delegatedFields(options) {
|
|
22
|
+
var _a;
|
|
23
|
+
if (!(options === null || options === void 0 ? void 0 : options.delegate))
|
|
24
|
+
return {};
|
|
25
|
+
const cost = options.externalCostUsd;
|
|
26
|
+
return Object.assign({ delegate: options.delegate, delegateFraming: (_a = options.delegateFraming) !== null && _a !== void 0 ? _a : DEFAULT_DELEGATE_FRAMING }, (typeof cost === 'number' && Number.isFinite(cost) && cost > 0
|
|
27
|
+
? { externalCostUsd: cost }
|
|
28
|
+
: {}));
|
|
29
|
+
}
|
|
15
30
|
/**
|
|
16
31
|
* A delegated `user` message's content as the model reads it: its framing in brackets, then the
|
|
17
32
|
* text. The one place this string is built, so the first model call (which takes the message as
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
2
|
import { COMPACTION_SUMMARY_TOKEN_ESTIMATE, estimateMessageTokens, projectCompaction, reachesProvider, } from './context-tokens';
|
|
3
3
|
import { frameDelegatedContent } from './delegated-message';
|
|
4
|
+
import { preservedUserLine, verbatimUserMessagesBlock } from './preserved-user-messages';
|
|
4
5
|
/**
|
|
5
6
|
* Masks the tool-specific payload of a single message — clears tool call args
|
|
6
7
|
* and replaces tool result content with a placeholder. Used when passing history
|
|
@@ -200,10 +201,15 @@ export function planCompaction(history, options = {}) {
|
|
|
200
201
|
}
|
|
201
202
|
/** One-line rendering of a message for the summarizer transcript. */
|
|
202
203
|
function renderMessageForSummary(m) {
|
|
203
|
-
var _a;
|
|
204
|
+
var _a, _b, _c;
|
|
204
205
|
switch (m.role) {
|
|
205
206
|
case 'compacted-summary':
|
|
206
|
-
|
|
207
|
+
// Its kept user messages too: a new compaction keeps only its own range's word for word, so
|
|
208
|
+
// the earlier ones survive by being folded into the new paraphrase (GENC-1660, C2).
|
|
209
|
+
return [
|
|
210
|
+
`[Earlier summary] ${m.content}`,
|
|
211
|
+
...((_b = (_a = m.compaction) === null || _a === void 0 ? void 0 : _a.preservedUserMessages) !== null && _b !== void 0 ? _b : []).map((u) => `[Kept word for word with it] ${preservedUserLine(u)}`),
|
|
212
|
+
].join('\n');
|
|
207
213
|
case 'user':
|
|
208
214
|
// A delegated message keeps its framing here too, or the summary would put words in the
|
|
209
215
|
// user's mouth that outlive the message itself (GENC-1660).
|
|
@@ -220,7 +226,7 @@ function renderMessageForSummary(m) {
|
|
|
220
226
|
if (m.category === 'narration') {
|
|
221
227
|
return m.content ? `Working: ${m.content}` : '';
|
|
222
228
|
}
|
|
223
|
-
if ((
|
|
229
|
+
if ((_c = m.toolCalls) === null || _c === void 0 ? void 0 : _c.length) {
|
|
224
230
|
const calls = m.toolCalls.map((t) => t.name).join(', ');
|
|
225
231
|
return m.content
|
|
226
232
|
? `Assistant: ${m.content} (called: ${calls})`
|
|
@@ -270,7 +276,7 @@ export function buildCompactionSummaryPrompt(toCompact) {
|
|
|
270
276
|
*/
|
|
271
277
|
export function normalizeForProvider(history) {
|
|
272
278
|
return history.map((m) => {
|
|
273
|
-
var _a;
|
|
279
|
+
var _a, _b, _c;
|
|
274
280
|
// A user message sent on the user's behalf (GENC-1660) is framed, so the model never reads
|
|
275
281
|
// it as something the person typed.
|
|
276
282
|
if (m.role === 'user' && m.delegate) {
|
|
@@ -278,9 +284,14 @@ export function normalizeForProvider(history) {
|
|
|
278
284
|
}
|
|
279
285
|
if (m.role !== 'compacted-summary')
|
|
280
286
|
return m;
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
287
|
+
// The user's own messages from the compacted range, word for word, so a paraphrase never
|
|
288
|
+
// stands in for what they actually said (GENC-1660, C2).
|
|
289
|
+
const preserved = (_c = (_b = m.compaction) === null || _b === void 0 ? void 0 : _b.preservedUserMessages) !== null && _c !== void 0 ? _c : [];
|
|
290
|
+
const verbatim = verbatimUserMessagesBlock(preserved);
|
|
291
|
+
return Object.assign(Object.assign({}, m), { role: 'user', content: `<conversation_summary>\n${m.content}\n</conversation_summary>${verbatim}\n\n` +
|
|
292
|
+
'The above summarizes earlier parts of this conversation that were compacted' +
|
|
293
|
+
(preserved.length ? ", with the user's own messages from them kept word for word" : '') +
|
|
294
|
+
'. Continue naturally from it.', compaction: undefined });
|
|
284
295
|
});
|
|
285
296
|
}
|
|
286
297
|
/** Human-facing divider label for a `compacted-summary` message. */
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { frameDelegatedContent } from './delegated-message';
|
|
2
|
+
/**
|
|
3
|
+
* The user messages a compaction of `toCompact` keeps word for word (GENC-1660, critique C2): the
|
|
4
|
+
* range's own, oldest first, delegated ones still marked as such.
|
|
5
|
+
*
|
|
6
|
+
* Only the range's own. An earlier summary in the range is not carried forward: the summariser
|
|
7
|
+
* reads it with its own kept messages, and folds them into the new paraphrase. So the kept block
|
|
8
|
+
* never grows past one compaction's worth, at the cost of steering from before the previous
|
|
9
|
+
* compaction surviving only as paraphrase.
|
|
10
|
+
*/
|
|
11
|
+
export function freshUserMessages(toCompact) {
|
|
12
|
+
return toCompact.flatMap((m) => {
|
|
13
|
+
var _a;
|
|
14
|
+
return m.role === 'user' && ((_a = m.content) === null || _a === void 0 ? void 0 : _a.trim())
|
|
15
|
+
? [
|
|
16
|
+
Object.assign(Object.assign({ content: m.content }, (m.timestamp ? { timestamp: m.timestamp } : {})), (m.delegate ? { delegate: m.delegate, delegateFraming: m.delegateFraming } : {})),
|
|
17
|
+
]
|
|
18
|
+
: [];
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/** One kept message as the model reads it: as the user, framed when it was sent on their behalf. */
|
|
22
|
+
export const preservedUserLine = (u) => `User: ${u.delegate ? frameDelegatedContent(u.content, u.delegateFraming) : u.content}`;
|
|
23
|
+
/**
|
|
24
|
+
* The kept user messages as the block that follows a summary on the wire, or `''` when there are
|
|
25
|
+
* none. The one place it is built, so what is sent and what the context estimate counts agree.
|
|
26
|
+
*/
|
|
27
|
+
export function verbatimUserMessagesBlock(preserved) {
|
|
28
|
+
if (!(preserved === null || preserved === void 0 ? void 0 : preserved.length))
|
|
29
|
+
return '';
|
|
30
|
+
return `\n\n<user_messages_verbatim>\n${preserved.map(preservedUserLine).join('\n')}\n</user_messages_verbatim>`;
|
|
31
|
+
}
|
package/dist/react.cjs
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
8
|
const React = require('react');
|
|
9
|
+
const { AutopilotHandBack: AutopilotHandBackWC } = require('./esm/autopilot/hand-back/hand-back.js');
|
|
9
10
|
const { AiActivityHalo: AiActivityHaloWC } = require('./esm/components/activity-halo/activity-halo.js');
|
|
10
11
|
const { AgentPicker: AgentPickerWC } = require('./esm/components/agent-picker/agent-picker.js');
|
|
11
12
|
const { AiChatBubble: AiChatBubbleWC } = require('./esm/components/chat-bubble/chat-bubble.js');
|
|
@@ -82,6 +83,11 @@ const ChatSuggestions = React.forwardRef(function ChatSuggestions(props, ref) {
|
|
|
82
83
|
return React.createElement(customElements.getName(ChatSuggestionsWC) ?? 'chat-suggestions', { ...rest, ref }, children);
|
|
83
84
|
});
|
|
84
85
|
|
|
86
|
+
const AutopilotHandBack = React.forwardRef(function AutopilotHandBack(props, ref) {
|
|
87
|
+
const { children, ...rest } = props;
|
|
88
|
+
return React.createElement(customElements.getName(AutopilotHandBackWC) ?? 'AUTOPILOT_HAND_BACK', { ...rest, ref }, children);
|
|
89
|
+
});
|
|
90
|
+
|
|
85
91
|
const AiActivityHalo = React.forwardRef(function AiActivityHalo(props, ref) {
|
|
86
92
|
const { children, ...rest } = props;
|
|
87
93
|
return React.createElement(customElements.getName(AiActivityHaloWC) ?? 'ai-activity-halo', { ...rest, ref }, children);
|
|
@@ -175,6 +181,7 @@ module.exports = {
|
|
|
175
181
|
AiWavesIndicator,
|
|
176
182
|
FoundationAiAssistant,
|
|
177
183
|
ChatSuggestions,
|
|
184
|
+
AutopilotHandBack,
|
|
178
185
|
AiActivityHalo,
|
|
179
186
|
AgentPicker,
|
|
180
187
|
AiChatBubble,
|
package/dist/react.mjs
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import React from 'react';
|
|
7
|
+
import { AutopilotHandBack as AutopilotHandBackWC } from './esm/autopilot/hand-back/hand-back.js';
|
|
7
8
|
import { AiActivityHalo as AiActivityHaloWC } from './esm/components/activity-halo/activity-halo.js';
|
|
8
9
|
import { AgentPicker as AgentPickerWC } from './esm/components/agent-picker/agent-picker.js';
|
|
9
10
|
import { AiChatBubble as AiChatBubbleWC } from './esm/components/chat-bubble/chat-bubble.js';
|
|
@@ -80,6 +81,11 @@ export const ChatSuggestions = React.forwardRef(function ChatSuggestions(props,
|
|
|
80
81
|
return React.createElement(customElements.getName(ChatSuggestionsWC) ?? 'chat-suggestions', { ...rest, ref }, children);
|
|
81
82
|
});
|
|
82
83
|
|
|
84
|
+
export const AutopilotHandBack = React.forwardRef(function AutopilotHandBack(props, ref) {
|
|
85
|
+
const { children, ...rest } = props;
|
|
86
|
+
return React.createElement(customElements.getName(AutopilotHandBackWC) ?? 'AUTOPILOT_HAND_BACK', { ...rest, ref }, children);
|
|
87
|
+
});
|
|
88
|
+
|
|
83
89
|
export const AiActivityHalo = React.forwardRef(function AiActivityHalo(props, ref) {
|
|
84
90
|
const { children, ...rest } = props;
|
|
85
91
|
return React.createElement(customElements.getName(AiActivityHaloWC) ?? 'ai-activity-halo', { ...rest, ref }, children);
|
package/docs/styling.md
CHANGED
|
@@ -266,7 +266,7 @@ one round-icon-button shape; the agent one additionally carries a label.
|
|
|
266
266
|
| `composer-bar` | The control bar under the textarea |
|
|
267
267
|
| `composer-bar-start` / `composer-bar-end` | The leading (agent / attach / ⋮) and trailing (Stop, Send) clusters |
|
|
268
268
|
| `input` | The textarea |
|
|
269
|
-
| `agent-toggle-button` | Agent button —
|
|
269
|
+
| `agent-toggle-button` | Agent button — a `sitemap` glyph under orchestration, the pinned agent's tinted pin otherwise |
|
|
270
270
|
| `attach-button` | Attach (paperclip) |
|
|
271
271
|
| `session-menu-button` | Session options (⋮) |
|
|
272
272
|
| `stop-button` | Stop, shown only while a turn runs |
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genesislcap/ai-assistant",
|
|
3
3
|
"description": "Genesis AI Assistant micro-frontend",
|
|
4
|
-
"version": "15.
|
|
4
|
+
"version": "15.63.0",
|
|
5
5
|
"license": "SEE LICENSE IN license.txt",
|
|
6
6
|
"main": "dist/esm/index.js",
|
|
7
7
|
"types": "dist/ai-assistant.d.ts",
|
|
@@ -92,31 +92,31 @@
|
|
|
92
92
|
}
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
|
-
"@genesislcap/foundation-comms": "15.
|
|
96
|
-
"@genesislcap/foundation-testing": "15.
|
|
97
|
-
"@genesislcap/genx": "15.
|
|
98
|
-
"@genesislcap/ts-builder": "15.
|
|
99
|
-
"@genesislcap/uvu-playwright-builder": "15.
|
|
100
|
-
"@genesislcap/vite-builder": "15.
|
|
101
|
-
"@genesislcap/webpack-builder": "15.
|
|
95
|
+
"@genesislcap/foundation-comms": "15.63.0",
|
|
96
|
+
"@genesislcap/foundation-testing": "15.63.0",
|
|
97
|
+
"@genesislcap/genx": "15.63.0",
|
|
98
|
+
"@genesislcap/ts-builder": "15.63.0",
|
|
99
|
+
"@genesislcap/uvu-playwright-builder": "15.63.0",
|
|
100
|
+
"@genesislcap/vite-builder": "15.63.0",
|
|
101
|
+
"@genesislcap/webpack-builder": "15.63.0",
|
|
102
102
|
"@types/dompurify": "^3.0.5",
|
|
103
103
|
"@types/marked": "^5.0.2",
|
|
104
104
|
"esbuild": "0.25.12"
|
|
105
105
|
},
|
|
106
106
|
"dependencies": {
|
|
107
|
-
"@genesislcap/foundation-ai": "15.
|
|
108
|
-
"@genesislcap/foundation-logger": "15.
|
|
109
|
-
"@genesislcap/foundation-notifications": "15.
|
|
110
|
-
"@genesislcap/foundation-redux": "15.
|
|
111
|
-
"@genesislcap/foundation-ui": "15.
|
|
112
|
-
"@genesislcap/foundation-utils": "15.
|
|
113
|
-
"@genesislcap/rapid-design-system": "15.
|
|
114
|
-
"@genesislcap/web-core": "15.
|
|
107
|
+
"@genesislcap/foundation-ai": "15.63.0",
|
|
108
|
+
"@genesislcap/foundation-logger": "15.63.0",
|
|
109
|
+
"@genesislcap/foundation-notifications": "15.63.0",
|
|
110
|
+
"@genesislcap/foundation-redux": "15.63.0",
|
|
111
|
+
"@genesislcap/foundation-ui": "15.63.0",
|
|
112
|
+
"@genesislcap/foundation-utils": "15.63.0",
|
|
113
|
+
"@genesislcap/rapid-design-system": "15.63.0",
|
|
114
|
+
"@genesislcap/web-core": "15.63.0",
|
|
115
115
|
"dompurify": "^3.3.1",
|
|
116
116
|
"marked": "^17.0.3"
|
|
117
117
|
},
|
|
118
118
|
"peerDependencies": {
|
|
119
|
-
"@genesislcap/foundation-comms": "^15.
|
|
119
|
+
"@genesislcap/foundation-comms": "^15.63.0"
|
|
120
120
|
},
|
|
121
121
|
"peerDependenciesMeta": {
|
|
122
122
|
"@genesislcap/foundation-comms": {
|
package/sandbox/README.md
CHANGED
|
@@ -30,12 +30,13 @@ The panel covers, roughly in the order you'll want them:
|
|
|
30
30
|
| **Session menu (⋮)** | Whether a persistence provider is configured (the menu is gated on one) and `showSessionMenu`; a button to open the menu |
|
|
31
31
|
| **Context window** | **Jump to state** (the four gate states in one click), the simulated window and fill, `chatConfig.context`, a flow-in-progress toggle, live readouts of the gate / thresholds / compaction plan, and Compact |
|
|
32
32
|
| **Simulated state** | Forces `idle` / busy / cancelling / blocked / compacting / restoring onto the element |
|
|
33
|
+
| **Autopilot** | The mode (unavailable / running / paused / self-paused), whether the agent hides the composer while working, the status text, "needs you", the collapsed bubble, a demo widget with a controller and who holds it, and the delegated mark |
|
|
33
34
|
| **Transcript** | Seeds an empty, short, tool-and-markdown-heavy, 28-turn, ~20k-token, or ~22k-token tool-loop conversation, and how far back to shift its timestamps |
|
|
34
35
|
| **Chrome** | Header title, popout mode, suggestions, the tool-call / reasoning / narration toggles, the timestamp mode, animations, per-reply thumbs (`messageFeedback`, with a stub send that succeeds or fails) |
|
|
35
36
|
| **Stage** | Frame size (floored at 400px — see below), light/dark, remount, full reset |
|
|
36
37
|
|
|
37
|
-
Panel state persists in `localStorage`, so a reload picks up where you left off
|
|
38
|
-
clears
|
|
38
|
+
Panel state persists in `localStorage`, so a reload picks up where you left off — including which
|
|
39
|
+
groups are open. **Reset sandbox** clears both.
|
|
39
40
|
|
|
40
41
|
## The stub provider
|
|
41
42
|
|
|
@@ -165,6 +166,41 @@ a binding once and an idle conversation never re-renders — without it "2 minut
|
|
|
165
166
|
still read "2 minutes ago" an hour later. The ticker only runs while the element is connected
|
|
166
167
|
and the mode is not `off`.
|
|
167
168
|
|
|
169
|
+
## Checking the autopilot UI (GENC-1660)
|
|
170
|
+
|
|
171
|
+
Everything the person sees around the autopilot, without one: the slim bar in the composer's place,
|
|
172
|
+
the hand-back banner inside a widget's own bubble, the halo staying on while the autopilot decides,
|
|
173
|
+
the four states of a widget, the autopilot mark on what it did, and the "needs you" badge.
|
|
174
|
+
|
|
175
|
+
Two stand-ins, both in `autopilot.ts`, and both reaching the element through its ordinary inputs:
|
|
176
|
+
|
|
177
|
+
- **The host** is a stub `AutopilotHost`, set as the element's `autopilotHostOverride` — the input a
|
|
178
|
+
real host leaves alone, because the element finds the `AutopilotDriver` it installed itself. Its
|
|
179
|
+
buttons really move it: the **Autopilot** pill pauses it while it is on and resumes it while it
|
|
180
|
+
is off, **Keep paused** on the banner keeps it paused, and the **Mode** control follows the click.
|
|
181
|
+
- **The demo widget** is Appendix A's confirm button: a registered widget with a DOM-free controller,
|
|
182
|
+
opened through the driver's `presentInteraction` as a tool would ask, and claimed by a real
|
|
183
|
+
interceptor on the element's own driver. **Demo widget held by** moves it through that interceptor's
|
|
184
|
+
real hold, so `heldBy` changes the way it does under the autopilot and the element decides what to
|
|
185
|
+
show for itself.
|
|
186
|
+
|
|
187
|
+
| Control | What to look for |
|
|
188
|
+
| --- | --- |
|
|
189
|
+
| **Mode: Unavailable** | Today's UI, unchanged. Nothing autopilot-shaped anywhere. |
|
|
190
|
+
| **Mode: Running** | While something is happening — **Simulated state: Busy**, or the demo widget open and held by the autopilot — the slim bar replaces the composer: the status, then the **Autopilot** pill on the right — filled like your own bubble while it is on, with the mark as its glyph and "Pause autopilot: …" as its tooltip — and **Stop** while busy. No text box, so nothing can be typed by accident. Idle (the state as it is after a wall such as the budget), the normal composer comes back with the pill filled among its pills, and no status. |
|
|
191
|
+
| **Mode: Paused** | With **Agent hides the composer while working** on and the state Busy, the slim bar again, reading "Paused" with the pill unfilled. Turn the toggle off (or go idle) and the normal composer comes back with the pill after the agent picker, among the other pills — the autopilot never forces the composer open. |
|
|
192
|
+
| **Hide composer** + **Mode: Running** or **Paused** | A host with no composer has no pills to put the **Autopilot** pill among, so the slim bar stays up whenever the autopilot is available — idle or not, running or paused — with its status and the pill, so the person can always see it is on and pause or resume it. |
|
|
193
|
+
| **Mode: Self-paused** | With the state Busy, the slim bar reads "Waiting for your answer…" with the pill unfilled; its tooltip leads with "Resume autopilot and force it to decide this one". Open the demo widget: its bubble carries the banner, "I need your input on this one: …", with **Keep paused**. |
|
|
194
|
+
| **Open the demo widget**, held by the autopilot | **Hidden** registration: no bubble at all, just the working indicator. **Visible**: the bubble stays and only its button goes, with a line saying the claimant holds it. |
|
|
195
|
+
| **Held by: The person** | The widget comes back with its button, exactly as today. Press it to see the answered state. |
|
|
196
|
+
| **Seed: Autopilot: delegated messages** | Narration before an answered widget, the "I chose" echo, and a written answer given on the user's behalf — every one on the assistant's side, with the mark beside the sender. **Delegated mark: None** removes the mark and nothing else. |
|
|
197
|
+
| **Needs you** + **Show the collapsed bubble** | A badge on the orb, bottom right. Self-paused raises it too. |
|
|
198
|
+
|
|
199
|
+
The **Element** readout is read off the element, not the panel: who holds the trailing interaction,
|
|
200
|
+
the halo, and whether the slim bar is up. Set **Simulated state: Busy**, open the demo widget, and
|
|
201
|
+
flip **Held by**: the halo stays on while the autopilot holds it and stops when the person does,
|
|
202
|
+
because the assistant is only waiting when the person holds the question.
|
|
203
|
+
|
|
168
204
|
## 400px is the narrowest supported width
|
|
169
205
|
|
|
170
206
|
The stage will not go below it — slider, drag handle and a restored panel state are all clamped —
|