@burdenoff/fe-libs 2026.915.4 → 2026.917.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/shared/assistant/adminModeSendGate.d.ts +81 -0
- package/dist/shared/assistant/adminModeSendGate.d.ts.map +1 -0
- package/dist/shared/assistant/adminModeSendGate.js +37 -0
- package/dist/shared/assistant/api.d.ts +8 -6
- package/dist/shared/assistant/api.d.ts.map +1 -1
- package/dist/shared/assistant/api.js +2 -2
- package/dist/shared/assistant/conversation.d.ts +44 -0
- package/dist/shared/assistant/conversation.d.ts.map +1 -1
- package/dist/shared/assistant/createSandboxAssistantTransport.d.ts.map +1 -1
- package/dist/shared/assistant/createSandboxAssistantTransport.js +27 -27
- package/dist/shared/assistant/i18nManifest.d.ts +9 -3
- package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
- package/dist/shared/assistant/i18nManifest.js +13 -10
- package/dist/shared/assistant/images.d.ts +37 -2
- package/dist/shared/assistant/images.d.ts.map +1 -1
- package/dist/shared/assistant/images.js +24 -16
- package/dist/shared/assistant/index.d.ts +3 -0
- package/dist/shared/assistant/index.d.ts.map +1 -1
- package/dist/shared/assistant/legacyFiller.d.ts.map +1 -1
- package/dist/shared/assistant/legacyFiller.js +2 -2
- package/dist/shared/assistant/modeCapabilities.d.ts +126 -0
- package/dist/shared/assistant/modeCapabilities.d.ts.map +1 -0
- package/dist/shared/assistant/modeCapabilities.js +50 -0
- package/dist/shared/assistant/modeCopy.d.ts +27 -7
- package/dist/shared/assistant/modeCopy.d.ts.map +1 -1
- package/dist/shared/assistant/modeCopy.js +7 -1
- package/dist/shared/assistant/modeIds.d.ts +67 -0
- package/dist/shared/assistant/modeIds.d.ts.map +1 -0
- package/dist/shared/assistant/modeIds.js +21 -0
- package/dist/shared/assistant/preview/AssistantPreviewOverlay.d.ts.map +1 -1
- package/dist/shared/assistant/progress.d.ts +38 -1
- package/dist/shared/assistant/progress.d.ts.map +1 -1
- package/dist/shared/assistant/progress.js +31 -17
- package/dist/shared/assistant/streamBudget.d.ts +18 -18
- package/dist/shared/assistant/streamBudget.d.ts.map +1 -1
- package/dist/shared/assistant/streamBudget.js +21 -19
- package/dist/shared/assistant/turnProgress.d.ts +2 -1
- package/dist/shared/assistant/turnProgress.d.ts.map +1 -1
- package/dist/shared/assistant/turnProgress.js +15 -15
- package/dist/shared/assistant/types.d.ts +43 -1
- package/dist/shared/assistant/types.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantChatArea.js +340 -317
- package/dist/shared/assistant/ui/AssistantToolActivity.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantToolActivity.js +3 -3
- package/dist/shared/assistant/ui/composer/AssistantModeSelector.d.ts +18 -2
- package/dist/shared/assistant/ui/composer/AssistantModeSelector.d.ts.map +1 -1
- package/dist/shared/assistant/ui/composer/AssistantModeSelector.js +38 -32
- package/dist/shared-assistant.js +118 -115
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { INCOMPLETE_TURN_NOTICES as e } from "./streamBudget.js";
|
|
2
2
|
import { STAGE_COPY as t, THINKING_PHRASES as n, stageText as r } from "./stageCopy.js";
|
|
3
3
|
//#region src/shared/assistant/legacyFiller.ts
|
|
4
4
|
var i = [
|
|
@@ -26,7 +26,7 @@ function l(n, r) {
|
|
|
26
26
|
let o = r.slice(0, i).trim();
|
|
27
27
|
if (!a(n, t.thinking, o)) return null;
|
|
28
28
|
let s = r.slice(i + 2);
|
|
29
|
-
return
|
|
29
|
+
return e.some((e) => {
|
|
30
30
|
let t = n(e.key, e.fallback);
|
|
31
31
|
return s.startsWith(e.fallback) || t !== "" && s.startsWith(t);
|
|
32
32
|
}) ? s : null;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { AssistantModeConfig } from './conversation';
|
|
2
|
+
import { AssistantMode, BuiltInAssistantMode } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* What a mode DOES, as far as the panel is concerned: whether its turns produce
|
|
5
|
+
* files, how long one turn may run, and whether an unfinished turn keeps going
|
|
6
|
+
* server-side.
|
|
7
|
+
*
|
|
8
|
+
* ★★ Capabilities, not mode ids. Each of these was a `mode === "vibe-plugins"`
|
|
9
|
+
* test scattered across the panel, which meant no other mode could ever list
|
|
10
|
+
* artifacts or run a long build — however it was configured — without another
|
|
11
|
+
* edit to shared code naming it. A product now says what its mode does on its
|
|
12
|
+
* `AssistantModeConfig`, and this is the one place that decides.
|
|
13
|
+
*
|
|
14
|
+
* ★ Built-in ids keep their built-in behaviour when the product says nothing.
|
|
15
|
+
* That is what keeps an existing product byte-identical: VibeControls' `Build`
|
|
16
|
+
* mode is `vibe-plugins` with none of these fields, and resolves exactly as the
|
|
17
|
+
* hard-coded checks did (artifacts, 600s, "still building").
|
|
18
|
+
*/
|
|
19
|
+
export interface AssistantModeCapabilities {
|
|
20
|
+
/** List `/sessions/:id/artifacts` after each turn and render them. */
|
|
21
|
+
readonly producesArtifacts: boolean;
|
|
22
|
+
/** How long the client polls one turn before closing it as unfinished. */
|
|
23
|
+
readonly streamBudgetMs: number;
|
|
24
|
+
/** An unfinished turn keeps building server-side — selects the "still building" note. */
|
|
25
|
+
readonly continuesInBackground: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Report this run's narration for the WHOLE run, joined oldest first, instead
|
|
28
|
+
* of only its newest message (BC1, BOFF-7334).
|
|
29
|
+
*
|
|
30
|
+
* ★★ Off for every mode by default, and deliberately so. Latest-only is what
|
|
31
|
+
* both host panels and every product wrapping the shared transport render
|
|
32
|
+
* today, so this cannot be switched on globally. It also changes what is
|
|
33
|
+
* STORED — the completed turn persists this content as its answer — so only a
|
|
34
|
+
* mode whose answer IS the account of what it built should ask for it.
|
|
35
|
+
*/
|
|
36
|
+
readonly accumulatesNarration: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* May the panel provision a sandbox for this mode at all.
|
|
39
|
+
*
|
|
40
|
+
* ★ `false` only for a mode that is neither built in nor declared by the
|
|
41
|
+
* product — a persisted id from another build, or a malformed one. It fails
|
|
42
|
+
* CLOSED: no sandbox, no artifacts, the default budget.
|
|
43
|
+
*/
|
|
44
|
+
readonly provisionable: boolean;
|
|
45
|
+
}
|
|
46
|
+
/** The capability fields a product may set, plus the id they belong to. */
|
|
47
|
+
export type AssistantModeCapabilityConfig = Pick<AssistantModeConfig, "id" | "producesArtifacts" | "streamBudgetMs" | "continuesInBackground" | "accumulatesNarration">;
|
|
48
|
+
/**
|
|
49
|
+
* The largest `streamBudgetMs` a product may configure: one hour.
|
|
50
|
+
*
|
|
51
|
+
* The sandbox TTL is extended every 30s while a turn is polled, so a long budget
|
|
52
|
+
* never outlives the sandbox — but a value like `Infinity` or a seconds/ms mix-up
|
|
53
|
+
* (`600_000_000`) would leave a spinner up for days. Out-of-range values fall
|
|
54
|
+
* back to the default rather than throwing, for the same reason a `NaN` must.
|
|
55
|
+
*/
|
|
56
|
+
export declare const MAX_ASSISTANT_STREAM_BUDGET_MS = 3600000;
|
|
57
|
+
/**
|
|
58
|
+
* The built-in modes' behaviour. The ONLY table in shared code that knows
|
|
59
|
+
* `vibe-plugins` builds things.
|
|
60
|
+
*/
|
|
61
|
+
export declare const BUILT_IN_MODE_CAPABILITIES: Readonly<Record<BuiltInAssistantMode, AssistantModeCapabilities>>;
|
|
62
|
+
/** Fail-closed result for a mode nobody declared. */
|
|
63
|
+
export declare const UNDECLARED_MODE_CAPABILITIES: AssistantModeCapabilities;
|
|
64
|
+
/**
|
|
65
|
+
* The capabilities of `mode`, given the product's config for it.
|
|
66
|
+
*
|
|
67
|
+
* - Built-in id: its built-in behaviour, with any field the product set applied
|
|
68
|
+
* over it.
|
|
69
|
+
* - Product-declared id WITH a config: chat defaults with the product's fields
|
|
70
|
+
* applied. Declared means "the product offers a config for exactly this id".
|
|
71
|
+
* - Anything else — an unoffered product id, a malformed id, no mode at all:
|
|
72
|
+
* `UNDECLARED_MODE_CAPABILITIES`.
|
|
73
|
+
*
|
|
74
|
+
* ★ A config whose `id` is not `mode` is IGNORED. The caller looked it up, and a
|
|
75
|
+
* lookup that fell back to another mode (as `resolveModeConfig` does, by design,
|
|
76
|
+
* for display) would otherwise lend one mode's 10-minute budget and artifact
|
|
77
|
+
* listing to another.
|
|
78
|
+
*
|
|
79
|
+
* ★ `continuesInBackground` follows `producesArtifacts` when only the latter is
|
|
80
|
+
* set: the "still building" note promises "any artifacts below will finish
|
|
81
|
+
* shortly", which is only ever true of a mode that produces them.
|
|
82
|
+
*/
|
|
83
|
+
export declare function resolveAssistantModeCapabilities(mode: AssistantMode | null | undefined, config?: AssistantModeCapabilityConfig | null): AssistantModeCapabilities;
|
|
84
|
+
/**
|
|
85
|
+
* Why a send in an admin-only mode must not go out yet, or null when it may.
|
|
86
|
+
*
|
|
87
|
+
* ★★ The mode list hides an admin-only mode from a non-admin, and an effect
|
|
88
|
+
* resets a persisted one back to Ask — but only AFTER the role check resolves,
|
|
89
|
+
* so an admin's own persisted choice is not reset during that window. A send in
|
|
90
|
+
* the window used to go straight through: the mode was provisioned while the
|
|
91
|
+
* answer was still unknown, and the proxy-token modes have no server-side admin
|
|
92
|
+
* check behind it. So the send asks the same question the list does.
|
|
93
|
+
*
|
|
94
|
+
* ★★ `loading` is NOT the send's normal path through here. The send WAITS for
|
|
95
|
+
* the check (`adminOnlyModeSendRefusalAfterAccess`), because refusing during it
|
|
96
|
+
* broke every product whose help button opens the panel and sends on the next
|
|
97
|
+
* tick. Reaching this branch means that wait timed out, so the copy says the
|
|
98
|
+
* check has not finished — it must never read as a refusal of the person.
|
|
99
|
+
*
|
|
100
|
+
* Only a config that says `requiresAdmin` is gated — Ask carries no such flag
|
|
101
|
+
* and is never held. Truthiness is read exactly as the mode list and the reset
|
|
102
|
+
* effect read it, so for any config the three agree.
|
|
103
|
+
*
|
|
104
|
+
* ★ The one case where they do not is a mode with NO config at all: the reset
|
|
105
|
+
* effect treats a missing config as blocked, while `requiresAdmin` is simply
|
|
106
|
+
* absent here, so nothing is gated. That is reachable only for a built-in id a
|
|
107
|
+
* build has stopped declaring — where there is no admin check to consult
|
|
108
|
+
* anyway, and `createApp` is RBAC-gated server-side regardless.
|
|
109
|
+
*/
|
|
110
|
+
export declare function adminOnlyModeSendRefusal(config: {
|
|
111
|
+
readonly requiresAdmin?: boolean;
|
|
112
|
+
} | null | undefined, access: {
|
|
113
|
+
readonly loading: boolean;
|
|
114
|
+
readonly canUseAdminModes: boolean;
|
|
115
|
+
}): string | null;
|
|
116
|
+
/**
|
|
117
|
+
* The product's config for EXACTLY this mode, or undefined.
|
|
118
|
+
*
|
|
119
|
+
* ★ Deliberately not `resolveModeConfig` (product.tsx), which falls back to the
|
|
120
|
+
* first mode so a stale id still renders suggestions. Behaviour must never be
|
|
121
|
+
* borrowed that way — see `resolveAssistantModeCapabilities`.
|
|
122
|
+
*/
|
|
123
|
+
export declare function findAssistantModeConfig<T extends {
|
|
124
|
+
id: AssistantMode;
|
|
125
|
+
}>(modes: readonly T[] | null | undefined, mode: AssistantMode | null | undefined): T | undefined;
|
|
126
|
+
//# sourceMappingURL=modeCapabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modeCapabilities.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/modeCapabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEnE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,yBAAyB;IACxC,sEAAsE;IACtE,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,0EAA0E;IAC1E,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,yFAAyF;IACzF,QAAQ,CAAC,qBAAqB,EAAE,OAAO,CAAC;IACxC;;;;;;;;;OASG;IACH,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;IACvC;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACjC;AAED,2EAA2E;AAC3E,MAAM,MAAM,6BAA6B,GAAG,IAAI,CAC9C,mBAAmB,EACjB,IAAI,GACJ,mBAAmB,GACnB,gBAAgB,GAChB,uBAAuB,GACvB,sBAAsB,CACzB,CAAC;AAKF;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,UAAY,CAAC;AAUxD;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAC/C,MAAM,CAAC,oBAAoB,EAAE,yBAAyB,CAAC,CAkBvD,CAAC;AAEH,qDAAqD;AACrD,eAAO,MAAM,4BAA4B,EAAE,yBAOvC,CAAC;AAeL;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,aAAa,GAAG,IAAI,GAAG,SAAS,EACtC,MAAM,CAAC,EAAE,6BAA6B,GAAG,IAAI,GAC5C,yBAAyB,CAyB3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE;IAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,EAC/D,MAAM,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAA;CAAE,GACxE,MAAM,GAAG,IAAI,CASf;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,aAAa,CAAA;CAAE,EACrE,KAAK,EAAE,SAAS,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,EACtC,IAAI,EAAE,aAAa,GAAG,IAAI,GAAG,SAAS,GACrC,CAAC,GAAG,SAAS,CAGf"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { isBuiltInAssistantMode as e } from "./modeCopy.js";
|
|
2
|
+
import { isProductAssistantModeId as t } from "./modeIds.js";
|
|
3
|
+
//#region src/shared/assistant/modeCapabilities.ts
|
|
4
|
+
var n = 18e4, r = 6e5, i = 36e5, a = Object.freeze({
|
|
5
|
+
producesArtifacts: !1,
|
|
6
|
+
streamBudgetMs: n,
|
|
7
|
+
continuesInBackground: !1,
|
|
8
|
+
accumulatesNarration: !1,
|
|
9
|
+
provisionable: !0
|
|
10
|
+
}), o = Object.freeze({
|
|
11
|
+
general: a,
|
|
12
|
+
assistant: a,
|
|
13
|
+
"api-calls": a,
|
|
14
|
+
"vibe-plugins": Object.freeze({
|
|
15
|
+
producesArtifacts: !0,
|
|
16
|
+
streamBudgetMs: r,
|
|
17
|
+
continuesInBackground: !0,
|
|
18
|
+
accumulatesNarration: !1,
|
|
19
|
+
provisionable: !0
|
|
20
|
+
})
|
|
21
|
+
}), s = Object.freeze({
|
|
22
|
+
producesArtifacts: !1,
|
|
23
|
+
streamBudgetMs: n,
|
|
24
|
+
continuesInBackground: !1,
|
|
25
|
+
accumulatesNarration: !1,
|
|
26
|
+
provisionable: !1
|
|
27
|
+
}), c = (e) => typeof e == "boolean" ? e : void 0, l = (e) => typeof e == "number" && Number.isFinite(e) && e > 0 && e <= 36e5 ? e : void 0;
|
|
28
|
+
function u(n, r) {
|
|
29
|
+
let i = r && r.id === n ? r : void 0, u;
|
|
30
|
+
if (e(n)) u = o[n];
|
|
31
|
+
else if (i && t(n)) u = a;
|
|
32
|
+
else return s;
|
|
33
|
+
if (!i) return u;
|
|
34
|
+
let d = c(i.producesArtifacts);
|
|
35
|
+
return {
|
|
36
|
+
producesArtifacts: d ?? u.producesArtifacts,
|
|
37
|
+
streamBudgetMs: l(i.streamBudgetMs) ?? u.streamBudgetMs,
|
|
38
|
+
continuesInBackground: c(i.continuesInBackground) ?? d ?? u.continuesInBackground,
|
|
39
|
+
accumulatesNarration: c(i.accumulatesNarration) ?? u.accumulatesNarration,
|
|
40
|
+
provisionable: !0
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function d(e, t) {
|
|
44
|
+
return e?.requiresAdmin ? t.loading ? "Still checking whether you can use this assistant mode. Wait a moment, then send again." : t.canUseAdminModes ? null : "This assistant mode is only available to organization admins. Switch to another mode and send again." : null;
|
|
45
|
+
}
|
|
46
|
+
function f(e, t) {
|
|
47
|
+
if (t) return e?.find((e) => e.id === t);
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { o as BUILT_IN_MODE_CAPABILITIES, i as MAX_ASSISTANT_STREAM_BUDGET_MS, s as UNDECLARED_MODE_CAPABILITIES, d as adminOnlyModeSendRefusal, f as findAssistantModeConfig, u as resolveAssistantModeCapabilities };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AssistantMode } from './types';
|
|
1
|
+
import { AssistantMode, BuiltInAssistantMode } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* The shared English name of each mode: what a mode pill shows when the
|
|
4
4
|
* product's own `label` is empty.
|
|
@@ -9,9 +9,10 @@ import { AssistantMode } from './types';
|
|
|
9
9
|
* the manifest outside any React tree — so neither may live behind a component
|
|
10
10
|
* import.
|
|
11
11
|
*
|
|
12
|
-
* ★ `satisfies Record<
|
|
13
|
-
* union: a new mode without a name here, or a name for a
|
|
14
|
-
* exists, fails the typecheck.
|
|
12
|
+
* ★ `satisfies Record<BuiltInAssistantMode, string>` makes the table exactly
|
|
13
|
+
* the built-in union: a new built-in mode without a name here, or a name for a
|
|
14
|
+
* mode that no longer exists, fails the typecheck. Product-declared modes are
|
|
15
|
+
* named by `assistantModeFallbackLabel`.
|
|
15
16
|
*/
|
|
16
17
|
export declare const ASSISTANT_MODE_FALLBACK_LABELS: {
|
|
17
18
|
readonly general: "Ask";
|
|
@@ -20,8 +21,27 @@ export declare const ASSISTANT_MODE_FALLBACK_LABELS: {
|
|
|
20
21
|
readonly "vibe-plugins": "Build";
|
|
21
22
|
};
|
|
22
23
|
/**
|
|
23
|
-
* Every mode id, read off the table above so the list cannot fall
|
|
24
|
-
* union.
|
|
24
|
+
* Every BUILT-IN mode id, read off the table above so the list cannot fall
|
|
25
|
+
* behind the union. Product-declared ids are, by design, not listed anywhere in
|
|
26
|
+
* shared code — see `ProductAssistantMode`.
|
|
25
27
|
*/
|
|
26
|
-
export declare const ASSISTANT_MODE_IDS: readonly
|
|
28
|
+
export declare const ASSISTANT_MODE_IDS: readonly BuiltInAssistantMode[];
|
|
29
|
+
/**
|
|
30
|
+
* Is this one of fe-libs' own modes?
|
|
31
|
+
*
|
|
32
|
+
* ★ Lives beside the table it reads, so the check and the list are one thing.
|
|
33
|
+
* `Object.hasOwn`, not `in`: `"toString" in table` is true.
|
|
34
|
+
*/
|
|
35
|
+
export declare function isBuiltInAssistantMode(value: unknown): value is BuiltInAssistantMode;
|
|
36
|
+
/**
|
|
37
|
+
* The shared English name for a mode whose product gave an empty `label`.
|
|
38
|
+
*
|
|
39
|
+
* Built-in: the table above. Product-declared: named by what it does — the
|
|
40
|
+
* build mode's word for a mode that `producesArtifacts`, otherwise Ask's. Same
|
|
41
|
+
* two words the built-ins already use, so no new copy exists to seed.
|
|
42
|
+
*/
|
|
43
|
+
export declare function assistantModeFallbackLabel(mode: {
|
|
44
|
+
id: AssistantMode;
|
|
45
|
+
producesArtifacts?: boolean;
|
|
46
|
+
}): string;
|
|
27
47
|
//# sourceMappingURL=modeCopy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modeCopy.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/modeCopy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"modeCopy.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/modeCopy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEnE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,8BAA8B;;;;;CAKc,CAAC;AAE1D;;;;GAIG;AAGH,eAAO,MAAM,kBAAkB,EAE1B,SAAS,oBAAoB,EAAE,CAAC;AAErC;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,oBAAoB,CAK/B;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,EAAE,EAAE,aAAa,CAAC;IAClB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,GAAG,MAAM,CAOT"}
|
|
@@ -5,5 +5,11 @@ var e = {
|
|
|
5
5
|
"api-calls": "Take action",
|
|
6
6
|
"vibe-plugins": "Build"
|
|
7
7
|
}, t = Object.keys(e);
|
|
8
|
+
function n(t) {
|
|
9
|
+
return typeof t == "string" && Object.hasOwn(e, t);
|
|
10
|
+
}
|
|
11
|
+
function r(t) {
|
|
12
|
+
return n(t.id) ? e[t.id] : t.producesArtifacts === !0 ? e["vibe-plugins"] : e.assistant;
|
|
13
|
+
}
|
|
8
14
|
//#endregion
|
|
9
|
-
export { e as ASSISTANT_MODE_FALLBACK_LABELS, t as ASSISTANT_MODE_IDS };
|
|
15
|
+
export { e as ASSISTANT_MODE_FALLBACK_LABELS, t as ASSISTANT_MODE_IDS, r as assistantModeFallbackLabel, n as isBuiltInAssistantMode };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { AssistantMode, BuiltInAssistantMode, ProductAssistantMode } from './types';
|
|
2
|
+
export { isBuiltInAssistantMode } from './modeCopy';
|
|
3
|
+
/**
|
|
4
|
+
* Which strings may name an assistant mode.
|
|
5
|
+
*
|
|
6
|
+
* Built-in ids are the `BuiltInAssistantMode` union. Everything else is a
|
|
7
|
+
* PRODUCT-declared id (see `ProductAssistantMode`) and must pass the checks
|
|
8
|
+
* below before shared code will provision, reuse, time or label a sandbox for it.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Lowercase kebab-case: `general`, `api-calls`, `vibe-plugins` all fit, and so
|
|
12
|
+
* does every product persona the sandbox service knows today.
|
|
13
|
+
*
|
|
14
|
+
* ★ Not cosmetic. The id is interpolated into the sandbox NAME
|
|
15
|
+
* (`ai-assistant-<id>-<epoch ms>`, a DNS-1123 label on the Kubernetes backend),
|
|
16
|
+
* stamped into its metadata, sent as `AI_ASSISTANT_MODE`, and becomes the last
|
|
17
|
+
* segment of the `mode.<id>` i18n key — where a `.` would split the key and a
|
|
18
|
+
* capital or space would make it unseedable.
|
|
19
|
+
*/
|
|
20
|
+
export declare const PRODUCT_ASSISTANT_MODE_ID_PATTERN: RegExp;
|
|
21
|
+
/**
|
|
22
|
+
* `ai-assistant-` (13) + id + `-` + 13-digit epoch ms must stay within the
|
|
23
|
+
* 63-character label limit: 63 - 27 = 36, rounded down for headroom.
|
|
24
|
+
*/
|
|
25
|
+
export declare const PRODUCT_ASSISTANT_MODE_ID_MAX_LENGTH = 32;
|
|
26
|
+
/**
|
|
27
|
+
* The built-in mode `value` extends with a `-` segment (`general-docs` →
|
|
28
|
+
* `general`), or undefined.
|
|
29
|
+
*
|
|
30
|
+
* ★★ Such an id is refused. Its sandboxes would be named
|
|
31
|
+
* `ai-assistant-general-docs-<epoch>`, which starts with the built-in's
|
|
32
|
+
* `ai-assistant-general-` — the prefix legacy built-in sandboxes are still
|
|
33
|
+
* recognised by. Metadata now decides first (`resolveSandboxAssistantMode`), so
|
|
34
|
+
* this is the second wall: no id a product can declare is a name-prefix
|
|
35
|
+
* collision with a built-in in the first place.
|
|
36
|
+
*/
|
|
37
|
+
export declare function builtInModeExtendedBy(value: string): BuiltInAssistantMode | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* A well-formed id that is NOT built in and does not extend a built-in's name —
|
|
40
|
+
* i.e. one only a product can declare.
|
|
41
|
+
*/
|
|
42
|
+
export declare function isProductAssistantModeId(value: unknown): value is ProductAssistantMode;
|
|
43
|
+
/** Built in, or a well-formed product id. Says nothing about whether it is OFFERED. */
|
|
44
|
+
export declare function isAssistantModeId(value: unknown): value is AssistantMode;
|
|
45
|
+
/**
|
|
46
|
+
* Admit a backend mode id a product offers — the one way to obtain a
|
|
47
|
+
* `ProductAssistantMode`.
|
|
48
|
+
*
|
|
49
|
+
* ```ts
|
|
50
|
+
* const NODE_BUILDER = declareAssistantMode("acme-node");
|
|
51
|
+
* const modes = [{ id: NODE_BUILDER, label: "Build a node", producesArtifacts: true, streamBudgetMs: 600_000, ... }];
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* ★ Throws rather than returning null: this runs once at module load in the
|
|
55
|
+
* product, where a thrown error is a failed build or a red test, not a user-facing
|
|
56
|
+
* crash — and a mode that silently failed to declare would vanish from the panel.
|
|
57
|
+
*
|
|
58
|
+
* ★ A declared mode gets NO authority. It never receives the user's tokens, never
|
|
59
|
+
* runs read-only or write-gated, and runs on the proxy-token artifact image; see
|
|
60
|
+
* `sandboxBaseModeFor` and `forwardsUserTokensToSandbox`. Authority is granted
|
|
61
|
+
* only by being `assistant` or `api-calls`, which is a fe-libs change.
|
|
62
|
+
*
|
|
63
|
+
* @throws when `id` is a built-in mode (use it directly), extends a built-in's
|
|
64
|
+
* name (`general-docs`), or is not a valid id.
|
|
65
|
+
*/
|
|
66
|
+
export declare function declareAssistantMode(id: string): ProductAssistantMode;
|
|
67
|
+
//# sourceMappingURL=modeIds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modeIds.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/modeIds.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,SAAS,CAAC;AAIjB,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;GAMG;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,iCAAiC,QAAoC,CAAC;AAEnF;;;GAGG;AACH,eAAO,MAAM,oCAAoC,KAAK,CAAC;AAEvD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,GACZ,oBAAoB,GAAG,SAAS,CAElC;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,oBAAoB,CAQ/B;AAED,uFAAuF;AACvF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAExE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,oBAAoB,CAkBrE"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ASSISTANT_MODE_IDS as e, isBuiltInAssistantMode as t } from "./modeCopy.js";
|
|
2
|
+
//#region src/shared/assistant/modeIds.ts
|
|
3
|
+
var n = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/, r = 32;
|
|
4
|
+
function i(t) {
|
|
5
|
+
return e.find((e) => t.startsWith(`${e}-`));
|
|
6
|
+
}
|
|
7
|
+
function a(e) {
|
|
8
|
+
return typeof e == "string" && e.length <= 32 && n.test(e) && !t(e) && i(e) === void 0;
|
|
9
|
+
}
|
|
10
|
+
function o(e) {
|
|
11
|
+
return t(e) || a(e);
|
|
12
|
+
}
|
|
13
|
+
function s(e) {
|
|
14
|
+
if (t(e)) throw Error(`declareAssistantMode: ${JSON.stringify(e)} is a built-in mode; use the id directly.`);
|
|
15
|
+
let n = typeof e == "string" ? i(e) : void 0;
|
|
16
|
+
if (n !== void 0) throw Error(`declareAssistantMode: ${JSON.stringify(e)} starts with the built-in mode "${n}-"; its sandboxes would be named like that mode's. Choose an id that does not.`);
|
|
17
|
+
if (!a(e)) throw Error(`declareAssistantMode: ${JSON.stringify(e)} is not a valid mode id (lowercase kebab-case, at most 32 characters).`);
|
|
18
|
+
return e;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { r as PRODUCT_ASSISTANT_MODE_ID_MAX_LENGTH, n as PRODUCT_ASSISTANT_MODE_ID_PATTERN, i as builtInModeExtendedBy, s as declareAssistantMode, o as isAssistantModeId, a as isProductAssistantModeId };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantPreviewOverlay.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/preview/AssistantPreviewOverlay.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAA6B,KAAK,EAAE,EAAkB,MAAM,OAAO,CAAC;AA2E3E,eAAO,MAAM,uBAAuB,EAAE,EAAE,CAAC;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"AssistantPreviewOverlay.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/preview/AssistantPreviewOverlay.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAA6B,KAAK,EAAE,EAAkB,MAAM,OAAO,CAAC;AA2E3E,eAAO,MAAM,uBAAuB,EAAE,EAAE,CAAC;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CA4F/D,CAAC"}
|
|
@@ -15,13 +15,50 @@ export declare function getAssistantText(parts: AssistantRawMessage['parts']): s
|
|
|
15
15
|
* the source is protocol-checked. A part we cannot render safely is DROPPED.
|
|
16
16
|
*/
|
|
17
17
|
export declare function getAssistantMedia(parts: AssistantRawMessage['parts']): string[];
|
|
18
|
+
/**
|
|
19
|
+
* One line per tool part: `"<Verb>: <tool>"`, with `" · <description>"` appended
|
|
20
|
+
* when the agent said what it was doing.
|
|
21
|
+
*
|
|
22
|
+
* ★★ APPENDED, not substituted. `parseToolActivity` puts the text after the verb
|
|
23
|
+
* into `step.tool` — which is what the collapsed "Details" row renders and what
|
|
24
|
+
* `step.id` is keyed on — so replacing the tool name with the description would
|
|
25
|
+
* blank the only place the raw tool is visible, and churn the React key (and the
|
|
26
|
+
* preview rail's follow-the-run logic, which tracks steps by id) on every poll
|
|
27
|
+
* where the wording changed.
|
|
28
|
+
*/
|
|
18
29
|
export declare function getToolProgress(parts: AssistantRawMessage['parts']): string[];
|
|
19
30
|
/**
|
|
20
31
|
* Reduce the assistant messages created at/after `sinceMs` into display content +
|
|
21
32
|
* a done flag. Done ⇔ the newest assistant message has `info.time.completed` and
|
|
22
33
|
* carries either text or tool progress.
|
|
23
34
|
*/
|
|
24
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Per-reduction behaviour a MODE may ask for. Every field is optional and every
|
|
37
|
+
* default reproduces today's output byte for byte — this reducer is what every
|
|
38
|
+
* product wrapping the shared transport renders through, so a behaviour change
|
|
39
|
+
* here is a behaviour change for all of them at once.
|
|
40
|
+
*/
|
|
41
|
+
export interface AssistantProgressOptions {
|
|
42
|
+
/**
|
|
43
|
+
* Join this run's narration across ALL of its messages, oldest first, instead
|
|
44
|
+
* of reporting only the newest one (BC1, BOFF-7334).
|
|
45
|
+
*
|
|
46
|
+
* ★★ Why it is opt-in. The agent grows text parts INSIDE one message, so
|
|
47
|
+
* content grows while it stays in message N — and the instant it opens message
|
|
48
|
+
* N+1, everything narrated in messages 1..N disappears on the next poll. A
|
|
49
|
+
* consumer that harvests entity links out of that prose loses every link
|
|
50
|
+
* printed before the current message. But latest-only is what every existing
|
|
51
|
+
* product renders today, so only a mode that asks for accumulation gets it.
|
|
52
|
+
*
|
|
53
|
+
* ★★ It changes what is STORED, not just what is shown: the orchestrator
|
|
54
|
+
* persists this content as the turn's answer, so an accumulating mode keeps a
|
|
55
|
+
* running account of the build rather than a final reply — and that is what
|
|
56
|
+
* Copy, Export and read-aloud will carry. Correct for a mode whose answer IS
|
|
57
|
+
* the build; wrong for a conversational one. Hence per mode, never global.
|
|
58
|
+
*/
|
|
59
|
+
readonly accumulateNarration?: boolean;
|
|
60
|
+
}
|
|
61
|
+
export declare function buildProgress(messages: AssistantRawMessage[], sinceMs: number, options?: AssistantProgressOptions): {
|
|
25
62
|
content: string;
|
|
26
63
|
done: boolean;
|
|
27
64
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/progress.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAA2B,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEpG,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAE3E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,GAAG,MAAM,CAM5E;AA8CD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,GAAG,MAAM,EAAE,CAkB/E;
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/progress.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAA2B,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEpG,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAE3E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,GAAG,MAAM,CAM5E;AA8CD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,GAAG,MAAM,EAAE,CAkB/E;AA0CD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,GAAG,MAAM,EAAE,CAY7E;AAED;;;;GAIG;AACH;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CACxC;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,wBAAwB,GACjC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CA6BpC;AAED,iEAAiE;AACjE,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAItE;AAED,2FAA2F;AAC3F,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CA0BrD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,mBAAmB,EAAE,EAClC,QAAQ,EAAE,mBAAmB,EAAE,GAC9B,mBAAmB,EAAE,CAavB;AAED,2FAA2F;AAC3F,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,mBAAmB,EAAE,GAAG,sBAAsB,EAAE,CAyB7F"}
|
|
@@ -33,37 +33,51 @@ function a(e) {
|
|
|
33
33
|
return t;
|
|
34
34
|
}
|
|
35
35
|
function o(e) {
|
|
36
|
+
return typeof e == "object" && e ? e : void 0;
|
|
37
|
+
}
|
|
38
|
+
function s(e) {
|
|
39
|
+
let t = o(e.state?.input);
|
|
40
|
+
if (!t) return;
|
|
41
|
+
let n = t.description;
|
|
42
|
+
if (typeof n == "string" && n.trim()) return n.trim();
|
|
43
|
+
let r = t.todos;
|
|
44
|
+
if (Array.isArray(r)) {
|
|
45
|
+
let e = o(r.find((e) => o(e)?.status === "in_progress") ?? r[0])?.content;
|
|
46
|
+
if (typeof e == "string" && e.trim()) return e.trim();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function c(e) {
|
|
36
50
|
return (e ?? []).filter((e) => e.type === "tool" && e.tool).map((e) => {
|
|
37
|
-
let t = e.state?.status ?? "running", n = e.tool ?? "tool";
|
|
38
|
-
return t === "completed" ? `Completed: ${
|
|
51
|
+
let t = e.state?.status ?? "running", n = e.tool ?? "tool", r = s(e), i = r ? `${n} · ${r}` : n;
|
|
52
|
+
return t === "completed" ? `Completed: ${i}` : t === "failed" ? `Failed: ${i}` : `Running: ${i}`;
|
|
39
53
|
});
|
|
40
54
|
}
|
|
41
|
-
function
|
|
42
|
-
let
|
|
43
|
-
if (
|
|
55
|
+
function l(n, r, i) {
|
|
56
|
+
let o = n.filter((t) => t.info?.role === "assistant" && e(t) >= r).sort((t, n) => e(t) - e(n));
|
|
57
|
+
if (o.length === 0) return {
|
|
44
58
|
content: "Thinking…",
|
|
45
59
|
done: !1
|
|
46
60
|
};
|
|
47
|
-
let s =
|
|
61
|
+
let s = o[o.length - 1], l = i?.accumulateNarration ? o.map((e) => t(e.parts)).filter(Boolean).join("\n\n") : t(s.parts), u = a(s.parts), d = c(s.parts);
|
|
48
62
|
return {
|
|
49
63
|
content: [
|
|
50
|
-
|
|
51
|
-
...
|
|
52
|
-
...
|
|
64
|
+
l,
|
|
65
|
+
...u,
|
|
66
|
+
...d
|
|
53
67
|
].filter(Boolean).join("\n\n") || "Thinking…",
|
|
54
|
-
done: !!s.info?.time?.completed && (!!
|
|
68
|
+
done: !!s.info?.time?.completed && (!!l || u.length > 0 || d.length > 0)
|
|
55
69
|
};
|
|
56
70
|
}
|
|
57
|
-
function
|
|
71
|
+
function u(e) {
|
|
58
72
|
return e.replace(/(Authorization\s*:\s*Bearer\s+)[^\s\n]+/gi, "$1[REDACTED]").replace(/(X-Workspace-Authorization\s*:\s*Bearer\s+)[^\s\n]+/gi, "$1[REDACTED]").replace(/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9._-]+\.[A-Za-z0-9._-]+\b/g, "[REDACTED_JWT]").replace(/\bsk-ant-[A-Za-z0-9-]+\b/g, "[REDACTED_API_KEY]");
|
|
59
73
|
}
|
|
60
|
-
function
|
|
74
|
+
function d(e) {
|
|
61
75
|
let t = e instanceof Error ? e.message.toLowerCase() : String(e).toLowerCase();
|
|
62
76
|
return t.includes("unable to connect") && t.includes("able to access the url");
|
|
63
77
|
}
|
|
64
|
-
function
|
|
78
|
+
function f(e) {
|
|
65
79
|
let t = e instanceof Error ? e.message.toLowerCase() : String(e).toLowerCase();
|
|
66
|
-
return t.includes("rate limit exceeded") || t.includes("unauthorized") || t.includes("k8s api error 401") ? !1 :
|
|
80
|
+
return t.includes("rate limit exceeded") || t.includes("unauthorized") || t.includes("k8s api error 401") ? !1 : d(e) ? !0 : [
|
|
67
81
|
"sandbox not found",
|
|
68
82
|
"sandbox is not running",
|
|
69
83
|
"sandbox service not available yet",
|
|
@@ -79,7 +93,7 @@ function u(e) {
|
|
|
79
93
|
"proxy error: 503"
|
|
80
94
|
].some((e) => t.includes(e));
|
|
81
95
|
}
|
|
82
|
-
function
|
|
96
|
+
function p(t, n) {
|
|
83
97
|
let r = /* @__PURE__ */ new Map();
|
|
84
98
|
for (let e of t) {
|
|
85
99
|
let t = e.info?.id;
|
|
@@ -91,7 +105,7 @@ function d(t, n) {
|
|
|
91
105
|
}
|
|
92
106
|
return Array.from(r.values()).sort((t, n) => e(t) - e(n));
|
|
93
107
|
}
|
|
94
|
-
function
|
|
108
|
+
function m(n) {
|
|
95
109
|
let r = [];
|
|
96
110
|
for (let i of n) {
|
|
97
111
|
let n = i.info?.role;
|
|
@@ -106,4 +120,4 @@ function f(n) {
|
|
|
106
120
|
return r;
|
|
107
121
|
}
|
|
108
122
|
//#endregion
|
|
109
|
-
export {
|
|
123
|
+
export { l as buildProgress, a as getAssistantMedia, t as getAssistantText, e as getRawMessageCreatedAt, c as getToolProgress, d as isReapedSandboxConnectionError, f as isRecoverable, m as mapSessionToHistory, p as mergeMessagesById, u as sanitize };
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AssistantModeCapabilityConfig } from './modeCapabilities';
|
|
2
|
+
import { AssistantMode, BuiltInAssistantMode } from './types';
|
|
2
3
|
/**
|
|
3
4
|
* How long the client streams progress before it stops polling a turn.
|
|
4
5
|
*
|
|
5
|
-
* Chat replies
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* TTL is auto-extended every 30s during the
|
|
9
|
-
* outlives the sandbox.
|
|
6
|
+
* Chat replies finish in seconds; a build is a multi-step pipeline that runs for
|
|
7
|
+
* minutes, so it gets a much larger budget. Which modes build is a CAPABILITY
|
|
8
|
+
* (`streamBudgetMs` on `AssistantModeConfig`, resolved in `modeCapabilities.ts`),
|
|
9
|
+
* not a list of mode ids. The sandbox TTL is auto-extended every 30s during the
|
|
10
|
+
* poll loop, so a longer budget never outlives the sandbox.
|
|
10
11
|
*
|
|
11
12
|
* ★★ THE BUDGET ELAPSING IS NOT AN ERROR. It used to be, for every mode except
|
|
12
|
-
*
|
|
13
|
+
* the build mode: the poll loop `throw`ew, the catch wrote
|
|
13
14
|
* `Sorry, an error occurred: …` into the assistant message, and that error was
|
|
14
15
|
* PERSISTED — it survived a reload, so the turn was destroyed rather than
|
|
15
16
|
* merely unfinished. Measured in production on 2026-09-12 with a 10.8 KB
|
|
@@ -21,29 +22,28 @@ import { AssistantMode } from './types';
|
|
|
21
22
|
* overwrite the conversation. So the budget elapsing now yields a normal
|
|
22
23
|
* assistant message: whatever content arrived, plus an honest closing note.
|
|
23
24
|
*/
|
|
24
|
-
export declare const STREAM_BUDGET_MS: Record<
|
|
25
|
-
export declare const DEFAULT_STREAM_BUDGET_MS
|
|
25
|
+
export declare const STREAM_BUDGET_MS: Record<BuiltInAssistantMode, number>;
|
|
26
|
+
export declare const DEFAULT_STREAM_BUDGET_MS: number;
|
|
26
27
|
/**
|
|
27
|
-
* Budget for `mode`,
|
|
28
|
+
* Budget for `mode`, with the product's config for it applied.
|
|
28
29
|
*
|
|
29
30
|
* Exported as a function rather than leaving callers to index the record, so a
|
|
30
31
|
* new mode cannot silently get `undefined` and a `NaN` deadline.
|
|
31
32
|
*/
|
|
32
|
-
export declare function streamBudgetMs(mode: AssistantMode): number;
|
|
33
|
+
export declare function streamBudgetMs(mode: AssistantMode, config?: AssistantModeCapabilityConfig | null): number;
|
|
33
34
|
/** i18n key + English fallback for the note closing an unfinished turn. */
|
|
34
35
|
export interface IncompleteTurnNotice {
|
|
35
36
|
key: string;
|
|
36
37
|
fallback: string;
|
|
37
38
|
}
|
|
38
39
|
/**
|
|
39
|
-
*
|
|
40
|
+
* Every note that can close an unfinished turn, whatever the mode.
|
|
40
41
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* raw braces to real users on most of the fleet. The elapsed budget is not worth
|
|
44
|
-
* that risk, and a reader does not need the number to know what to do next.
|
|
42
|
+
* ★ Two keys for any number of modes: the copy is chosen by capability, so a
|
|
43
|
+
* product declaring a new mode adds no notice keys to seed.
|
|
45
44
|
*/
|
|
46
|
-
export declare
|
|
45
|
+
export declare const INCOMPLETE_TURN_NOTICES: readonly IncompleteTurnNotice[];
|
|
46
|
+
export declare function incompleteTurnNotice(mode: AssistantMode, config?: AssistantModeCapabilityConfig | null): IncompleteTurnNotice;
|
|
47
47
|
/**
|
|
48
48
|
* Close an unfinished turn: keep every character the turn did produce, then
|
|
49
49
|
* append the note for `mode`.
|
|
@@ -53,5 +53,5 @@ export declare function incompleteTurnNotice(mode: AssistantMode): IncompleteTur
|
|
|
53
53
|
* silent failure. `translate` is injected rather than taken from a hook so this
|
|
54
54
|
* is testable without a React tree or an i18n provider.
|
|
55
55
|
*/
|
|
56
|
-
export declare function withIncompleteTurnNotice(content: string, mode: AssistantMode, translate: (key: string, fallback: string) => string): string;
|
|
56
|
+
export declare function withIncompleteTurnNotice(content: string, mode: AssistantMode, translate: (key: string, fallback: string) => string, config?: AssistantModeCapabilityConfig | null): string;
|
|
57
57
|
//# sourceMappingURL=streamBudget.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streamBudget.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/streamBudget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"streamBudget.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/streamBudget.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,6BAA6B,EACnC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,oBAAoB,EAAE,MAAM,CAKjE,CAAC;AAEF,eAAO,MAAM,wBAAwB,QACQ,CAAC;AAE9C;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,aAAa,EACnB,MAAM,CAAC,EAAE,6BAA6B,GAAG,IAAI,GAC5C,MAAM,CAER;AAED,2EAA2E;AAC3E,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CAClB;AA+BD;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,oBAAoB,EAGlE,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,aAAa,EACnB,MAAM,CAAC,EAAE,6BAA6B,GAAG,IAAI,GAC5C,oBAAoB,CAMtB;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,aAAa,EACnB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,EACpD,MAAM,CAAC,EAAE,6BAA6B,GAAG,IAAI,GAC5C,MAAM,CAWR"}
|