@vectoriox/iox-ui 5.79.0 → 5.81.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/fesm2022/vectoriox-iox-ui-forms-core.mjs +96 -1
- package/fesm2022/vectoriox-iox-ui-forms-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs +7 -0
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-harness-core.mjs +3 -1
- package/fesm2022/vectoriox-iox-ui-harness-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui.mjs +579 -45
- package/fesm2022/vectoriox-iox-ui.mjs.map +1 -1
- package/forms-core/index.d.ts +83 -2
- package/generation-core/index.d.ts +8 -1
- package/harness-core/index.d.ts +6 -2
- package/index.d.ts +204 -17
- package/package.json +1 -1
- package/src/forms-core/public-api.ts +1 -0
- package/src/forms-core/submit-lifecycle.ts +128 -0
- package/src/generation-core/ai-run.ts +9 -0
- package/src/harness-core/generation-view.ts +6 -2
- package/styles/iox-forms.css +15 -0
|
@@ -177,7 +177,10 @@ export function modelCanDo(model: Pick<AiModelEntry, 'capabilities'>, step: AiSt
|
|
|
177
177
|
export enum AiRefusalCode {
|
|
178
178
|
NotInPlan = 'ai.notInPlan',
|
|
179
179
|
OutOfCredits = 'ai.outOfCredits',
|
|
180
|
+
/** A step used more than twice its estimate (a loop), or the build its plan's `aiCreditsPerGeneration`. */
|
|
180
181
|
CapReached = 'ai.capReached',
|
|
182
|
+
/** The build asked for `GENERATION_LIMITS.plans` plans already — build one, change it with a sentence, or start over. */
|
|
183
|
+
PlansUsed = 'ai.plansUsed',
|
|
181
184
|
NotConnected = 'ai.notConnected',
|
|
182
185
|
KeyInvalid = 'ai.keyInvalid',
|
|
183
186
|
PlanUnknown = 'ai.planUnknown',
|
|
@@ -188,6 +191,7 @@ export const AI_REFUSAL_STATUS: Readonly<Record<AiRefusalCode, number>> = {
|
|
|
188
191
|
[AiRefusalCode.NotInPlan]: 403,
|
|
189
192
|
[AiRefusalCode.OutOfCredits]: 402,
|
|
190
193
|
[AiRefusalCode.CapReached]: 402,
|
|
194
|
+
[AiRefusalCode.PlansUsed]: 409,
|
|
191
195
|
[AiRefusalCode.NotConnected]: 409,
|
|
192
196
|
[AiRefusalCode.KeyInvalid]: 409,
|
|
193
197
|
[AiRefusalCode.PlanUnknown]: 503,
|
|
@@ -201,12 +205,15 @@ export enum AiNextKind {
|
|
|
201
205
|
Settings = 'settings',
|
|
202
206
|
/** Try again later, or with less. */
|
|
203
207
|
Retry = 'retry',
|
|
208
|
+
/** Keep the plan there is: build it, or change it with a sentence. */
|
|
209
|
+
KeepPlan = 'keepPlan',
|
|
204
210
|
}
|
|
205
211
|
|
|
206
212
|
export const AI_REFUSAL_NEXT: Readonly<Record<AiRefusalCode, AiNextKind>> = {
|
|
207
213
|
[AiRefusalCode.NotInPlan]: AiNextKind.Contact,
|
|
208
214
|
[AiRefusalCode.OutOfCredits]: AiNextKind.Contact,
|
|
209
215
|
[AiRefusalCode.CapReached]: AiNextKind.Retry,
|
|
216
|
+
[AiRefusalCode.PlansUsed]: AiNextKind.KeepPlan,
|
|
210
217
|
[AiRefusalCode.NotConnected]: AiNextKind.Settings,
|
|
211
218
|
[AiRefusalCode.KeyInvalid]: AiNextKind.Settings,
|
|
212
219
|
[AiRefusalCode.PlanUnknown]: AiNextKind.Retry,
|
|
@@ -219,6 +226,8 @@ export interface AiRefusal {
|
|
|
219
226
|
remaining?: number;
|
|
220
227
|
/** What the refused call would have cost, about. */
|
|
221
228
|
estimate?: number;
|
|
229
|
+
/** `PlansUsed`: how many plans one build may ask for. */
|
|
230
|
+
plans?: number;
|
|
222
231
|
next: { kind: AiNextKind; href?: string };
|
|
223
232
|
}
|
|
224
233
|
|
|
@@ -95,7 +95,9 @@ export interface AiGenerationView {
|
|
|
95
95
|
siteBuildId?: string;
|
|
96
96
|
models: Partial<Record<`${AiStep}`, string>>;
|
|
97
97
|
estimate: number;
|
|
98
|
-
|
|
98
|
+
/** The plan's `aiCreditsPerGeneration` for the whole build, or null when it sets none (a step's own ceiling is
|
|
99
|
+
* twice that step's estimate — going back and planning again starts a new step). */
|
|
100
|
+
cap: number | null;
|
|
99
101
|
/** Derived from the ledger — the running credit total. */
|
|
100
102
|
spent: number;
|
|
101
103
|
error?: { code: string; detail: string; providerMessage?: string; issues?: Array<{ code: string; path: string }> };
|
|
@@ -108,10 +110,12 @@ export interface GenerationStartRequest {
|
|
|
108
110
|
addresses?: string[];
|
|
109
111
|
}
|
|
110
112
|
|
|
111
|
-
/** The longest message, the most files and addresses a generation starts from (Start's limits)
|
|
113
|
+
/** The longest message, the most files and addresses a generation starts from (Start's limits), and how many plans
|
|
114
|
+
* one build may ask for (a Design pick, a Try again or "Build with these" each asks one). */
|
|
112
115
|
export const GENERATION_LIMITS = {
|
|
113
116
|
promptChars: 4_000,
|
|
114
117
|
files: 12,
|
|
115
118
|
addresses: 3,
|
|
116
119
|
sentenceChars: 500,
|
|
120
|
+
plans: 5,
|
|
117
121
|
} as const;
|
package/styles/iox-forms.css
CHANGED
|
@@ -49,6 +49,21 @@
|
|
|
49
49
|
.iox-field__error { margin: 4px 0 0; }
|
|
50
50
|
.iox-submit { font: inherit; border: none; cursor: pointer; }
|
|
51
51
|
|
|
52
|
+
/* The submit button follows its FORM's state (vectoriox/iox-ui#42). Its two labels (forms-core
|
|
53
|
+
submitButtonLabelsHtml / IoxSubmitButtonComponent) share one grid cell, so the button keeps the longer one's
|
|
54
|
+
width and never jumps; the form's data-iox-state picks the one that shows — the canvas's Sending state, the
|
|
55
|
+
component path and the string path alike. `visibility` (not display) keeps the hidden one out of the
|
|
56
|
+
accessible name. Busy and disabled are written by syncSubmitButtons. */
|
|
57
|
+
.iox-submit__labels { display: inline-grid; }
|
|
58
|
+
.iox-submit__labels > * { grid-area: 1 / 1; }
|
|
59
|
+
.iox-form:not([data-iox-state="submitting"]) .iox-submit__busy,
|
|
60
|
+
.iox-form[data-iox-state="submitting"] .iox-submit__idle { visibility: hidden; }
|
|
61
|
+
.iox-submit[aria-busy="true"] { cursor: progress; }
|
|
62
|
+
|
|
63
|
+
/* The honeypot and the failure announcer (forms-core `formChromeHtml`, IoxFormComponent's template): off-screen
|
|
64
|
+
rather than display:none — some bots skip hidden inputs, and a live region must stay in the tree. */
|
|
65
|
+
.iox-form__hp { position: absolute; inset-inline-start: -9999px; width: 1px; height: 1px; overflow: hidden; }
|
|
66
|
+
|
|
52
67
|
/* Visually hidden, still announced — a label may be hidden, never deleted. */
|
|
53
68
|
.iox-field__label--hidden {
|
|
54
69
|
position: absolute; width: 1px; height: 1px; margin: -1px;
|