@anchrd/intel-contract 0.8.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.
@@ -470,6 +470,41 @@ export declare const AgentReference: z.ZodObject<{
470
470
  }>;
471
471
  }, z.core.$strict>;
472
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[];
473
508
  export declare const AgentScheduleTarget: z.ZodObject<{
474
509
  kind: z.ZodEnum<{
475
510
  document: "document";
@@ -673,6 +708,116 @@ export declare const RunAgentNowInput: z.ZodObject<{
673
708
  }, z.core.$strict>;
674
709
  }, z.core.$strict>;
675
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>;
676
821
  export declare const ListAgentsInput: z.ZodObject<{
677
822
  parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
678
823
  includeArchived: z.ZodDefault<z.ZodBoolean>;
@@ -281,6 +281,45 @@ export const AgentMediaType = "application/vnd.anchrd.agent+json";
281
281
  // memory write target — ordinary Knowledge, versioned and readable like everything else
282
282
  export const AgentReferenceRole = z.enum(["system-message", "semantic-context", "memory"]);
283
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
+ }
284
323
  // A `document` target means the content of that document is the instruction — a "skill" somebody
285
324
  // wrote as ordinary text; a `flow` target means a run is started through Intel MCP and worked step
286
325
  // by step. Both are references, so nothing in here goes stale (ADR-0005 §4).
@@ -442,6 +481,68 @@ export const RunAgentNowInput = z.strictObject({
442
481
  nodeId: IntelId,
443
482
  target: AgentScheduleTarget,
444
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
+ });
445
546
  // ⚠️ Three states, not two, and the same three the flow list makes: omitted is the whole tree,
446
547
  // `null` is the root level, an ID is that folder. "Which agents may I use" is a question about the
447
548
  // tree rather than about one folder, so the useful answer has to be reachable without knowing where
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anchrd/intel-contract",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {