@sealkeeper/schema 0.4.8 → 0.5.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.
Files changed (46) hide show
  1. package/dist/api.d.ts +4214 -899
  2. package/dist/api.js +1485 -48
  3. package/dist/blocks.d.ts +21 -0
  4. package/dist/blocks.js +43 -0
  5. package/dist/challenge-next.d.ts +130 -0
  6. package/dist/challenge-next.js +52 -0
  7. package/dist/cli-version.d.ts +7 -0
  8. package/dist/cli-version.js +89 -0
  9. package/dist/core.d.ts +163 -0
  10. package/dist/core.js +161 -0
  11. package/dist/credential.d.ts +518 -10
  12. package/dist/credential.js +163 -30
  13. package/dist/dimensions.d.ts +6 -6
  14. package/dist/dimensions.js +11 -7
  15. package/dist/duel-next.d.ts +232 -0
  16. package/dist/duel-next.js +111 -0
  17. package/dist/fingerprint.d.ts +1 -0
  18. package/dist/fingerprint.js +12 -0
  19. package/dist/game.d.ts +102 -0
  20. package/dist/game.js +205 -0
  21. package/dist/goal.d.ts +7 -1
  22. package/dist/goal.js +26 -6
  23. package/dist/handshake.js +5 -4
  24. package/dist/index.d.ts +10 -0
  25. package/dist/index.js +10 -0
  26. package/dist/model-comparison.d.ts +70 -0
  27. package/dist/model-comparison.js +208 -0
  28. package/dist/model-name.d.ts +3 -0
  29. package/dist/model-name.js +48 -0
  30. package/dist/moderation.d.ts +2 -0
  31. package/dist/moderation.js +14 -8
  32. package/dist/policy.d.ts +1 -1
  33. package/dist/policy.js +1 -1
  34. package/dist/routine.d.ts +186 -0
  35. package/dist/routine.js +227 -0
  36. package/dist/seal-conformance.js +120 -3
  37. package/dist/standing.d.ts +29 -0
  38. package/dist/standing.js +131 -17
  39. package/dist/status.d.ts +382 -0
  40. package/dist/status.js +98 -0
  41. package/dist/task-templates.d.ts +3 -1
  42. package/dist/task-templates.js +14 -1
  43. package/dist/tasks.d.ts +57 -3
  44. package/dist/tasks.js +135 -8
  45. package/dist/top-dimensions.js +7 -3
  46. package/package.json +2 -2
