@vectoriox/iox-ui 5.61.0 → 5.62.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-generation-core.mjs +464 -274
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs.map +1 -1
- package/generation-core/index.d.ts +181 -99
- package/package.json +1 -1
- package/src/generation-core/ai-run.ts +40 -3
- package/src/generation-core/plan-edits.ts +128 -47
- package/src/generation-core/plan-wire.ts +148 -62
- package/src/generation-core/strict-schema.ts +32 -7
|
@@ -5724,6 +5724,122 @@ interface BuildStepFacts {
|
|
|
5724
5724
|
}
|
|
5725
5725
|
declare function buildStepFacts(plan: SitePlan, actions?: Readonly<Record<string, `${ContentTypeAction}`>>): BuildStepFacts;
|
|
5726
5726
|
|
|
5727
|
+
/**
|
|
5728
|
+
* The plan WIRE (AI plan M1-3, vectoriox/iox-cms#45, #47): what a model writes when it plans a site — a compact format
|
|
5729
|
+
* inside the Claude API's structured-output limits (≤ 24 optional parameters and ≤ 16 unions per request, and a compiled
|
|
5730
|
+
* grammar under the size Claude refuses — measured as ≤ 60 properties; `strict-schema.ts`). The Site Plan itself
|
|
5731
|
+
* (`SPEC_SITE_PLAN_SHAPE`) has 213 optional keys once every pattern is a branch, so the model never writes it: it writes
|
|
5732
|
+
* this, and ONE pure `expandPlanWire` turns it into the Site Plan that `validateSitePlan` and the stage's gate judge
|
|
5733
|
+
* exactly as before.
|
|
5734
|
+
*
|
|
5735
|
+
* - **Written in two PARTS, one request each** (#47 — the whole plan in one format was 64 properties): the **structure** (the business,
|
|
5736
|
+
* the content types, the data sources) and then the **pages** (the pages, the header and footer), written knowing the
|
|
5737
|
+
* structure. Every top-level key belongs to exactly one part (`part` below); `expandPlanWire` puts the parts together.
|
|
5738
|
+
*
|
|
5739
|
+
* - **Every key required.** A plan key that may be absent is written with its stated "none" — `''`, `0`, `false`, `[]`.
|
|
5740
|
+
* - **Closed lists as enums** (patterns, page types, needs, slots, parts, forms, entrances, header/footer), from the
|
|
5741
|
+
* contract — never per-pattern branches: the gate refuses a slot or a part the chosen pattern does not have, with its path.
|
|
5742
|
+
* - **Maps as lists:** slots `[{ slot, text }]`, links `[{ slot, route }]`, seed values `[{ field, value }]`, roles `[{ role, field }]`.
|
|
5743
|
+
* - **One data source object** for both kinds; `type` says which keys are read (the other kind's hold their none).
|
|
5744
|
+
* - **What the model does not decide is not on the wire** (`PLAN_WIRE_DERIVED`): the look (the owner's pick), the run,
|
|
5745
|
+
* the language (the reading's), the facts (the owner's own, verbatim), the version, the home page (the page at `/`).
|
|
5746
|
+
* So the format is the same for every studio and every run — one compiled grammar, cached by the provider.
|
|
5747
|
+
*
|
|
5748
|
+
* ONE source: every wire key names the plan keys it carries (`refs`) and is described in the plan table's own words, and
|
|
5749
|
+
* every plan key is either carried or derived (`planWireGaps()`); a key the plan shape gains breaks the builder until it
|
|
5750
|
+
* is placed. The expanders translate, never repair: a value the model got wrong stays wrong, for the gate to refuse.
|
|
5751
|
+
*/
|
|
5752
|
+
/** The plan's parts, in the order they are written: the pages bind to the structure's sources and types. */
|
|
5753
|
+
declare enum PlanPart {
|
|
5754
|
+
Structure = "structure",
|
|
5755
|
+
Pages = "pages"
|
|
5756
|
+
}
|
|
5757
|
+
declare const PLAN_PARTS: ReadonlyArray<PlanPart>;
|
|
5758
|
+
/** Each part's format name (a request names the format it asks for). */
|
|
5759
|
+
declare const PLAN_WIRE_PART_SCHEMA_NAMES: Readonly<Record<PlanPart, string>>;
|
|
5760
|
+
declare enum PlanWireEntry {
|
|
5761
|
+
Plan = "plan",
|
|
5762
|
+
Business = "business",
|
|
5763
|
+
ContentType = "contentType",
|
|
5764
|
+
RoleField = "roleField",
|
|
5765
|
+
Field = "field",
|
|
5766
|
+
Seed = "seed",
|
|
5767
|
+
SeedValue = "seedValue",
|
|
5768
|
+
DataSource = "dataSource",
|
|
5769
|
+
Page = "page",
|
|
5770
|
+
PageSeo = "pageSeo",
|
|
5771
|
+
Section = "section",
|
|
5772
|
+
SlotText = "slotText",
|
|
5773
|
+
SlotLink = "slotLink",
|
|
5774
|
+
Globals = "globals"
|
|
5775
|
+
}
|
|
5776
|
+
/** The plan keys the model does not write, and where the expander takes each from. */
|
|
5777
|
+
declare const PLAN_WIRE_DERIVED: Readonly<Record<string, string>>;
|
|
5778
|
+
/** The wire's shape table, in the plan table's words — what the model reads, and what the format is built from. */
|
|
5779
|
+
declare const PLAN_WIRE_SHAPE: Readonly<Record<`${PlanWireEntry}`, ShapeEntry>>;
|
|
5780
|
+
/** Each part's top-level keys, from the ONE wire table. */
|
|
5781
|
+
declare const PLAN_PART_KEYS: Readonly<Record<PlanPart, ReadonlyArray<string>>>;
|
|
5782
|
+
/**
|
|
5783
|
+
* The part a plan path is the answer of (`contentTypes[1].seed.title` → structure, `pages[0].sections[2]` → pages). A
|
|
5784
|
+
* path no part writes — the root (the composer), or a key the generation decides — is the LAST part's: it is written
|
|
5785
|
+
* knowing everything before it.
|
|
5786
|
+
*/
|
|
5787
|
+
declare function planPartOfPath(path: string): PlanPart;
|
|
5788
|
+
/** Plan keys neither carried by a wire key nor derived — always empty (a spec and the builder hold it). */
|
|
5789
|
+
declare function planWireGaps(): string[];
|
|
5790
|
+
declare class PlanWireShapeError extends Error {
|
|
5791
|
+
}
|
|
5792
|
+
/** The patterns a page section may use (every non-global one), in library order. */
|
|
5793
|
+
declare function sectionPatternIds(): string[];
|
|
5794
|
+
declare function wireFieldJsonSchema(): JsonSchema;
|
|
5795
|
+
/** What an object of the wire travels without when its children are written as their own entries (a plan edit's). */
|
|
5796
|
+
interface WireOptions {
|
|
5797
|
+
/** false: a content type without its `fields`, a page without its `sections` (each added by an edit after it). */
|
|
5798
|
+
children?: boolean;
|
|
5799
|
+
}
|
|
5800
|
+
declare function wireContentTypeJsonSchema(options?: WireOptions): JsonSchema;
|
|
5801
|
+
declare function wireDataSourceJsonSchema(): JsonSchema;
|
|
5802
|
+
declare function wireSectionJsonSchema(): JsonSchema;
|
|
5803
|
+
declare function wirePageJsonSchema(options?: WireOptions): JsonSchema;
|
|
5804
|
+
/** The plan's top-level shape for one part (its keys only) — what that part's request shows and is built from. */
|
|
5805
|
+
declare function planWirePartShape(part: PlanPart): ShapeEntry;
|
|
5806
|
+
/**
|
|
5807
|
+
* The format a model writes one part of a plan in — one request each (vectoriox/iox-cms#47). The same for every studio
|
|
5808
|
+
* and run: nothing in it is pinned, so the provider compiles each part's grammar once.
|
|
5809
|
+
*/
|
|
5810
|
+
declare function planWirePartJsonSchema(part: PlanPart): JsonSchema;
|
|
5811
|
+
/** What the plan takes from the generation, not from the model. */
|
|
5812
|
+
interface PlanWireContext {
|
|
5813
|
+
design: DesignChoices;
|
|
5814
|
+
source: SitePlanSource;
|
|
5815
|
+
/** The owner's own facts (the analysis's, as corrected), verbatim. */
|
|
5816
|
+
facts?: Readonly<Partial<Record<FactKey, string>>>;
|
|
5817
|
+
locale?: `${SiteLocale}`;
|
|
5818
|
+
}
|
|
5819
|
+
declare function expandWireField(wire: unknown): ContentFieldPlan | unknown;
|
|
5820
|
+
declare function expandWireContentType(wire: unknown, options?: WireOptions): ContentTypePlan | unknown;
|
|
5821
|
+
declare function expandWireDataSource(wire: unknown): DataSourcePlan | unknown;
|
|
5822
|
+
declare function expandWireSection(wire: unknown): PageSectionPlan | unknown;
|
|
5823
|
+
declare function expandWirePage(wire: unknown, options?: WireOptions): PagePlan | unknown;
|
|
5824
|
+
/** A plan on the wire, by part — what each request answered. A part not written yet is absent. */
|
|
5825
|
+
type PlanWireParts = Partial<Record<PlanPart, unknown>>;
|
|
5826
|
+
/**
|
|
5827
|
+
* A model's plan (its parts, on the wire) + what the generation decides (the look, the run, the language, the owner's
|
|
5828
|
+
* facts) → the Site Plan. Pure. Translates, never repairs: whatever an answer got wrong is still wrong, for
|
|
5829
|
+
* `validateSitePlan` — a part that is not an object is the result itself, a part not written yet leaves its keys out
|
|
5830
|
+
* (the validator then names them, at their own paths).
|
|
5831
|
+
*/
|
|
5832
|
+
declare function expandPlanWire(parts: PlanWireParts, context: PlanWireContext): SitePlan | unknown;
|
|
5833
|
+
declare function fieldToWire(field: ContentFieldPlan): PlainObject;
|
|
5834
|
+
declare function contentTypeToWire(type: ContentTypePlan, options?: WireOptions): PlainObject;
|
|
5835
|
+
declare function dataSourceToWire(source: DataSourcePlan): PlainObject;
|
|
5836
|
+
declare function sectionToWire(section: PageSectionPlan): PlainObject;
|
|
5837
|
+
declare function pageToWire(page: PagePlan, options?: WireOptions): PlainObject;
|
|
5838
|
+
/** One part of the plan on the wire: what that part's request would have answered. */
|
|
5839
|
+
declare function planPartToWire(plan: SitePlan, part: PlanPart): PlainObject;
|
|
5840
|
+
/** The plan → the wire, by part: what a model would have written (the change prompt shows it; fakes and evals write it). */
|
|
5841
|
+
declare function planToWire(plan: SitePlan): Record<PlanPart, PlainObject>;
|
|
5842
|
+
|
|
5727
5843
|
/**
|
|
5728
5844
|
* The AI pipeline's WIRE vocabulary (AI plan §3c, §3n, M0): what iox-cms's `ai` API answers and what every client
|
|
5729
5845
|
* of it reads — the steps a model works on, who pays (IOX credits or the studio's own key), a model of the vetted
|
|
@@ -5760,7 +5876,18 @@ declare enum AiCapability {
|
|
|
5760
5876
|
ImageOutput = "imageOutput"
|
|
5761
5877
|
}
|
|
5762
5878
|
declare const AI_STEP_NEEDS: Readonly<Record<AiStep, ReadonlyArray<AiCapability>>>;
|
|
5763
|
-
/**
|
|
5879
|
+
/**
|
|
5880
|
+
* The steps a model answers in the plan's parts, one request per part (vectoriox/iox-cms#47 — the whole plan's format
|
|
5881
|
+
* compiles to a grammar Claude refuses), and the tokens a typical request of each part reads and writes. Each part reads
|
|
5882
|
+
* the same instructions; the pages read the structure too and write most of the words.
|
|
5883
|
+
*/
|
|
5884
|
+
declare const AI_STEP_PART_TOKENS: Readonly<Partial<Record<AiStep, Readonly<Record<PlanPart, AiTokenCounts>>>>>;
|
|
5885
|
+
/** The parts a step is asked in, in order — none for a step asked in one request. */
|
|
5886
|
+
declare function aiStepParts(step: AiStep): ReadonlyArray<PlanPart>;
|
|
5887
|
+
/**
|
|
5888
|
+
* Tokens a typical use of a step reads and writes (plan §3d "Where credits go") — what a shown estimate is made of. A
|
|
5889
|
+
* step asked in parts is every part's request together, so the estimate (and a generation's start gate) counts them all.
|
|
5890
|
+
*/
|
|
5764
5891
|
declare const AI_STEP_TYPICAL_TOKENS: Readonly<Record<AiStep, AiTokenCounts>>;
|
|
5765
5892
|
/** Tokens by the class a provider prices them in. */
|
|
5766
5893
|
interface AiTokenCounts {
|
|
@@ -5806,6 +5933,8 @@ declare const NO_TOKENS: Readonly<AiTokenCounts>;
|
|
|
5806
5933
|
declare function costUsd(tokens: AiTokenCounts, price: AiTokenPrice): number;
|
|
5807
5934
|
/** Dollars → credits, kept to a millionth of a credit (a short read costs a fraction of one). */
|
|
5808
5935
|
declare function creditsOfUsd(usd: number): number;
|
|
5936
|
+
/** What a typical request of `step` reads and writes — one part's when the step is asked in parts, else the whole step's. */
|
|
5937
|
+
declare function typicalStepTokens(step: AiStep, part?: PlanPart): AiTokenCounts;
|
|
5809
5938
|
/** The credits a typical use of `step` costs on a model of `price` — never typed, always computed (§3d). */
|
|
5810
5939
|
declare function estimateStepCredits(step: AiStep, price: AiTokenPrice, tokens?: AiTokenCounts): number;
|
|
5811
5940
|
/** Can `model` do `step`? The step's needs against the model's capabilities. */
|
|
@@ -5896,86 +6025,6 @@ declare enum AiCallStatus {
|
|
|
5896
6025
|
Interrupted = "interrupted"
|
|
5897
6026
|
}
|
|
5898
6027
|
|
|
5899
|
-
/**
|
|
5900
|
-
* The plan WIRE (AI plan M1-3, vectoriox/iox-cms#45): what a model writes when it plans a site — a compact format inside
|
|
5901
|
-
* the Claude API's structured-output limits (≤ 24 optional parameters and ≤ 16 unions per request; `strict-schema.ts`).
|
|
5902
|
-
* The Site Plan itself (`SPEC_SITE_PLAN_SHAPE`) has 213 optional keys once every pattern is a branch, so the model never
|
|
5903
|
-
* writes it: it writes this, and ONE pure `expandPlanWire` turns it into the Site Plan that `validateSitePlan` and the
|
|
5904
|
-
* stage's gate judge exactly as before.
|
|
5905
|
-
*
|
|
5906
|
-
* - **Every key required.** A plan key that may be absent is written with its stated "none" — `''`, `0`, `false`, `[]`.
|
|
5907
|
-
* - **Closed lists as enums** (patterns, page types, needs, slots, parts, forms, entrances, header/footer), from the
|
|
5908
|
-
* contract — never per-pattern branches: the gate refuses a slot or a part the chosen pattern does not have, with its path.
|
|
5909
|
-
* - **Maps as lists:** slots `[{ slot, text }]`, links `[{ slot, route }]`, seed values `[{ field, value }]`, roles fixed.
|
|
5910
|
-
* - **One data source object** for both kinds; `type` says which keys are read (the other kind's hold their none).
|
|
5911
|
-
* - **What the model does not decide is not on the wire** (`PLAN_WIRE_DERIVED`): the look (the owner's pick), the run,
|
|
5912
|
-
* the language (the reading's), the facts (the owner's own, verbatim), the version, the home page (the page at `/`).
|
|
5913
|
-
* So the format is the same for every studio and every run — one compiled grammar, cached by the provider.
|
|
5914
|
-
*
|
|
5915
|
-
* ONE source: every wire key names the plan keys it carries (`refs`) and is described in the plan table's own words, and
|
|
5916
|
-
* every plan key is either carried or derived (`planWireGaps()`); a key the plan shape gains breaks the builder until it
|
|
5917
|
-
* is placed. The expanders translate, never repair: a value the model got wrong stays wrong, for the gate to refuse.
|
|
5918
|
-
*/
|
|
5919
|
-
declare const PLAN_WIRE_SCHEMA_NAME = "site_plan";
|
|
5920
|
-
declare enum PlanWireEntry {
|
|
5921
|
-
Plan = "plan",
|
|
5922
|
-
Business = "business",
|
|
5923
|
-
ContentType = "contentType",
|
|
5924
|
-
Roles = "roles",
|
|
5925
|
-
Field = "field",
|
|
5926
|
-
Seed = "seed",
|
|
5927
|
-
SeedValue = "seedValue",
|
|
5928
|
-
DataSource = "dataSource",
|
|
5929
|
-
Page = "page",
|
|
5930
|
-
PageSeo = "pageSeo",
|
|
5931
|
-
Section = "section",
|
|
5932
|
-
SlotText = "slotText",
|
|
5933
|
-
SlotLink = "slotLink",
|
|
5934
|
-
Globals = "globals"
|
|
5935
|
-
}
|
|
5936
|
-
/** The plan keys the model does not write, and where the expander takes each from. */
|
|
5937
|
-
declare const PLAN_WIRE_DERIVED: Readonly<Record<string, string>>;
|
|
5938
|
-
/** The wire's shape table, in the plan table's words — what the model reads, and what the format is built from. */
|
|
5939
|
-
declare const PLAN_WIRE_SHAPE: Readonly<Record<`${PlanWireEntry}`, ShapeEntry>>;
|
|
5940
|
-
/** Plan keys neither carried by a wire key nor derived — always empty (a spec and the builder hold it). */
|
|
5941
|
-
declare function planWireGaps(): string[];
|
|
5942
|
-
declare class PlanWireShapeError extends Error {
|
|
5943
|
-
}
|
|
5944
|
-
/** The patterns a page section may use (every non-global one), in library order. */
|
|
5945
|
-
declare function sectionPatternIds(): string[];
|
|
5946
|
-
declare function wireFieldJsonSchema(): JsonSchema;
|
|
5947
|
-
declare function wireContentTypeJsonSchema(): JsonSchema;
|
|
5948
|
-
declare function wireDataSourceJsonSchema(): JsonSchema;
|
|
5949
|
-
declare function wireSectionJsonSchema(): JsonSchema;
|
|
5950
|
-
declare function wirePageJsonSchema(): JsonSchema;
|
|
5951
|
-
/** The format a model writes a plan in. The same for every studio and run: nothing in it is pinned. */
|
|
5952
|
-
declare function planWireJsonSchema(): JsonSchema;
|
|
5953
|
-
/** What the plan takes from the generation, not from the model. */
|
|
5954
|
-
interface PlanWireContext {
|
|
5955
|
-
design: DesignChoices;
|
|
5956
|
-
source: SitePlanSource;
|
|
5957
|
-
/** The owner's own facts (the analysis's, as corrected), verbatim. */
|
|
5958
|
-
facts?: Readonly<Partial<Record<FactKey, string>>>;
|
|
5959
|
-
locale?: `${SiteLocale}`;
|
|
5960
|
-
}
|
|
5961
|
-
declare function expandWireField(wire: unknown): ContentFieldPlan | unknown;
|
|
5962
|
-
declare function expandWireContentType(wire: unknown): ContentTypePlan | unknown;
|
|
5963
|
-
declare function expandWireDataSource(wire: unknown): DataSourcePlan | unknown;
|
|
5964
|
-
declare function expandWireSection(wire: unknown): PageSectionPlan | unknown;
|
|
5965
|
-
declare function expandWirePage(wire: unknown): PagePlan | unknown;
|
|
5966
|
-
/**
|
|
5967
|
-
* A model's plan (the wire) + what the generation decides (the look, the run, the language, the owner's facts) → the
|
|
5968
|
-
* Site Plan. Pure. Translates, never repairs: whatever the answer got wrong is still wrong, for `validateSitePlan`.
|
|
5969
|
-
*/
|
|
5970
|
-
declare function expandPlanWire(wire: unknown, context: PlanWireContext): SitePlan | unknown;
|
|
5971
|
-
declare function fieldToWire(field: ContentFieldPlan): PlainObject;
|
|
5972
|
-
declare function contentTypeToWire(type: ContentTypePlan): PlainObject;
|
|
5973
|
-
declare function dataSourceToWire(source: DataSourcePlan): PlainObject;
|
|
5974
|
-
declare function sectionToWire(section: PageSectionPlan): PlainObject;
|
|
5975
|
-
declare function pageToWire(page: PagePlan): PlainObject;
|
|
5976
|
-
/** The plan → the wire: what a model would have written (the plan edits' prompt shows it; fakes and evals write it). */
|
|
5977
|
-
declare function planToWire(plan: SitePlan): PlainObject;
|
|
5978
|
-
|
|
5979
6028
|
/**
|
|
5980
6029
|
* What a structured-output request costs the provider's grammar compiler, counted the way the Claude API counts it
|
|
5981
6030
|
* (platform.claude.com/docs/en/build-with-claude/structured-outputs, "Schema complexity limits", read 2026-10-27):
|
|
@@ -5985,16 +6034,27 @@ declare function planToWire(plan: SitePlan): PlainObject;
|
|
|
5985
6034
|
* The limits are per REQUEST — every strict schema in it together. The ONE counter: the specs hold every schema iox-cms
|
|
5986
6035
|
* sends to it, and the fake Claude API refuses with it exactly as Claude does — the plan stage once sent 213 optional
|
|
5987
6036
|
* parameters and every suite stayed green because the fake accepted anything (vectoriox/iox-cms#45).
|
|
6037
|
+
*
|
|
6038
|
+
* Beyond those, Claude refuses a grammar it compiles too large — a limit the docs name ("additional internal limits on
|
|
6039
|
+
* the compiled grammar size") without a number. MEASURED against the API on 2026-10-27 (vectoriox/iox-cms#47): the
|
|
6040
|
+
* total number of properties decides it, not enums or descriptions — 64 and 61 properties refused, 53 and fewer
|
|
6041
|
+
* accepted (53 already took ~9 s to compile). So 60 is the line we refuse above, and 40 is what we send.
|
|
5988
6042
|
*/
|
|
5989
6043
|
declare const STRICT_SCHEMA_LIMITS: {
|
|
5990
6044
|
readonly strictTools: 20;
|
|
5991
6045
|
readonly optional: 24;
|
|
5992
6046
|
readonly unions: 16;
|
|
6047
|
+
/** MEASURED, not documented (2026-10-27): the smallest refused request held 61 properties, the largest accepted 53. */
|
|
6048
|
+
readonly properties: 60;
|
|
5993
6049
|
};
|
|
5994
|
-
/**
|
|
6050
|
+
/**
|
|
6051
|
+
* What one request iox-cms sends may use: half of each documented limit, so a step can gain a field (or a strict tool)
|
|
6052
|
+
* without a 400 — and 40 properties, a third under the measured grammar line, where compiling stays a few seconds.
|
|
6053
|
+
*/
|
|
5995
6054
|
declare const STRICT_SCHEMA_BUDGET: {
|
|
5996
6055
|
readonly optional: 12;
|
|
5997
6056
|
readonly unions: 8;
|
|
6057
|
+
readonly properties: 40;
|
|
5998
6058
|
};
|
|
5999
6059
|
interface StrictSchemaComplexity {
|
|
6000
6060
|
/** Properties not listed in their object's `required`, every object of every schema. */
|
|
@@ -6003,6 +6063,10 @@ interface StrictSchemaComplexity {
|
|
|
6003
6063
|
unions: number;
|
|
6004
6064
|
/** Tools with `strict: true` (a JSON output format is not a tool). */
|
|
6005
6065
|
strictTools: number;
|
|
6066
|
+
/** Every key of every object's `properties`, at every depth — what the compiled grammar's size follows. */
|
|
6067
|
+
properties: number;
|
|
6068
|
+
/** Objects that declare `properties`. */
|
|
6069
|
+
objects: number;
|
|
6006
6070
|
/** What the strict mode does not support, each with its path (`pages.items.properties.route: minLength`). */
|
|
6007
6071
|
unsupported: string[];
|
|
6008
6072
|
}
|
|
@@ -6014,10 +6078,13 @@ interface StrictSchemaRefusal {
|
|
|
6014
6078
|
type: 'invalid_request_error';
|
|
6015
6079
|
message: string;
|
|
6016
6080
|
}
|
|
6081
|
+
/** Claude's words for a grammar it compiles too large (2026-10-27, the plan stage — vectoriox/iox-cms#47), verbatim. */
|
|
6082
|
+
declare const GRAMMAR_TOO_LARGE_MESSAGE = "The compiled grammar is too large, which would cause performance issues. Simplify your tool schemas or reduce the number of strict tools.";
|
|
6017
6083
|
/**
|
|
6018
|
-
* The 400 the Claude API answers a request over its limits with, or null. The optional-parameter
|
|
6019
|
-
* Claude answered on 2026-10-27, verbatim; the union, strict-tool and unsupported messages follow
|
|
6020
|
-
* captured).
|
|
6084
|
+
* The 400 the Claude API answers a request over its limits with, or null. The optional-parameter and the grammar-size
|
|
6085
|
+
* messages are the ones Claude answered on 2026-10-27, verbatim; the union, strict-tool and unsupported messages follow
|
|
6086
|
+
* their shape (not yet captured). The documented limits are checked first: a request over one of them never reaches the
|
|
6087
|
+
* grammar compiler.
|
|
6021
6088
|
*/
|
|
6022
6089
|
declare function strictSchemaRefusal(complexity: StrictSchemaComplexity): StrictSchemaRefusal | null;
|
|
6023
6090
|
|
|
@@ -6109,6 +6176,13 @@ type PlanEdit = {
|
|
|
6109
6176
|
* A page is named by its `key`; a section by its 0-based `index` on that page.
|
|
6110
6177
|
*/
|
|
6111
6178
|
declare const PLAN_EDIT_SHAPE: Readonly<Record<`${PlanEditOp}`, ShapeEntry>>;
|
|
6179
|
+
/**
|
|
6180
|
+
* The plan part each op changes (vectoriox/iox-cms#47): a sentence is answered in the plan's two parts, one request each —
|
|
6181
|
+
* the structure's edits first, then the pages' written knowing them.
|
|
6182
|
+
*/
|
|
6183
|
+
declare const PLAN_EDIT_OP_PART: Readonly<Record<`${PlanEditOp}`, PlanPart>>;
|
|
6184
|
+
/** The ops written in one part, in `PlanEditOp` order. */
|
|
6185
|
+
declare function planEditOps(part: PlanPart): PlanEditOp[];
|
|
6112
6186
|
declare enum PlanChangeKind {
|
|
6113
6187
|
Page = "page",
|
|
6114
6188
|
Section = "section",
|
|
@@ -6164,7 +6238,8 @@ declare function validatePlanEdits(edits: unknown): {
|
|
|
6164
6238
|
* The result still has to pass `validateSitePlan`.
|
|
6165
6239
|
*/
|
|
6166
6240
|
declare function applyPlanEdits(plan: SitePlan, edits: ReadonlyArray<PlanEdit>): PlanEditResult;
|
|
6167
|
-
|
|
6241
|
+
/** Each part's answer format name. */
|
|
6242
|
+
declare const PLAN_EDITS_PART_SCHEMA_NAMES: Readonly<Record<PlanPart, string>>;
|
|
6168
6243
|
/** A sentence's answer: the edits, or why the ops cannot say it (one line, in the owner's language). */
|
|
6169
6244
|
declare enum PlanEditsOutcome {
|
|
6170
6245
|
Edits = "edits",
|
|
@@ -6176,23 +6251,30 @@ interface PlanEditsAnswer {
|
|
|
6176
6251
|
/** `cannot`: the one line the owner reads. `edits`: empty. */
|
|
6177
6252
|
reason: string;
|
|
6178
6253
|
}
|
|
6179
|
-
/**
|
|
6180
|
-
|
|
6254
|
+
/**
|
|
6255
|
+
* Each part's answer, explained. The structure is asked first, so it says whether the sentence is a plan change at all
|
|
6256
|
+
* (`outcome`); the pages are asked only when it is, and write only their edits.
|
|
6257
|
+
*/
|
|
6258
|
+
declare const PLAN_EDITS_ANSWER_SHAPES: Readonly<Record<PlanPart, ShapeEntry>>;
|
|
6181
6259
|
/** Each op's keys (`PLAN_EDIT_SHAPE`) → the wire key that carries it. */
|
|
6182
6260
|
declare const PLAN_EDIT_WIRE_KEYS: Readonly<Record<`${PlanEditOp}`, Readonly<Record<string, string>>>>;
|
|
6183
|
-
/** The
|
|
6184
|
-
declare
|
|
6185
|
-
/**
|
|
6186
|
-
declare function
|
|
6261
|
+
/** The wire keys a part's edit carries: every key its ops read, in `EDIT_WIRE` order. */
|
|
6262
|
+
declare function planEditWireKeys(part: PlanPart): string[];
|
|
6263
|
+
/** A part's flat edit, as a shape table: every key required, each with its none. */
|
|
6264
|
+
declare function planEditWireShape(part: PlanPart): ShapeEntry;
|
|
6265
|
+
/** Per op of a part, the wire keys it reads, in `PLAN_EDIT_SHAPE`'s words (`?` = may hold its none) — what the model reads. */
|
|
6266
|
+
declare function planEditWireOps(part: PlanPart): Record<string, Record<string, string>>;
|
|
6187
6267
|
/** Op keys no wire key carries, or wire keys that do not exist — always empty (a spec and the builder hold it). */
|
|
6188
6268
|
declare function planEditWireGaps(): string[];
|
|
6189
|
-
/** The format a sentence's answer is written in
|
|
6190
|
-
declare function planEditsJsonSchema(): JsonSchema;
|
|
6269
|
+
/** The format one part of a sentence's answer is written in — one request each (vectoriox/iox-cms#47). */
|
|
6270
|
+
declare function planEditsJsonSchema(part: PlanPart): JsonSchema;
|
|
6191
6271
|
/** One flat edit → the op's edit: the keys it reads, a none left out where the op may go without it. Never repaired. */
|
|
6192
6272
|
declare function expandWireEdit(wire: unknown): PlanEdit | unknown;
|
|
6193
|
-
/** An edit → the flat wire
|
|
6194
|
-
declare function planEditToWire(edit: PlanEdit): PlainObject;
|
|
6195
|
-
/**
|
|
6273
|
+
/** An edit → the flat wire edits a model would write for it: itself, then its children (fakes and specs write them). */
|
|
6274
|
+
declare function planEditToWire(edit: PlanEdit): PlainObject[];
|
|
6275
|
+
/** Edits → each part's flat wire edits, in order (what each part's answer would hold). */
|
|
6276
|
+
declare function planEditsToWire(edits: ReadonlyArray<PlanEdit>): Record<PlanPart, PlainObject[]>;
|
|
6277
|
+
/** A model's answer (either part's) → edits (each flat edit expanded); never repaired. */
|
|
6196
6278
|
declare function planEditsFromWire(answer: unknown): PlanEditsAnswer | unknown;
|
|
6197
6279
|
|
|
6198
6280
|
/**
|
|
@@ -6472,5 +6554,5 @@ declare function stockCreditNode(index: number, credit: StockLink): SerializedNo
|
|
|
6472
6554
|
/** Append the credit lines to the footer root (once each). Returns how many it added. */
|
|
6473
6555
|
declare function addStockCredits(footer: SerializedNode, credits: ReadonlyArray<StockLink>): number;
|
|
6474
6556
|
|
|
6475
|
-
export { ACTIVE_BUILD_STATUSES, AI_REFUSAL_NEXT, AI_REFUSAL_STATUS, AI_STEPS, AI_STEP_LABELS, AI_STEP_NEEDS, AI_STEP_TYPICAL_TOKENS, AiCallStatus, AiCapability, AiFeature, AiGenerationStage, AiKeyMode, AiLimit, AiNextKind, AiProviderId, AiRefusalCode, AiStep, BAR_ITEMS_MAX, BAR_ITEMS_MIN, BASELINE_ROLES, BUILD_STEPS, BaselineRole, BindScope, BuildNoticeCode, BuildStep, CONTENT_ROLE_MEANINGS, CREDITS_PER_USD, CardBindTarget, CheckSeverity, ComposeError, ComposeIssueCode, ContentRole, ContentTypeAction, CreatedKind, DANGLING_LINK_CODES, DEFAULT_PHONE_MENU_BREAKPOINT, DEFAULT_SITE_LOCALE, ENTRANCE_EASING, ENTRANCE_ORIGIN_LOOK, ENTRANCE_TRIGGER, EntrancePart, EntranceSide, FACT_KEYS, FINAL_GENERATION_STAGES, FINDING_SEVERITY, GlobalSlot, HEBREW_PREFIXES, JSON_SCHEMA_BANNED_KEYWORDS, JsonSchemaShapeError, KeptReason, NAV_PART_LABELS, NAV_SHAPE_COPY, NEUTRAL_STYLE_PROPS, NODE_BASELINES, NO_TOKENS, NavPagesSource, NavRole, NavShape, NavShapeError, PAGE_ARCHETYPES,
|
|
6476
|
-
export type { AddBarItemResult, AiEntitlementsView, AiMeter, AiModelEntry, AiRefusal, AiTokenCounts, AiTokenPrice, AuditPage, AuditPlaceholder, BarItemsEditResult, BuildNotice, BuildStepError, BuildStepFacts, BuildStepRecord, CmsDataSourcePlan, ComposeContext, ComposeIssue, ComposedDataSource, ComposedItem, ComposedNavHeader, ComposedPage, ComposedPlaceholder, ComposedRoute, ComposedSection, ComposedSite, ContentFieldPlan, ContentRoles, ContentSeedPlan, ContentTypePlan, CreateNodeOptions, CreatedRecord, DataSourcePlan, DynamicKeysAsList, EntranceAction, EntranceActionOptions, EntranceInteraction, EntranceMark, EntranceSpec, EntranceStamp, FactKey, JsonSchema, NavHeaderInput, NavHeaderOptions, NavPage, NavShapeOptions, NavShapeResult, NodeBaseline, PageArchetype, PageArchetypeId, PageArchetypeSlot, PageData, PageDataLine, PagePlan, PageSectionPlan, PageSeoPlan, PathIssue, PatternManifestEntry, PatternNode, PatternPath, PatternRoleNeed, PlainObject, PlanChange, PlanEdit, PlanEditIssue, PlanEditResult, PlanEditsAnswer, PlanEntrancesInput, PlanWireContext, PlanWordContext, PlanWordIssue, PreflightRefusal, PublishRefusal, RelativeDataSourcePlan, SectionEntrances, SectionInput, SectionOptions, SerializedBinding, SerializedNode, SerializedResponsive, ShapeEntry, ShapeIssueCodes, ShowcaseInput, SiteAudit, SiteAuditOptions, SiteAuditSnapshot, SiteBuildRun, SiteBusiness, SiteCheck, SiteFinding, SiteNeedId, SitePageRef, SitePattern, SitePlan, SitePlanIssue, SitePlanSource, SitePlanValidation, SiteTemplate, StockCredit, StockLink, StockPhoto, StockPlacement, StockProviderTerms, StockSlot, StrictSchemaComplexity, StrictSchemaRefusal, TemplatePlanInput, UndoKept, UndoPreview, UndoRecord, WrittenText };
|
|
6557
|
+
export { ACTIVE_BUILD_STATUSES, AI_REFUSAL_NEXT, AI_REFUSAL_STATUS, AI_STEPS, AI_STEP_LABELS, AI_STEP_NEEDS, AI_STEP_PART_TOKENS, AI_STEP_TYPICAL_TOKENS, AiCallStatus, AiCapability, AiFeature, AiGenerationStage, AiKeyMode, AiLimit, AiNextKind, AiProviderId, AiRefusalCode, AiStep, BAR_ITEMS_MAX, BAR_ITEMS_MIN, BASELINE_ROLES, BUILD_STEPS, BaselineRole, BindScope, BuildNoticeCode, BuildStep, CONTENT_ROLE_MEANINGS, CREDITS_PER_USD, CardBindTarget, CheckSeverity, ComposeError, ComposeIssueCode, ContentRole, ContentTypeAction, CreatedKind, DANGLING_LINK_CODES, DEFAULT_PHONE_MENU_BREAKPOINT, DEFAULT_SITE_LOCALE, ENTRANCE_EASING, ENTRANCE_ORIGIN_LOOK, ENTRANCE_TRIGGER, EntrancePart, EntranceSide, FACT_KEYS, FINAL_GENERATION_STAGES, FINDING_SEVERITY, GRAMMAR_TOO_LARGE_MESSAGE, GlobalSlot, HEBREW_PREFIXES, JSON_SCHEMA_BANNED_KEYWORDS, JsonSchemaShapeError, KeptReason, NAV_PART_LABELS, NAV_SHAPE_COPY, NEUTRAL_STYLE_PROPS, NODE_BASELINES, NO_TOKENS, NavPagesSource, NavRole, NavShape, NavShapeError, PAGE_ARCHETYPES, PLAN_EDITS_ANSWER_SHAPES, PLAN_EDITS_PART_SCHEMA_NAMES, PLAN_EDIT_OP_PART, PLAN_EDIT_SHAPE, PLAN_EDIT_WIRE_KEYS, PLAN_PARTS, PLAN_PART_KEYS, PLAN_WIRE_DERIVED, PLAN_WIRE_PART_SCHEMA_NAMES, PLAN_WIRE_SHAPE, PRICING_PATTERN, PUBLISH_BLOCKING_PLACEHOLDERS, PageDataKind, PathIssueCollector, PatternDirective, PatternGlobalPosition, PatternOpens, PatternPlaceholder, PatternRecipe, PhoneMenuBreakpoint, PlaceholderKind, PlanChangeAction, PlanChangeKind, PlanDataSourceMode, PlanDataSourceType, PlanEditIssueCode, PlanEditOp, PlanEditsOutcome, PlanPart, PlanWireEntry, PlanWireShapeError, PlanWordIssueCode, PreflightRefusalCode, PublishRefusalCode, REQUIRED_CONTENT_ROLES, RelativeOp, SAMPLE_IMAGE_REF, SITE_CHECKS, SITE_FACT_LABELS, SITE_HEADER_PATTERN, SITE_LIBRARY, SITE_LOCALES, SITE_NEED_IDS, SITE_PATTERNS, SITE_PLAN_VERSION, SITE_TEMPLATES, SPEC_SITE_ARCHETYPES, SPEC_SITE_COPY_LENGTHS, SPEC_SITE_DENSITY_COPY, SPEC_SITE_FACTS, SPEC_SITE_LIBRARY, SPEC_SITE_LOCALES, SPEC_SITE_NEED_IDS, SPEC_SITE_PATTERNS, SPEC_SITE_PLAN_SHAPE, SPEC_SITE_REQUIRED_ROLES, SPEC_SITE_ROLES, SPEC_SITE_TEMPLATES, STOCK_FAMILIES, STOCK_PROVIDER_TERMS, STRICT_SCHEMA_BUDGET, STRICT_SCHEMA_LIMITS, STUDIO_TEMPLATE, SiteBuildKind, SiteBuildStatus, SiteCheckId, SiteFindingCode, SiteLocale, SitePlanError, SitePlanIssueCode, SitePlanSourceKind, SiteTemplateError, SiteTemplateId, StepState, StockProviderId, addBarItem, addStockCredits, aiStepParts, applyPlanEdits, applyStockPhotos, archetypeIssues, assertStyleSlots, assertValidSitePlan, auditSite, barIconForRoute, blocksPublish, buildKeys, buildStepFacts, builtHomePageId, composeNavHeader, composeSection, composeSite, contentTypePreviewFields, contentTypeToWire, copyLengthOf, costUsd, createSerializedNode, creditsOfUsd, dataSourceToWire, describePlanData, describeShapeKey, entranceAction, entranceInteraction, estimateStepCredits, expandPlanWire, expandWireContentType, expandWireDataSource, expandWireEdit, expandWireField, expandWirePage, expandWireSection, failedBuildStep, fieldToWire, findNavRoot, isActiveBuild, isNonEmptyString, isPlainObject, isRtlLocale, jsonAnyOf, jsonBoolean, jsonClosedObject, jsonInteger, jsonListOf, jsonOneOf, jsonSchemaKeywords, jsonSchemaObjects, jsonShapedObject, jsonText, modelCanDo, moveBarItem, navPages, navShapeBreakpoint, navShapeOf, nextSourceOf, nodeBindPaths, pageToWire, parsePatternPath, parseSampleImageRef, pathAt, patternById, patternHasForm, patternLinkSlots, patternManifest, patternNeedsBinding, patternNodes, patternOptionalParts, patternRoleNeeds, patternScopes, patternSlotBudgets, patternSlots, patternTakesBinding, phoneMenuPages, planEditOps, planEditToWire, planEditWireGaps, planEditWireKeys, planEditWireOps, planEditWireShape, planEditsFromWire, planEditsJsonSchema, planEditsToWire, planEntrances, planFromTemplate, planNavShape, planPartOfPath, planPartToWire, planStockPhotos, planToWire, planWireGaps, planWirePartJsonSchema, planWirePartShape, planWordIssues, publishRefusal, publishVerdict, releasedLayoutDefaults, removeBarItem, requiredAcknowledgements, requiredShapeKeys, roleField, routeMatches, routeParams, sampleImageRef, sectionEntrances, sectionPatternIds, sectionToWire, setStyleProps, shapeKeys, showcaseGlobals, showcasePages, showcasePlans, siteNavPages, slotBudget, stockCopyKey, stockCreditLine, stockCreditLines, stockCreditNode, stockCreditNodeId, stockSlots, strictSchemaComplexity, strictSchemaRefusal, typicalStepTokens, validatePlanEdits, validateSitePlan, walkSerialized, wireContentTypeJsonSchema, wireDataSourceJsonSchema, wireFieldJsonSchema, wirePageJsonSchema, wireSectionJsonSchema, wordPattern, writtenTexts };
|
|
6558
|
+
export type { AddBarItemResult, AiEntitlementsView, AiMeter, AiModelEntry, AiRefusal, AiTokenCounts, AiTokenPrice, AuditPage, AuditPlaceholder, BarItemsEditResult, BuildNotice, BuildStepError, BuildStepFacts, BuildStepRecord, CmsDataSourcePlan, ComposeContext, ComposeIssue, ComposedDataSource, ComposedItem, ComposedNavHeader, ComposedPage, ComposedPlaceholder, ComposedRoute, ComposedSection, ComposedSite, ContentFieldPlan, ContentRoles, ContentSeedPlan, ContentTypePlan, CreateNodeOptions, CreatedRecord, DataSourcePlan, DynamicKeysAsList, EntranceAction, EntranceActionOptions, EntranceInteraction, EntranceMark, EntranceSpec, EntranceStamp, FactKey, JsonSchema, NavHeaderInput, NavHeaderOptions, NavPage, NavShapeOptions, NavShapeResult, NodeBaseline, PageArchetype, PageArchetypeId, PageArchetypeSlot, PageData, PageDataLine, PagePlan, PageSectionPlan, PageSeoPlan, PathIssue, PatternManifestEntry, PatternNode, PatternPath, PatternRoleNeed, PlainObject, PlanChange, PlanEdit, PlanEditIssue, PlanEditResult, PlanEditsAnswer, PlanEntrancesInput, PlanWireContext, PlanWireParts, PlanWordContext, PlanWordIssue, PreflightRefusal, PublishRefusal, RelativeDataSourcePlan, SectionEntrances, SectionInput, SectionOptions, SerializedBinding, SerializedNode, SerializedResponsive, ShapeEntry, ShapeIssueCodes, ShowcaseInput, SiteAudit, SiteAuditOptions, SiteAuditSnapshot, SiteBuildRun, SiteBusiness, SiteCheck, SiteFinding, SiteNeedId, SitePageRef, SitePattern, SitePlan, SitePlanIssue, SitePlanSource, SitePlanValidation, SiteTemplate, StockCredit, StockLink, StockPhoto, StockPlacement, StockProviderTerms, StockSlot, StrictSchemaComplexity, StrictSchemaRefusal, TemplatePlanInput, UndoKept, UndoPreview, UndoRecord, WireOptions, WrittenText };
|
package/package.json
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { PLAN_PARTS, PlanPart } from './plan-wire';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* The AI pipeline's WIRE vocabulary (AI plan §3c, §3n, M0): what iox-cms's `ai` API answers and what every client
|
|
3
5
|
* of it reads — the steps a model works on, who pays (IOX credits or the studio's own key), a model of the vetted
|
|
@@ -54,11 +56,41 @@ export const AI_STEP_NEEDS: Readonly<Record<AiStep, ReadonlyArray<AiCapability>>
|
|
|
54
56
|
[AiStep.NameStructures]: [AiCapability.StructuredOutput],
|
|
55
57
|
};
|
|
56
58
|
|
|
57
|
-
/**
|
|
59
|
+
/**
|
|
60
|
+
* The steps a model answers in the plan's parts, one request per part (vectoriox/iox-cms#47 — the whole plan's format
|
|
61
|
+
* compiles to a grammar Claude refuses), and the tokens a typical request of each part reads and writes. Each part reads
|
|
62
|
+
* the same instructions; the pages read the structure too and write most of the words.
|
|
63
|
+
*/
|
|
64
|
+
export const AI_STEP_PART_TOKENS: Readonly<Partial<Record<AiStep, Readonly<Record<PlanPart, AiTokenCounts>>>>> = {
|
|
65
|
+
[AiStep.PlanSite]: {
|
|
66
|
+
[PlanPart.Structure]: { input: 10_000, output: 1_500, cacheWrite: 0, cacheRead: 0 },
|
|
67
|
+
[PlanPart.Pages]: { input: 12_000, output: 5_500, cacheWrite: 0, cacheRead: 0 },
|
|
68
|
+
},
|
|
69
|
+
[AiStep.ChangePlan]: {
|
|
70
|
+
[PlanPart.Structure]: { input: 6_000, output: 300, cacheWrite: 0, cacheRead: 0 },
|
|
71
|
+
[PlanPart.Pages]: { input: 6_500, output: 400, cacheWrite: 0, cacheRead: 0 },
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/** The parts a step is asked in, in order — none for a step asked in one request. */
|
|
76
|
+
export function aiStepParts(step: AiStep): ReadonlyArray<PlanPart> {
|
|
77
|
+
return AI_STEP_PART_TOKENS[step] ? PLAN_PARTS : [];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const addTokens = (a: AiTokenCounts, b: AiTokenCounts): AiTokenCounts => ({
|
|
81
|
+
input: a.input + b.input, output: a.output + b.output, cacheWrite: a.cacheWrite + b.cacheWrite, cacheRead: a.cacheRead + b.cacheRead,
|
|
82
|
+
...(a.imageOutput !== undefined || b.imageOutput !== undefined ? { imageOutput: (a.imageOutput ?? 0) + (b.imageOutput ?? 0) } : {}),
|
|
83
|
+
});
|
|
84
|
+
const partsTotal = (step: AiStep): AiTokenCounts => PLAN_PARTS.map(part => AI_STEP_PART_TOKENS[step]![part]).reduce(addTokens);
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Tokens a typical use of a step reads and writes (plan §3d "Where credits go") — what a shown estimate is made of. A
|
|
88
|
+
* step asked in parts is every part's request together, so the estimate (and a generation's start gate) counts them all.
|
|
89
|
+
*/
|
|
58
90
|
export const AI_STEP_TYPICAL_TOKENS: Readonly<Record<AiStep, AiTokenCounts>> = {
|
|
59
91
|
[AiStep.ReadMessage]: { input: 8_800, output: 1_500, cacheWrite: 0, cacheRead: 0 },
|
|
60
|
-
[AiStep.PlanSite]:
|
|
61
|
-
[AiStep.ChangePlan]:
|
|
92
|
+
[AiStep.PlanSite]: partsTotal(AiStep.PlanSite),
|
|
93
|
+
[AiStep.ChangePlan]: partsTotal(AiStep.ChangePlan),
|
|
62
94
|
// a 1 K picture is 1,120 image tokens (Google's figure for Nano Banana 2) — I-D4
|
|
63
95
|
[AiStep.MakePictures]: { input: 0, output: 0, cacheWrite: 0, cacheRead: 0, imageOutput: 1_120 },
|
|
64
96
|
[AiStep.NameStructures]: { input: 80_000, output: 10_000, cacheWrite: 0, cacheRead: 0 },
|
|
@@ -126,6 +158,11 @@ export function creditsOfUsd(usd: number): number {
|
|
|
126
158
|
return Math.round(usd * CREDITS_PER_USD * CREDIT_PRECISION) / CREDIT_PRECISION;
|
|
127
159
|
}
|
|
128
160
|
|
|
161
|
+
/** What a typical request of `step` reads and writes — one part's when the step is asked in parts, else the whole step's. */
|
|
162
|
+
export function typicalStepTokens(step: AiStep, part?: PlanPart): AiTokenCounts {
|
|
163
|
+
return (part && AI_STEP_PART_TOKENS[step]?.[part]) || AI_STEP_TYPICAL_TOKENS[step];
|
|
164
|
+
}
|
|
165
|
+
|
|
129
166
|
/** The credits a typical use of `step` costs on a model of `price` — never typed, always computed (§3d). */
|
|
130
167
|
export function estimateStepCredits(step: AiStep, price: AiTokenPrice, tokens: AiTokenCounts = AI_STEP_TYPICAL_TOKENS[step]): number {
|
|
131
168
|
return creditsOfUsd(costUsd(tokens, price));
|