@anchrd/intel-contract 0.7.0 → 0.9.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/contract/contract.d.ts +154 -0
- package/dist/contract/contract.js +143 -0
- package/package.json +1 -1
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export declare const IntelId: z.ZodString;
|
|
3
3
|
export declare const IsoDateTime: z.ZodISODateTime;
|
|
4
|
+
export declare const UI_LANGUAGES: readonly ["en", "de", "es"];
|
|
5
|
+
export type UiLanguage = (typeof UI_LANGUAGES)[number];
|
|
4
6
|
export declare const ProblemDetails: z.ZodObject<{
|
|
5
7
|
type: z.ZodString;
|
|
6
8
|
status: z.ZodNumber;
|
|
@@ -468,6 +470,41 @@ export declare const AgentReference: z.ZodObject<{
|
|
|
468
470
|
}>;
|
|
469
471
|
}, z.core.$strict>;
|
|
470
472
|
export type AgentReference = z.infer<typeof AgentReference>;
|
|
473
|
+
/**
|
|
474
|
+
* Which kinds of node each role can actually be given (#255).
|
|
475
|
+
*
|
|
476
|
+
* ⚠️ Not every role takes every kind, and the reasons are about what the runtime DOES with a
|
|
477
|
+
* reference rather than about tidiness:
|
|
478
|
+
*
|
|
479
|
+
* `memory` is a folder because the agent WRITES there — `agent_remember` creates a note inside
|
|
480
|
+
* it. A single document as memory would mean the agent overwrites the document it was given.
|
|
481
|
+
*
|
|
482
|
+
* `semantic-context` is a folder because it is a search SPACE, searched per folder by
|
|
483
|
+
* `loop/scoped-search`. A single document is not a narrower search space; reading it whole is a
|
|
484
|
+
* different behaviour, and one that gets named before it is introduced, not slipped in.
|
|
485
|
+
*
|
|
486
|
+
* `system-message` reads single nodes already and takes a document or a table as well as a
|
|
487
|
+
* folder. A document is the natural case — a skill somebody wrote as ordinary text — and a table
|
|
488
|
+
* is the same read: the runtime asks intel for the node and prepends its content, which for a
|
|
489
|
+
* table is its CSV.
|
|
490
|
+
*
|
|
491
|
+
* ⚠️ `folder` stays on `system-message` although a folder carries no content of its own. Every
|
|
492
|
+
* definition written before #255 could only name folders, and taking the combination away here
|
|
493
|
+
* would refuse the next save of an agent that has been working for months — "existing definitions
|
|
494
|
+
* stay valid" is not only about reading them.
|
|
495
|
+
*
|
|
496
|
+
* ⚠️ This is the ONE place the rule lives. The screen offers what it says and the write path
|
|
497
|
+
* refuses what it forbids; a surface that made its own list would eventually disagree with the
|
|
498
|
+
* other, and the one that matters is whichever runs last.
|
|
499
|
+
*/
|
|
500
|
+
export declare const AgentReferenceKinds: {
|
|
501
|
+
readonly "system-message": readonly ["folder", "document", "table"];
|
|
502
|
+
readonly "semantic-context": readonly ["folder"];
|
|
503
|
+
readonly memory: readonly ["folder"];
|
|
504
|
+
};
|
|
505
|
+
export declare function agentReferenceAccepts(role: AgentReferenceRole, kind: NodeKind): boolean;
|
|
506
|
+
/** The roles a node of this kind may be given — the same rule, read from the other side. */
|
|
507
|
+
export declare function agentReferenceRolesFor(kind: NodeKind): AgentReferenceRole[];
|
|
471
508
|
export declare const AgentScheduleTarget: z.ZodObject<{
|
|
472
509
|
kind: z.ZodEnum<{
|
|
473
510
|
document: "document";
|
|
@@ -478,6 +515,7 @@ export declare const AgentScheduleTarget: z.ZodObject<{
|
|
|
478
515
|
export type AgentScheduleTarget = z.infer<typeof AgentScheduleTarget>;
|
|
479
516
|
export declare const AgentSchedule: z.ZodObject<{
|
|
480
517
|
cron: z.ZodString;
|
|
518
|
+
timezone: z.ZodDefault<z.ZodString>;
|
|
481
519
|
target: z.ZodObject<{
|
|
482
520
|
kind: z.ZodEnum<{
|
|
483
521
|
document: "document";
|
|
@@ -553,6 +591,7 @@ export declare const AgentDefinition: z.ZodObject<{
|
|
|
553
591
|
}, z.core.$strict>>>;
|
|
554
592
|
schedules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
555
593
|
cron: z.ZodString;
|
|
594
|
+
timezone: z.ZodDefault<z.ZodString>;
|
|
556
595
|
target: z.ZodObject<{
|
|
557
596
|
kind: z.ZodEnum<{
|
|
558
597
|
document: "document";
|
|
@@ -595,6 +634,7 @@ export declare const AgentDefinitionInput: z.ZodObject<{
|
|
|
595
634
|
}, z.core.$strict>>>;
|
|
596
635
|
schedules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
597
636
|
cron: z.ZodString;
|
|
637
|
+
timezone: z.ZodDefault<z.ZodString>;
|
|
598
638
|
target: z.ZodObject<{
|
|
599
639
|
kind: z.ZodEnum<{
|
|
600
640
|
document: "document";
|
|
@@ -629,6 +669,7 @@ export declare const SaveAgentDefinitionInput: z.ZodObject<{
|
|
|
629
669
|
}, z.core.$strict>>>;
|
|
630
670
|
schedules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
631
671
|
cron: z.ZodString;
|
|
672
|
+
timezone: z.ZodDefault<z.ZodString>;
|
|
632
673
|
target: z.ZodObject<{
|
|
633
674
|
kind: z.ZodEnum<{
|
|
634
675
|
document: "document";
|
|
@@ -667,6 +708,116 @@ export declare const RunAgentNowInput: z.ZodObject<{
|
|
|
667
708
|
}, z.core.$strict>;
|
|
668
709
|
}, z.core.$strict>;
|
|
669
710
|
export type RunAgentNowInput = z.infer<typeof RunAgentNowInput>;
|
|
711
|
+
/**
|
|
712
|
+
* What one agent has actually cost, read out of Cloudflare's AI Gateway log (#251).
|
|
713
|
+
*
|
|
714
|
+
* ⚠️ Intel computes none of this from tokens and a price table. The gateway publishes the billed
|
|
715
|
+
* figure per call, and that figure is the debit from the Cloudflare balance 1:1 — Cloudflare takes
|
|
716
|
+
* its 5 % when the balance is loaded and passes inference through unchanged (measured 2026-08-07).
|
|
717
|
+
* A second, self-maintained answer beside it would be wrong on the day the two disagreed, and the
|
|
718
|
+
* wrong one would be the one on screen.
|
|
719
|
+
*
|
|
720
|
+
* ⚠️ `status` travels with the numbers and may never be dropped. `runs: []` means "cost nothing"
|
|
721
|
+
* only when `status` is `read`; under `not_configured` or `unreadable` it means "not known", and a
|
|
722
|
+
* screen that renders the two alike reports an outage as a saving.
|
|
723
|
+
*/
|
|
724
|
+
export declare const AgentCostStatus: z.ZodEnum<{
|
|
725
|
+
read: "read";
|
|
726
|
+
not_configured: "not_configured";
|
|
727
|
+
unreadable: "unreadable";
|
|
728
|
+
}>;
|
|
729
|
+
export type AgentCostStatus = z.infer<typeof AgentCostStatus>;
|
|
730
|
+
export declare const AgentRunCost: z.ZodObject<{
|
|
731
|
+
runId: z.ZodString;
|
|
732
|
+
cost: z.ZodNumber;
|
|
733
|
+
calls: z.ZodNumber;
|
|
734
|
+
}, z.core.$strict>;
|
|
735
|
+
export type AgentRunCost = z.infer<typeof AgentRunCost>;
|
|
736
|
+
export declare const AgentCostWindow: z.ZodObject<{
|
|
737
|
+
days: z.ZodNumber;
|
|
738
|
+
cost: z.ZodNumber;
|
|
739
|
+
calls: z.ZodNumber;
|
|
740
|
+
models: z.ZodArray<z.ZodString>;
|
|
741
|
+
}, z.core.$strict>;
|
|
742
|
+
export type AgentCostWindow = z.infer<typeof AgentCostWindow>;
|
|
743
|
+
export declare const AgentCosts: z.ZodObject<{
|
|
744
|
+
status: z.ZodEnum<{
|
|
745
|
+
read: "read";
|
|
746
|
+
not_configured: "not_configured";
|
|
747
|
+
unreadable: "unreadable";
|
|
748
|
+
}>;
|
|
749
|
+
currency: z.ZodLiteral<"USD">;
|
|
750
|
+
runs: z.ZodArray<z.ZodObject<{
|
|
751
|
+
runId: z.ZodString;
|
|
752
|
+
cost: z.ZodNumber;
|
|
753
|
+
calls: z.ZodNumber;
|
|
754
|
+
}, z.core.$strict>>;
|
|
755
|
+
windows: z.ZodArray<z.ZodObject<{
|
|
756
|
+
days: z.ZodNumber;
|
|
757
|
+
cost: z.ZodNumber;
|
|
758
|
+
calls: z.ZodNumber;
|
|
759
|
+
models: z.ZodArray<z.ZodString>;
|
|
760
|
+
}, z.core.$strict>>;
|
|
761
|
+
partial: z.ZodBoolean;
|
|
762
|
+
}, z.core.$strict>;
|
|
763
|
+
export type AgentCosts = z.infer<typeof AgentCosts>;
|
|
764
|
+
/**
|
|
765
|
+
* What the models on offer cost and how much they hold (#257).
|
|
766
|
+
*
|
|
767
|
+
* ⚠️ `source` is per ENTRY and not per response, and that is not over-engineering. Cloudflare
|
|
768
|
+
* publishes figures for the models it serves itself and none at all for the Anthropic models it
|
|
769
|
+
* resells through Unified Billing — so a perfectly healthy read still leaves half the list on a
|
|
770
|
+
* written-out table, and one flag for the whole answer would call either the read stale or the
|
|
771
|
+
* table live.
|
|
772
|
+
*/
|
|
773
|
+
export declare const ModelPrice: z.ZodObject<{
|
|
774
|
+
inputPerMillion: z.ZodNumber;
|
|
775
|
+
outputPerMillion: z.ZodNumber;
|
|
776
|
+
}, z.core.$strict>;
|
|
777
|
+
export type ModelPrice = z.infer<typeof ModelPrice>;
|
|
778
|
+
export declare const ModelCatalogEntry: z.ZodObject<{
|
|
779
|
+
provider: z.ZodEnum<{
|
|
780
|
+
"workers-ai": "workers-ai";
|
|
781
|
+
anthropic: "anthropic";
|
|
782
|
+
}>;
|
|
783
|
+
model: z.ZodString;
|
|
784
|
+
name: z.ZodString;
|
|
785
|
+
contextTokens: z.ZodNullable<z.ZodNumber>;
|
|
786
|
+
price: z.ZodNullable<z.ZodObject<{
|
|
787
|
+
inputPerMillion: z.ZodNumber;
|
|
788
|
+
outputPerMillion: z.ZodNumber;
|
|
789
|
+
}, z.core.$strict>>;
|
|
790
|
+
source: z.ZodEnum<{
|
|
791
|
+
cloudflare: "cloudflare";
|
|
792
|
+
builtin: "builtin";
|
|
793
|
+
}>;
|
|
794
|
+
}, z.core.$strict>;
|
|
795
|
+
export type ModelCatalogEntry = z.infer<typeof ModelCatalogEntry>;
|
|
796
|
+
export declare const ModelCatalog: z.ZodObject<{
|
|
797
|
+
entries: z.ZodArray<z.ZodObject<{
|
|
798
|
+
provider: z.ZodEnum<{
|
|
799
|
+
"workers-ai": "workers-ai";
|
|
800
|
+
anthropic: "anthropic";
|
|
801
|
+
}>;
|
|
802
|
+
model: z.ZodString;
|
|
803
|
+
name: z.ZodString;
|
|
804
|
+
contextTokens: z.ZodNullable<z.ZodNumber>;
|
|
805
|
+
price: z.ZodNullable<z.ZodObject<{
|
|
806
|
+
inputPerMillion: z.ZodNumber;
|
|
807
|
+
outputPerMillion: z.ZodNumber;
|
|
808
|
+
}, z.core.$strict>>;
|
|
809
|
+
source: z.ZodEnum<{
|
|
810
|
+
cloudflare: "cloudflare";
|
|
811
|
+
builtin: "builtin";
|
|
812
|
+
}>;
|
|
813
|
+
}, z.core.$strict>>;
|
|
814
|
+
liveStatus: z.ZodEnum<{
|
|
815
|
+
read: "read";
|
|
816
|
+
not_configured: "not_configured";
|
|
817
|
+
unreadable: "unreadable";
|
|
818
|
+
}>;
|
|
819
|
+
}, z.core.$strict>;
|
|
820
|
+
export type ModelCatalog = z.infer<typeof ModelCatalog>;
|
|
670
821
|
export declare const ListAgentsInput: z.ZodObject<{
|
|
671
822
|
parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
672
823
|
includeArchived: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -690,6 +841,7 @@ export declare const CreateAgentInput: z.ZodObject<{
|
|
|
690
841
|
}, z.core.$strict>>>;
|
|
691
842
|
schedules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
692
843
|
cron: z.ZodString;
|
|
844
|
+
timezone: z.ZodDefault<z.ZodString>;
|
|
693
845
|
target: z.ZodObject<{
|
|
694
846
|
kind: z.ZodEnum<{
|
|
695
847
|
document: "document";
|
|
@@ -759,6 +911,7 @@ export declare const NodeAgent: z.ZodObject<{
|
|
|
759
911
|
}, z.core.$strict>>>;
|
|
760
912
|
schedules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
761
913
|
cron: z.ZodString;
|
|
914
|
+
timezone: z.ZodDefault<z.ZodString>;
|
|
762
915
|
target: z.ZodObject<{
|
|
763
916
|
kind: z.ZodEnum<{
|
|
764
917
|
document: "document";
|
|
@@ -842,6 +995,7 @@ export declare const CreatedAgent: z.ZodObject<{
|
|
|
842
995
|
}, z.core.$strict>>>;
|
|
843
996
|
schedules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
844
997
|
cron: z.ZodString;
|
|
998
|
+
timezone: z.ZodDefault<z.ZodString>;
|
|
845
999
|
target: z.ZodObject<{
|
|
846
1000
|
kind: z.ZodEnum<{
|
|
847
1001
|
document: "document";
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export const IntelId = z.string().min(1).max(128);
|
|
3
3
|
export const IsoDateTime = z.iso.datetime({ offset: true });
|
|
4
|
+
// The languages whose UI catalog ships inside intel-ui. They live here rather than only in the UI
|
|
5
|
+
// because `intel build` has to know them: a built-in language may be chosen as `ui.defaultLanguage`
|
|
6
|
+
// without the customer listing a copy under `ui.languages` that would rot at every UI update.
|
|
7
|
+
//
|
|
8
|
+
// ⚠️ The list is a claim about the contents of packages/ui/src/i18n and cannot be checked here.
|
|
9
|
+
// `i18n.unit.ts` compares it against the catalogs actually built in; a language listed here without
|
|
10
|
+
// a file gives a red run there instead of a UI that starts on a catalog which does not exist.
|
|
11
|
+
export const UI_LANGUAGES = ["en", "de", "es"];
|
|
4
12
|
export const ProblemDetails = z.strictObject({
|
|
5
13
|
type: z.string(),
|
|
6
14
|
status: z.number().int().min(400).max(599),
|
|
@@ -273,6 +281,45 @@ export const AgentMediaType = "application/vnd.anchrd.agent+json";
|
|
|
273
281
|
// memory write target — ordinary Knowledge, versioned and readable like everything else
|
|
274
282
|
export const AgentReferenceRole = z.enum(["system-message", "semantic-context", "memory"]);
|
|
275
283
|
export const AgentReference = z.strictObject({ nodeId: IntelId, role: AgentReferenceRole });
|
|
284
|
+
/**
|
|
285
|
+
* Which kinds of node each role can actually be given (#255).
|
|
286
|
+
*
|
|
287
|
+
* ⚠️ Not every role takes every kind, and the reasons are about what the runtime DOES with a
|
|
288
|
+
* reference rather than about tidiness:
|
|
289
|
+
*
|
|
290
|
+
* `memory` is a folder because the agent WRITES there — `agent_remember` creates a note inside
|
|
291
|
+
* it. A single document as memory would mean the agent overwrites the document it was given.
|
|
292
|
+
*
|
|
293
|
+
* `semantic-context` is a folder because it is a search SPACE, searched per folder by
|
|
294
|
+
* `loop/scoped-search`. A single document is not a narrower search space; reading it whole is a
|
|
295
|
+
* different behaviour, and one that gets named before it is introduced, not slipped in.
|
|
296
|
+
*
|
|
297
|
+
* `system-message` reads single nodes already and takes a document or a table as well as a
|
|
298
|
+
* folder. A document is the natural case — a skill somebody wrote as ordinary text — and a table
|
|
299
|
+
* is the same read: the runtime asks intel for the node and prepends its content, which for a
|
|
300
|
+
* table is its CSV.
|
|
301
|
+
*
|
|
302
|
+
* ⚠️ `folder` stays on `system-message` although a folder carries no content of its own. Every
|
|
303
|
+
* definition written before #255 could only name folders, and taking the combination away here
|
|
304
|
+
* would refuse the next save of an agent that has been working for months — "existing definitions
|
|
305
|
+
* stay valid" is not only about reading them.
|
|
306
|
+
*
|
|
307
|
+
* ⚠️ This is the ONE place the rule lives. The screen offers what it says and the write path
|
|
308
|
+
* refuses what it forbids; a surface that made its own list would eventually disagree with the
|
|
309
|
+
* other, and the one that matters is whichever runs last.
|
|
310
|
+
*/
|
|
311
|
+
export const AgentReferenceKinds = {
|
|
312
|
+
"system-message": ["folder", "document", "table"],
|
|
313
|
+
"semantic-context": ["folder"],
|
|
314
|
+
memory: ["folder"],
|
|
315
|
+
};
|
|
316
|
+
export function agentReferenceAccepts(role, kind) {
|
|
317
|
+
return AgentReferenceKinds[role].includes(kind);
|
|
318
|
+
}
|
|
319
|
+
/** The roles a node of this kind may be given — the same rule, read from the other side. */
|
|
320
|
+
export function agentReferenceRolesFor(kind) {
|
|
321
|
+
return AgentReferenceRole.options.filter((role) => agentReferenceAccepts(role, kind));
|
|
322
|
+
}
|
|
276
323
|
// A `document` target means the content of that document is the instruction — a "skill" somebody
|
|
277
324
|
// wrote as ordinary text; a `flow` target means a run is started through Intel MCP and worked step
|
|
278
325
|
// by step. Both are references, so nothing in here goes stale (ADR-0005 §4).
|
|
@@ -283,8 +330,42 @@ export const AgentScheduleTarget = z.strictObject({
|
|
|
283
330
|
kind: z.enum(["document", "flow"]),
|
|
284
331
|
id: IntelId,
|
|
285
332
|
});
|
|
333
|
+
/**
|
|
334
|
+
* ⚠️ `timezone` is what the cron expression is READ IN, and it belongs to the schedule rather than
|
|
335
|
+
* to whoever is looking at it (#228). "Every morning at eight" means eight o'clock where the person
|
|
336
|
+
* who wrote it sits — in Berlin that is 06:00 UTC in summer and 07:00 in winter, and a field that
|
|
337
|
+
* does not carry the zone cannot express that difference. A UTC cron is an hour wrong twice a year
|
|
338
|
+
* and nobody sees why.
|
|
339
|
+
*
|
|
340
|
+
* The UI suggests the reader's own zone when a schedule is created, but it is not a per-user
|
|
341
|
+
* setting: an agent's schedule would otherwise move whenever its owner travelled, and it would mean
|
|
342
|
+
* different times to two people reading the same definition. What is stored is the answer.
|
|
343
|
+
*
|
|
344
|
+
* ⚠️ The default is `"UTC"`, and it is load-bearing rather than tidy: every definition written
|
|
345
|
+
* before this field parses to it and therefore keeps firing exactly when it did. A default of
|
|
346
|
+
* "whatever the writer's browser says" would silently move every existing schedule at the next save.
|
|
347
|
+
*
|
|
348
|
+
* The name is validated against this runtime's own tz database rather than a pattern. A regular
|
|
349
|
+
* expression would accept `Mars/Olympus`, and the failure would surface inside a Durable Object
|
|
350
|
+
* alarm — the place where nobody is watching.
|
|
351
|
+
*/
|
|
352
|
+
const IanaTimezone = z
|
|
353
|
+
.string()
|
|
354
|
+
.trim()
|
|
355
|
+
.min(1)
|
|
356
|
+
.max(64)
|
|
357
|
+
.refine((zone) => {
|
|
358
|
+
try {
|
|
359
|
+
new Intl.DateTimeFormat("en-US", { timeZone: zone });
|
|
360
|
+
return true;
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
365
|
+
}, { message: "must be an IANA timezone name this runtime knows, for example Europe/Berlin" });
|
|
286
366
|
export const AgentSchedule = z.strictObject({
|
|
287
367
|
cron: z.string().trim().min(1).max(120),
|
|
368
|
+
timezone: IanaTimezone.default("UTC"),
|
|
288
369
|
target: AgentScheduleTarget,
|
|
289
370
|
});
|
|
290
371
|
export const AgentModel = z.strictObject({
|
|
@@ -400,6 +481,68 @@ export const RunAgentNowInput = z.strictObject({
|
|
|
400
481
|
nodeId: IntelId,
|
|
401
482
|
target: AgentScheduleTarget,
|
|
402
483
|
});
|
|
484
|
+
/**
|
|
485
|
+
* What one agent has actually cost, read out of Cloudflare's AI Gateway log (#251).
|
|
486
|
+
*
|
|
487
|
+
* ⚠️ Intel computes none of this from tokens and a price table. The gateway publishes the billed
|
|
488
|
+
* figure per call, and that figure is the debit from the Cloudflare balance 1:1 — Cloudflare takes
|
|
489
|
+
* its 5 % when the balance is loaded and passes inference through unchanged (measured 2026-08-07).
|
|
490
|
+
* A second, self-maintained answer beside it would be wrong on the day the two disagreed, and the
|
|
491
|
+
* wrong one would be the one on screen.
|
|
492
|
+
*
|
|
493
|
+
* ⚠️ `status` travels with the numbers and may never be dropped. `runs: []` means "cost nothing"
|
|
494
|
+
* only when `status` is `read`; under `not_configured` or `unreadable` it means "not known", and a
|
|
495
|
+
* screen that renders the two alike reports an outage as a saving.
|
|
496
|
+
*/
|
|
497
|
+
export const AgentCostStatus = z.enum(["read", "not_configured", "unreadable"]);
|
|
498
|
+
export const AgentRunCost = z.strictObject({
|
|
499
|
+
runId: z.string(),
|
|
500
|
+
cost: z.number(),
|
|
501
|
+
calls: z.number(),
|
|
502
|
+
});
|
|
503
|
+
export const AgentCostWindow = z.strictObject({
|
|
504
|
+
days: z.number(),
|
|
505
|
+
cost: z.number(),
|
|
506
|
+
calls: z.number(),
|
|
507
|
+
// Which models produced this figure. It is here so the model select can say the number is about
|
|
508
|
+
// the PAST (#257) — a reader who switched model would otherwise take it for a forecast.
|
|
509
|
+
models: z.array(z.string()),
|
|
510
|
+
});
|
|
511
|
+
export const AgentCosts = z.strictObject({
|
|
512
|
+
status: AgentCostStatus,
|
|
513
|
+
currency: z.literal("USD"),
|
|
514
|
+
runs: z.array(AgentRunCost),
|
|
515
|
+
windows: z.array(AgentCostWindow),
|
|
516
|
+
// The read hit its page limit, so every total above is a floor rather than a total.
|
|
517
|
+
partial: z.boolean(),
|
|
518
|
+
});
|
|
519
|
+
/**
|
|
520
|
+
* What the models on offer cost and how much they hold (#257).
|
|
521
|
+
*
|
|
522
|
+
* ⚠️ `source` is per ENTRY and not per response, and that is not over-engineering. Cloudflare
|
|
523
|
+
* publishes figures for the models it serves itself and none at all for the Anthropic models it
|
|
524
|
+
* resells through Unified Billing — so a perfectly healthy read still leaves half the list on a
|
|
525
|
+
* written-out table, and one flag for the whole answer would call either the read stale or the
|
|
526
|
+
* table live.
|
|
527
|
+
*/
|
|
528
|
+
export const ModelPrice = z.strictObject({
|
|
529
|
+
inputPerMillion: z.number(),
|
|
530
|
+
outputPerMillion: z.number(),
|
|
531
|
+
});
|
|
532
|
+
export const ModelCatalogEntry = z.strictObject({
|
|
533
|
+
provider: z.enum(["workers-ai", "anthropic"]),
|
|
534
|
+
model: z.string(),
|
|
535
|
+
name: z.string(),
|
|
536
|
+
contextTokens: z.number().nullable(),
|
|
537
|
+
// `null` where this installation has no figure. Never zero and never a guess — an invented number
|
|
538
|
+
// is a false statement about money.
|
|
539
|
+
price: ModelPrice.nullable(),
|
|
540
|
+
source: z.enum(["cloudflare", "builtin"]),
|
|
541
|
+
});
|
|
542
|
+
export const ModelCatalog = z.strictObject({
|
|
543
|
+
entries: z.array(ModelCatalogEntry),
|
|
544
|
+
liveStatus: z.enum(["read", "not_configured", "unreadable"]),
|
|
545
|
+
});
|
|
403
546
|
// ⚠️ Three states, not two, and the same three the flow list makes: omitted is the whole tree,
|
|
404
547
|
// `null` is the root level, an ID is that folder. "Which agents may I use" is a question about the
|
|
405
548
|
// tree rather than about one folder, so the useful answer has to be reachable without knowing where
|