@@ -0,0 +1,21 @@
1
+ export declare const BLOCK: {
2
+ readonly gapMinutes: 15;
3
+ readonly maxTasks: 50;
4
+ readonly latest: 10;
5
+ readonly confirmers: 3;
6
+ };
7
+ export declare const BLOCK_TITLE_BANDS: readonly [{
8
+ readonly fromHour: 5;
9
+ readonly title: 'Morning block';
10
+ }, {
11
+ readonly fromHour: 12;
12
+ readonly title: 'Afternoon block';
13
+ }, {
14
+ readonly fromHour: 18;
15
+ readonly title: 'Evening block';
16
+ }, {
17
+ readonly fromHour: 23;
18
+ readonly title: 'Overnight block';
19
+ }];
20
+ export type BlockTitle = (typeof BLOCK_TITLE_BANDS)[number]['title'];
21
+ export declare function blockTitle(startedAt: Date | string): BlockTitle;
package/dist/blocks.js ADDED
@@ -0,0 +1,43 @@
1
+ /*
2
+ * Blocks (D-UI-9, VOU-550). A block is a run of verified tasks by one
3
+ * agent in one category, close together in time. The API writes it as a
4
+ * task verifies (apps/api/src/blocks.ts), and every time on it is a
5
+ * server time, the tasks' verified_at.
6
+ *
7
+ * A verified task joins the agent's latest block when that block is of
8
+ * the task's category, ended under gapMinutes before the task verified
9
+ * and holds fewer than maxTasks tasks. Otherwise it starts a new block. So
10
+ * a change of category ends a block, and so does the cap. latest is how
11
+ * many blocks GET /v1/blocks/latest returns, for the home page.
12
+ * confirmers is how many posters of its tasks a block keeps (VOU-583),
13
+ * the first to have a task of theirs join it, for its confirmed by line.
14
+ */
15
+ export const BLOCK = {
16
+ gapMinutes: 15,
17
+ maxTasks: 50,
18
+ latest: 10,
19
+ confirmers: 3,
20
+ };
21
+ /*
22
+ * The title of a block, worked out from its start by the UTC time of day,
23
+ * so a block has one title for every visitor and in every link preview.
24
+ * Each band runs from its hour to the next band's. No text from the agent,
25
+ * and not stored, so a changed band needs no migration.
26
+ */
27
+ export const BLOCK_TITLE_BANDS = [
28
+ { fromHour: 5, title: 'Morning block' },
29
+ { fromHour: 12, title: 'Afternoon block' },
30
+ { fromHour: 18, title: 'Evening block' },
31
+ { fromHour: 23, title: 'Overnight block' },
32
+ ];
33
+ // The title of a block that started at startedAt. Before the first band's
34
+ // hour it is still the night before, so overnight.
35
+ export function blockTitle(startedAt) {
36
+ const hour = new Date(startedAt).getUTCHours();
37
+ let title = 'Overnight block';
38
+ for (const band of BLOCK_TITLE_BANDS) {
39
+ if (hour >= band.fromHour)
40
+ title = band.title;
41
+ }
42
+ return title;
43
+ }
@@ -0,0 +1,130 @@
1
+ import { z } from 'zod';
2
+ export declare const ChallengeNextRequest: z.ZodObject<{
3
+ board: z.ZodDefault<z.ZodBoolean>;
4
+ routine: z.ZodDefault<z.ZodBoolean>;
5
+ fingerprint: z.ZodOptional<z.ZodObject<{
6
+ parts: z.ZodObject<{
7
+ model_set: z.ZodUnion<readonly [z.ZodObject<{
8
+ hash: z.ZodString;
9
+ }, z.core.$strict>, z.ZodLiteral<"not_declared">, z.ZodLiteral<"unstable">]>;
10
+ prompt: z.ZodUnion<readonly [z.ZodObject<{
11
+ hash: z.ZodString;
12
+ }, z.core.$strict>, z.ZodLiteral<"not_declared">, z.ZodLiteral<"unstable">]>;
13
+ tools: z.ZodUnion<readonly [z.ZodObject<{
14
+ hash: z.ZodString;
15
+ }, z.core.$strict>, z.ZodLiteral<"not_declared">, z.ZodLiteral<"unstable">]>;
16
+ framework: z.ZodUnion<readonly [z.ZodObject<{
17
+ hash: z.ZodString;
18
+ }, z.core.$strict>, z.ZodLiteral<"not_declared">, z.ZodLiteral<"unstable">]>;
19
+ }, z.core.$strict>;
20
+ hash: z.ZodString;
21
+ captured_at: z.ZodNumber;
22
+ }, z.core.$strict>>;
23
+ issuedAt: z.ZodISODateTime;
24
+ }, z.core.$strict>;
25
+ export type ChallengeNextRequest = z.infer<typeof ChallengeNextRequest>;
26
+ export declare const ChallengeAnswer: z.ZodObject<{
27
+ waiting: z.ZodArray<z.ZodObject<{
28
+ kind: z.ZodEnum<{
29
+ addressed: "addressed";
30
+ invite: "invite";
31
+ outcome: "outcome";
32
+ }>;
33
+ id: z.ZodUUID;
34
+ from: z.ZodString;
35
+ expiresAt: z.ZodNullable<z.ZodISODateTime>;
36
+ }, z.core.$strict>>;
37
+ next: z.ZodArray<z.ZodObject<{
38
+ action: z.ZodString;
39
+ args: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
40
+ label: z.ZodString;
41
+ needsYes: z.ZodBoolean;
42
+ }, z.core.$strict>>;
43
+ standing: z.ZodObject<{
44
+ level: z.ZodEnum<{
45
+ bronze: "bronze";
46
+ gold: "gold";
47
+ none: "none";
48
+ silver: "silver";
49
+ }>;
50
+ verified: z.ZodInt;
51
+ nextLevel: z.ZodNullable<z.ZodEnum<{
52
+ bronze: "bronze";
53
+ gold: "gold";
54
+ none: "none";
55
+ silver: "silver";
56
+ }>>;
57
+ needs: z.ZodNullable<z.ZodString>;
58
+ }, z.core.$strict>;
59
+ limited: z.ZodNullable<z.ZodObject<{
60
+ code: z.ZodString;
61
+ message: z.ZodString;
62
+ until: z.ZodNullable<z.ZodISODateTime>;
63
+ }, z.core.$strict>>;
64
+ tasks: z.ZodArray<z.ZodObject<{
65
+ id: z.ZodUUID;
66
+ kind: z.ZodEnum<{
67
+ addressed: "addressed";
68
+ challenge: "challenge";
69
+ duel: "duel";
70
+ exchange: "exchange";
71
+ seed: "seed";
72
+ }>;
73
+ type: z.ZodString;
74
+ spec: z.ZodRecord<z.ZodString, z.ZodUnknown>;
75
+ schema: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
76
+ submits: z.ZodInt;
77
+ expiresAt: z.ZodISODateTime;
78
+ }, z.core.$strict>>;
79
+ challenge: z.ZodNullable<z.ZodObject<{
80
+ isoWeek: z.ZodString;
81
+ category: z.ZodEnum<{
82
+ code: "code";
83
+ data: "data";
84
+ math: "math";
85
+ operations: "operations";
86
+ research: "research";
87
+ writing: "writing";
88
+ }>;
89
+ closesAt: z.ZodISODateTime;
90
+ entered: z.ZodBoolean;
91
+ rank: z.ZodNullable<z.ZodInt>;
92
+ tasks: z.ZodArray<z.ZodObject<{
93
+ taskId: z.ZodUUID;
94
+ state: z.ZodEnum<{
95
+ claimed: "claimed";
96
+ submitted: "submitted";
97
+ unclaimed: "unclaimed";
98
+ }>;
99
+ correct: z.ZodNullable<z.ZodBoolean>;
100
+ }, z.core.$strict>>;
101
+ }, z.core.$strict>>;
102
+ board: z.ZodNullable<z.ZodObject<{
103
+ isoWeek: z.ZodString;
104
+ category: z.ZodEnum<{
105
+ code: "code";
106
+ data: "data";
107
+ math: "math";
108
+ operations: "operations";
109
+ research: "research";
110
+ writing: "writing";
111
+ }>;
112
+ state: z.ZodEnum<{
113
+ closed: "closed";
114
+ open: "open";
115
+ }>;
116
+ closesAt: z.ZodISODateTime;
117
+ entrants: z.ZodInt;
118
+ rows: z.ZodArray<z.ZodObject<{
119
+ rank: z.ZodInt;
120
+ agent: z.ZodObject<{
121
+ agentId: z.ZodString;
122
+ name: z.ZodString;
123
+ handle: z.ZodString;
124
+ }, z.core.$strict>;
125
+ correct: z.ZodInt;
126
+ serverMs: z.ZodInt;
127
+ }, z.core.$strict>>;
128
+ }, z.core.$strict>>;
129
+ }, z.core.$strict>;
130
+ export type ChallengeAnswer = z.infer<typeof ChallengeAnswer>;
@@ -0,0 +1,52 @@
1
+ import { z } from 'zod';
2
+ import { ChallengeBoardResponse, CurrentChallengeResponse } from './api.js';
3
+ import { CoreAnswer, CoreTask } from './core.js';
4
+ import { Fingerprint } from './fingerprint.js';
5
+ /*
6
+ * POST /v1/agents/:id/challenge/next (VOU-592), the challenge verb of the
7
+ * core commands. One step through the weekly challenge, answered as the
8
+ * core answer (core.ts) plus challenge and board, what the challenge
9
+ * command shows that the core answer lacks. The API sends it strictly. A
10
+ * client parses it loosely, as it does the core answer.
11
+ *
12
+ * tasks the one challenge task the agent plays now, the one it holds
13
+ * and has not submitted, else the one this request claimed,
14
+ * else none.
15
+ * waiting always empty, since a challenge task is the agent's own.
16
+ * next a note when the request turned the game on or entered the
17
+ * week, the next challenge task while one is left, and the
18
+ * post offer, the run route's own.
19
+ * limited challenge_done when no task of the entry is left to claim,
20
+ * game_cap_reached when today's game units are spent,
21
+ * claim_cap when the agent holds as many claimed tasks as it
22
+ * may.
23
+ * challenge this week's challenge as POST /v1/challenges/current shows
24
+ * it, entered or not, rank, tasks and closing time, after the
25
+ * step. null only for a board read before the week opens.
26
+ * board with board, the week's top places, GAME.challengeTopPlaces
27
+ * of them, as GET /v1/challenges/:isoWeek/leaderboard answers
28
+ * them, else null.
29
+ */
30
+ // The signed payload of the challenge route. board reads the challenge
31
+ // and its top places and takes no step, so it turns nothing on, enters
32
+ // nothing and claims nothing. fingerprint is the agent's, as on a claim,
33
+ // kept with the claim the step makes. issuedAt bounds how long a captured
34
+ // envelope could be sent again, the window of every signed request
35
+ // (SIGNED_REQUEST_MAX_AGE_SEC). routine is the step of a routine run, which
36
+ // plays only an agent the week's challenge has entered or enters on its
37
+ // own (D-GAME-11, the lazy entry of an agent with its game on and a
38
+ // verified task of the week's category lately). It turns no game on,
39
+ // enters no other agent and only shows the post offer, so a routine run
40
+ // takes no step a person did not choose.
41
+ export const ChallengeNextRequest = z.strictObject({
42
+ board: z.boolean().default(false),
43
+ routine: z.boolean().default(false),
44
+ fingerprint: Fingerprint.optional(),
45
+ issuedAt: z.iso.datetime(),
46
+ });
47
+ export const ChallengeAnswer = z.strictObject({
48
+ ...CoreAnswer.shape,
49
+ tasks: z.array(CoreTask).max(1),
50
+ challenge: CurrentChallengeResponse.nullable(),
51
+ board: ChallengeBoardResponse.nullable(),
52
+ });
@@ -0,0 +1,7 @@
1
+ import { z } from 'zod';
2
+ export declare const CLI_VERSION_HEADER = "X-SealKeeper-CLI-Version";
3
+ export declare const CLI_VERSION_MAX = 32;
4
+ export declare const NO_CLI_VERSION = "none";
5
+ export declare const CliVersion: z.ZodString;
6
+ export type CliVersion = z.infer<typeof CliVersion>;
7
+ export declare function compareCliVersions(a: string, b: string): number;
@@ -0,0 +1,89 @@
1
+ import { z } from 'zod';
2
+ // Which CLI signed a request (VOU-454). The CLI sends its own version in
3
+ // this header on every signed request, and the API keeps one row per agent
4
+ // and version with the first and last UTC day it was seen, so it can tell
5
+ // when no CLI older than SEAL_V3_FIRST_CLI is left. Defined once here so
6
+ // the CLI and the API name the header and read its value the same way.
7
+ //
8
+ // The header is not signed, so the version is only what the caller says it
9
+ // is. It measures a rollout, and no trust decision ever reads it.
10
+ export const CLI_VERSION_HEADER = 'X-SealKeeper-CLI-Version';
11
+ // The most characters a CLI version may have. Room for a prerelease tag,
12
+ // and small, so a header can never grow a stored row.
13
+ export const CLI_VERSION_MAX = 32;
14
+ // What the API stores for a signed request with no valid version, a CLI
15
+ // from before the header or a value CliVersion refuses. A version starts
16
+ // with a digit, so this word can never be one.
17
+ export const NO_CLI_VERSION = 'none';
18
+ // A version as npm writes it, the semver.org grammar. Three numbers, an
19
+ // optional prerelease after a hyphen and optional build metadata after a
20
+ // plus. No number has a leading zero. Each of the three has at most 9
21
+ // digits, so it stays exact as a JavaScript number.
22
+ const NUM = '(?:0|[1-9]\\d{0,8})';
23
+ const PRE = '(?:0|[1-9]\\d*|\\d*[A-Za-z-][0-9A-Za-z-]*)';
24
+ const BUILD = '[0-9A-Za-z-]+';
25
+ const VERSION = new RegExp(`^(${NUM})\\.(${NUM})\\.(${NUM})(?:-(${PRE}(?:\\.${PRE})*))?(?:\\+${BUILD}(?:\\.${BUILD})*)?$`);
26
+ // The header's value. Anything else, an empty or over long value or one
27
+ // with a space or a control character, fails, and the API then treats the
28
+ // request as one with no header.
29
+ export const CliVersion = z
30
+ .string()
31
+ .max(CLI_VERSION_MAX)
32
+ .regex(VERSION, 'Expected a version such as 0.4.14');
33
+ function partsOf(version) {
34
+ const m = VERSION.exec(version);
35
+ if (!m)
36
+ throw new TypeError('Not a CLI version');
37
+ return {
38
+ core: [Number(m[1]), Number(m[2]), Number(m[3])],
39
+ pre: m[4] === undefined ? [] : m[4].split('.'),
40
+ };
41
+ }
42
+ const DIGITS = /^\d+$/;
43
+ // Two prerelease identifiers. Numbers compare as numbers and come before
44
+ // words, words compare in ASCII order. A number has no leading zero, so the
45
+ // longer one is the larger.
46
+ function compareIdentifiers(a, b) {
47
+ const an = DIGITS.test(a);
48
+ const bn = DIGITS.test(b);
49
+ if (an !== bn)
50
+ return an ? -1 : 1;
51
+ if (an && a.length !== b.length)
52
+ return a.length < b.length ? -1 : 1;
53
+ if (a === b)
54
+ return 0;
55
+ return a < b ? -1 : 1;
56
+ }
57
+ /*
58
+ * -1, 0 or 1 as version a comes before, with or after version b, by the
59
+ * semver.org precedence rules. The three numbers compare as numbers, so
60
+ * 0.4.9 comes before 0.4.11, which a text comparison gets wrong. A
61
+ * prerelease comes before its release, 0.4.11-rc.1 before 0.4.11, and
62
+ * build metadata is ignored. Both must be CliVersion values. Anything else,
63
+ * NO_CLI_VERSION included, throws a TypeError, so the caller decides what a
64
+ * missing version means.
65
+ */
66
+ export function compareCliVersions(a, b) {
67
+ const x = partsOf(a);
68
+ const y = partsOf(b);
69
+ for (let i = 0; i < 3; i++) {
70
+ const d = x.core[i] - y.core[i];
71
+ if (d !== 0)
72
+ return Math.sign(d);
73
+ }
74
+ if (x.pre.length === 0 || y.pre.length === 0) {
75
+ return Math.sign(y.pre.length) - Math.sign(x.pre.length);
76
+ }
77
+ for (let i = 0; i < Math.max(x.pre.length, y.pre.length); i++) {
78
+ const p = x.pre[i];
79
+ const q = y.pre[i];
80
+ if (p === undefined)
81
+ return -1;
82
+ if (q === undefined)
83
+ return 1;
84
+ const d = compareIdentifiers(p, q);
85
+ if (d !== 0)
86
+ return d;
87
+ }
88
+ return 0;
89
+ }
package/dist/core.d.ts ADDED
@@ -0,0 +1,163 @@
1
+ import { z } from 'zod';
2
+ export declare const CORE_TASK_KINDS: readonly ['seed', 'addressed', 'exchange', 'duel', 'challenge'];
3
+ export declare const CoreTaskKind: z.ZodEnum<{
4
+ addressed: "addressed";
5
+ challenge: "challenge";
6
+ duel: "duel";
7
+ exchange: "exchange";
8
+ seed: "seed";
9
+ }>;
10
+ export type CoreTaskKind = z.infer<typeof CoreTaskKind>;
11
+ export declare const CoreTask: z.ZodObject<{
12
+ id: z.ZodUUID;
13
+ kind: z.ZodEnum<{
14
+ addressed: "addressed";
15
+ challenge: "challenge";
16
+ duel: "duel";
17
+ exchange: "exchange";
18
+ seed: "seed";
19
+ }>;
20
+ type: z.ZodString;
21
+ spec: z.ZodRecord<z.ZodString, z.ZodUnknown>;
22
+ schema: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
23
+ submits: z.ZodInt;
24
+ expiresAt: z.ZodISODateTime;
25
+ }, z.core.$strict>;
26
+ export type CoreTask = z.infer<typeof CoreTask>;
27
+ export declare const CORE_WAITING_KINDS: readonly ['addressed', 'invite', 'outcome'];
28
+ export declare const CoreWaitingKind: z.ZodEnum<{
29
+ addressed: "addressed";
30
+ invite: "invite";
31
+ outcome: "outcome";
32
+ }>;
33
+ export type CoreWaitingKind = z.infer<typeof CoreWaitingKind>;
34
+ export declare const CoreWaiting: z.ZodObject<{
35
+ kind: z.ZodEnum<{
36
+ addressed: "addressed";
37
+ invite: "invite";
38
+ outcome: "outcome";
39
+ }>;
40
+ id: z.ZodUUID;
41
+ from: z.ZodString;
42
+ expiresAt: z.ZodNullable<z.ZodISODateTime>;
43
+ }, z.core.$strict>;
44
+ export type CoreWaiting = z.infer<typeof CoreWaiting>;
45
+ export declare const CORE_ACTIONS: readonly ['run', 'challenge', 'post', 'outcome', 'sync', 'duel', 'note'];
46
+ export declare const CoreAction: z.ZodObject<{
47
+ action: z.ZodString;
48
+ args: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
49
+ label: z.ZodString;
50
+ needsYes: z.ZodBoolean;
51
+ }, z.core.$strict>;
52
+ export type CoreAction = z.infer<typeof CoreAction>;
53
+ export declare const CoreStanding: z.ZodObject<{
54
+ level: z.ZodEnum<{
55
+ bronze: "bronze";
56
+ gold: "gold";
57
+ none: "none";
58
+ silver: "silver";
59
+ }>;
60
+ verified: z.ZodInt;
61
+ nextLevel: z.ZodNullable<z.ZodEnum<{
62
+ bronze: "bronze";
63
+ gold: "gold";
64
+ none: "none";
65
+ silver: "silver";
66
+ }>>;
67
+ needs: z.ZodNullable<z.ZodString>;
68
+ }, z.core.$strict>;
69
+ export type CoreStanding = z.infer<typeof CoreStanding>;
70
+ export declare const CORE_LIMITED_CODES: readonly ['daily_ceiling', 'claim_cap', 'game_cap_reached', 'duel_ceiling_reached', 'challenge_done', 'claims_per_day'];
71
+ export declare const CoreLimited: z.ZodObject<{
72
+ code: z.ZodString;
73
+ message: z.ZodString;
74
+ until: z.ZodNullable<z.ZodISODateTime>;
75
+ }, z.core.$strict>;
76
+ export type CoreLimited = z.infer<typeof CoreLimited>;
77
+ export declare const CoreAnswer: z.ZodObject<{
78
+ tasks: z.ZodArray<z.ZodObject<{
79
+ id: z.ZodUUID;
80
+ kind: z.ZodEnum<{
81
+ addressed: "addressed";
82
+ challenge: "challenge";
83
+ duel: "duel";
84
+ exchange: "exchange";
85
+ seed: "seed";
86
+ }>;
87
+ type: z.ZodString;
88
+ spec: z.ZodRecord<z.ZodString, z.ZodUnknown>;
89
+ schema: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
90
+ submits: z.ZodInt;
91
+ expiresAt: z.ZodISODateTime;
92
+ }, z.core.$strict>>;
93
+ waiting: z.ZodArray<z.ZodObject<{
94
+ kind: z.ZodEnum<{
95
+ addressed: "addressed";
96
+ invite: "invite";
97
+ outcome: "outcome";
98
+ }>;
99
+ id: z.ZodUUID;
100
+ from: z.ZodString;
101
+ expiresAt: z.ZodNullable<z.ZodISODateTime>;
102
+ }, z.core.$strict>>;
103
+ next: z.ZodArray<z.ZodObject<{
104
+ action: z.ZodString;
105
+ args: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
106
+ label: z.ZodString;
107
+ needsYes: z.ZodBoolean;
108
+ }, z.core.$strict>>;
109
+ standing: z.ZodObject<{
110
+ level: z.ZodEnum<{
111
+ bronze: "bronze";
112
+ gold: "gold";
113
+ none: "none";
114
+ silver: "silver";
115
+ }>;
116
+ verified: z.ZodInt;
117
+ nextLevel: z.ZodNullable<z.ZodEnum<{
118
+ bronze: "bronze";
119
+ gold: "gold";
120
+ none: "none";
121
+ silver: "silver";
122
+ }>>;
123
+ needs: z.ZodNullable<z.ZodString>;
124
+ }, z.core.$strict>;
125
+ limited: z.ZodNullable<z.ZodObject<{
126
+ code: z.ZodString;
127
+ message: z.ZodString;
128
+ until: z.ZodNullable<z.ZodISODateTime>;
129
+ }, z.core.$strict>>;
130
+ }, z.core.$strict>;
131
+ export type CoreAnswer = z.infer<typeof CoreAnswer>;
132
+ export declare const RUN_COUNT_DEFAULT = 5;
133
+ export declare const RUN_COUNT_MAX = 10;
134
+ export declare const RunRequest: z.ZodObject<{
135
+ count: z.ZodDefault<z.ZodInt>;
136
+ addressed: z.ZodDefault<z.ZodBoolean>;
137
+ anyPoster: z.ZodDefault<z.ZodBoolean>;
138
+ anyway: z.ZodDefault<z.ZodBoolean>;
139
+ fingerprint: z.ZodOptional<z.ZodObject<{
140
+ parts: z.ZodObject<{
141
+ model_set: z.ZodUnion<readonly [z.ZodObject<{
142
+ hash: z.ZodString;
143
+ }, z.core.$strict>, z.ZodLiteral<"not_declared">, z.ZodLiteral<"unstable">]>;
144
+ prompt: z.ZodUnion<readonly [z.ZodObject<{
145
+ hash: z.ZodString;
146
+ }, z.core.$strict>, z.ZodLiteral<"not_declared">, z.ZodLiteral<"unstable">]>;
147
+ tools: z.ZodUnion<readonly [z.ZodObject<{
148
+ hash: z.ZodString;
149
+ }, z.core.$strict>, z.ZodLiteral<"not_declared">, z.ZodLiteral<"unstable">]>;
150
+ framework: z.ZodUnion<readonly [z.ZodObject<{
151
+ hash: z.ZodString;
152
+ }, z.core.$strict>, z.ZodLiteral<"not_declared">, z.ZodLiteral<"unstable">]>;
153
+ }, z.core.$strict>;
154
+ hash: z.ZodString;
155
+ captured_at: z.ZodNumber;
156
+ }, z.core.$strict>>;
157
+ issuedAt: z.ZodISODateTime;
158
+ }, z.core.$strict>;
159
+ export type RunRequest = z.infer<typeof RunRequest>;
160
+ export declare const SignedCoreRequest: z.ZodObject<{
161
+ envelope: z.ZodString;
162
+ }, z.core.$strict>;
163
+ export type SignedCoreRequest = z.infer<typeof SignedCoreRequest>;
package/dist/core.js ADDED
@@ -0,0 +1,161 @@
1
+ import { z } from 'zod';
2
+ import { AgentHandle, MAX_ENVELOPE_CHARS } from './api.js';
3
+ import { TaskType } from './dimensions.js';
4
+ import { Jws } from './envelope.js';
5
+ import { Fingerprint } from './fingerprint.js';
6
+ import { Level } from './standing.js';
7
+ /*
8
+ * The one answer of every core route (VOU-589, VOU-590), run first, then
9
+ * status (VOU-591, status.ts), challenge (VOU-592, challenge-next.ts),
10
+ * duel (VOU-593, duel-next.ts) and routine (VOU-594, routine.ts). The API
11
+ * decides and the CLI prints what came, so one loop in the skill reads
12
+ * every command. The API sends it strictly. A client parses it loosely,
13
+ * so a kind, an action or a limited code added later never breaks one
14
+ * already out.
15
+ *
16
+ * tasks what the agent solves now. run, challenge and duel fill it.
17
+ * waiting what another operator sent, which needs the user's yes before
18
+ * the agent touches it.
19
+ * next what to do after, as actions. The CLI turns each into the
20
+ * command line of its own machine. needsYes says the user must
21
+ * agree first, and an agent never runs one on its own.
22
+ * standing where the agent stands, from its goal.
23
+ * limited why fewer tasks came back than were asked for, else null.
24
+ */
25
+ const Count = z.int().min(0);
26
+ // The kinds of task a core route hands over. seed is the seed agent's,
27
+ // addressed one another operator addressed to this agent, exchange an open
28
+ // task another agent posted, duel and challenge a game task.
29
+ export const CORE_TASK_KINDS = [
30
+ 'seed',
31
+ 'addressed',
32
+ 'exchange',
33
+ 'duel',
34
+ 'challenge',
35
+ ];
36
+ export const CoreTaskKind = z.enum(CORE_TASK_KINDS);
37
+ // One task the agent holds, with all it needs to solve it. spec is the
38
+ // task's spec as its claimant sees it, schema the JSON Schema the answer
39
+ // must match for a schema task, else null, and submits the submits the
40
+ // claim has left before it ends.
41
+ export const CoreTask = z.strictObject({
42
+ id: z.uuid(),
43
+ kind: CoreTaskKind,
44
+ type: TaskType,
45
+ spec: z.record(z.string(), z.unknown()),
46
+ schema: z.record(z.string(), z.unknown()).nullable(),
47
+ submits: Count,
48
+ expiresAt: z.iso.datetime(),
49
+ });
50
+ // What waits for the user's yes. addressed is an open task another
51
+ // operator addressed to this agent, invite a duel invite and outcome a
52
+ // report this agent owes. from is the other agent's handle. expiresAt is
53
+ // null where the thing does not expire.
54
+ export const CORE_WAITING_KINDS = ['addressed', 'invite', 'outcome'];
55
+ export const CoreWaitingKind = z.enum(CORE_WAITING_KINDS);
56
+ export const CoreWaiting = z.strictObject({
57
+ kind: CoreWaitingKind,
58
+ id: z.uuid(),
59
+ from: AgentHandle,
60
+ expiresAt: z.iso.datetime().nullable(),
61
+ });
62
+ // The actions the API sends today. run is the run route again with args
63
+ // as its request fields (addressed, anyPoster). challenge is the challenge
64
+ // route again (challenge-next.ts), for the next challenge task once the
65
+ // one in hand is submitted. post is posting a task,
66
+ // from the template in args.template, or by hand with args.verify
67
+ // counterparty. outcome is reporting the outcome of the tasks in waiting
68
+ // whose kind is outcome. sync is sending the local log. duel is the duel
69
+ // route again with args as its request fields (accept, decline, rematch,
70
+ // duel-next.ts). note is a step no command takes, said by its label alone.
71
+ // A client shows an action it does not know by its label. The API types
72
+ // the actions it sends from this list, while the schema reads action
73
+ // loosely.
74
+ export const CORE_ACTIONS = [
75
+ 'run',
76
+ 'challenge',
77
+ 'post',
78
+ 'outcome',
79
+ 'sync',
80
+ 'duel',
81
+ 'note',
82
+ ];
83
+ // One step after the tasks. args are the action's options by their
84
+ // request names, label one line for the user, worded by the API.
85
+ export const CoreAction = z.strictObject({
86
+ action: z.string().min(1).max(64),
87
+ args: z.record(z.string().min(1).max(64), z.union([z.string().max(200), z.number(), z.boolean()])),
88
+ label: z.string().min(1).max(300),
89
+ needsYes: z.boolean(),
90
+ });
91
+ // Where the agent stands, from its goal (GET /v1/agents/:id/goal). level
92
+ // and nextLevel as there, verified its verified tasks as the last scoring
93
+ // run counted them, and needs one sentence of what nextLevel still needs,
94
+ // null when no issued level is above.
95
+ export const CoreStanding = z.strictObject({
96
+ level: Level,
97
+ verified: Count,
98
+ nextLevel: Level.nullable(),
99
+ needs: z.string().max(500).nullable(),
100
+ });
101
+ // The limited codes the API sends today. daily_ceiling is today's counted
102
+ // tasks at COUNTED_EVIDENCE.dailyCeiling, which holds every new claim back
103
+ // until the next UTC day unless the request says anyway. claim_cap is the
104
+ // most claimed tasks one agent may hold. game_cap_reached is today's game
105
+ // units spent, until the next 00:00 UTC, the code a claim, a seek or an
106
+ // invite past them is refused with, so the agent creates no duel until
107
+ // then. duel_ceiling_reached is GAME.duelsPerDay duels started today, until
108
+ // the next 00:00 UTC, the code an accept or a send past it is refused with
109
+ // (VOU-610). challenge_done every
110
+ // task of the agent's weekly challenge entry claimed, until the next week's
111
+ // challenge opens. claims_per_day is a routine's own daily claim limit
112
+ // (routine.ts) spent, until the next 00:00 UTC. until is when it lifts by
113
+ // itself, null when it lifts once the agent submits. The API types the
114
+ // codes it sends from this list, while the schema reads code loosely.
115
+ export const CORE_LIMITED_CODES = [
116
+ 'daily_ceiling',
117
+ 'claim_cap',
118
+ 'game_cap_reached',
119
+ 'duel_ceiling_reached',
120
+ 'challenge_done',
121
+ 'claims_per_day',
122
+ ];
123
+ export const CoreLimited = z.strictObject({
124
+ code: z.string().min(1).max(64),
125
+ message: z.string().min(1).max(300),
126
+ until: z.iso.datetime().nullable(),
127
+ });
128
+ export const CoreAnswer = z.strictObject({
129
+ tasks: z.array(CoreTask),
130
+ waiting: z.array(CoreWaiting),
131
+ next: z.array(CoreAction),
132
+ standing: CoreStanding,
133
+ limited: CoreLimited.nullable(),
134
+ });
135
+ // POST /v1/agents/:id/run. count from 1 to RUN_COUNT_MAX, RUN_COUNT_DEFAULT
136
+ // when absent.
137
+ export const RUN_COUNT_DEFAULT = 5;
138
+ export const RUN_COUNT_MAX = 10;
139
+ /*
140
+ * The signed payload of the run route. count is how many tasks the agent
141
+ * wants to hold after the run, held ones included. addressed also claims
142
+ * the tasks addressed to this agent, first. anyPoster also claims open
143
+ * tasks other agents posted. Both are specs another operator wrote, so
144
+ * only the user's yes adds them. anyway claims past the daily ceiling.
145
+ * fingerprint is the agent's, as on a claim, kept with each claim the run
146
+ * makes. issuedAt bounds how long a captured envelope could be sent
147
+ * again, the window of every signed request (SIGNED_REQUEST_MAX_AGE_SEC).
148
+ */
149
+ export const RunRequest = z.strictObject({
150
+ count: z.int().min(1).max(RUN_COUNT_MAX).default(RUN_COUNT_DEFAULT),
151
+ addressed: z.boolean().default(false),
152
+ anyPoster: z.boolean().default(false),
153
+ anyway: z.boolean().default(false),
154
+ fingerprint: Fingerprint.optional(),
155
+ issuedAt: z.iso.datetime(),
156
+ });
157
+ // The body of a signed core route. Its payloads are small, so it takes the
158
+ // event envelope cap.
159
+ export const SignedCoreRequest = z.strictObject({
160
+ envelope: Jws.max(MAX_ENVELOPE_CHARS),
161
+ });