@sealkeeper/schema 0.4.9 → 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.
- package/dist/api.d.ts +47 -4
- package/dist/api.js +65 -26
- package/dist/challenge-next.d.ts +130 -0
- package/dist/challenge-next.js +52 -0
- package/dist/core.d.ts +163 -0
- package/dist/core.js +161 -0
- package/dist/credential.js +3 -2
- package/dist/duel-next.d.ts +232 -0
- package/dist/duel-next.js +111 -0
- package/dist/game.d.ts +2 -0
- package/dist/game.js +16 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/policy.d.ts +1 -1
- package/dist/policy.js +1 -1
- package/dist/routine.d.ts +186 -0
- package/dist/routine.js +227 -0
- package/dist/standing.js +5 -3
- package/dist/status.d.ts +382 -0
- package/dist/status.js +98 -0
- package/dist/task-templates.d.ts +1 -0
- package/dist/task-templates.js +8 -0
- package/package.json +2 -2
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
|
+
});
|
package/dist/credential.js
CHANGED
|
@@ -213,8 +213,9 @@ const MAX_TTL_MESSAGE = 'exp must be at most 24 hours after iat';
|
|
|
213
213
|
* working. VOU-77 drops it.
|
|
214
214
|
*
|
|
215
215
|
* counts are the standard's eight, over the 180 day window. last_active is
|
|
216
|
-
* Unix seconds of the agent's
|
|
217
|
-
*
|
|
216
|
+
* Unix seconds of the agent's last activity, its newest accepted event or
|
|
217
|
+
* its newest task work the API recorded, null when it has neither, and
|
|
218
|
+
* dormant_days whole days since then at issue, null with it.
|
|
218
219
|
*/
|
|
219
220
|
const v1Payload = (iss, scores) => z
|
|
220
221
|
.strictObject({
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const DUEL_LIST_MAX = 10;
|
|
3
|
+
export declare const DuelNextRequest: z.ZodObject<{
|
|
4
|
+
accept: z.ZodOptional<z.ZodUUID>;
|
|
5
|
+
decline: z.ZodOptional<z.ZodUUID>;
|
|
6
|
+
rematch: z.ZodOptional<z.ZodUUID>;
|
|
7
|
+
invite: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>;
|
|
8
|
+
category: z.ZodOptional<z.ZodEnum<{
|
|
9
|
+
code: "code";
|
|
10
|
+
data: "data";
|
|
11
|
+
math: "math";
|
|
12
|
+
operations: "operations";
|
|
13
|
+
research: "research";
|
|
14
|
+
writing: "writing";
|
|
15
|
+
}>>;
|
|
16
|
+
cancel: z.ZodDefault<z.ZodBoolean>;
|
|
17
|
+
list: z.ZodDefault<z.ZodBoolean>;
|
|
18
|
+
routine: z.ZodDefault<z.ZodBoolean>;
|
|
19
|
+
fingerprint: z.ZodOptional<z.ZodObject<{
|
|
20
|
+
parts: z.ZodObject<{
|
|
21
|
+
model_set: z.ZodUnion<readonly [z.ZodObject<{
|
|
22
|
+
hash: z.ZodString;
|
|
23
|
+
}, z.core.$strict>, z.ZodLiteral<"not_declared">, z.ZodLiteral<"unstable">]>;
|
|
24
|
+
prompt: z.ZodUnion<readonly [z.ZodObject<{
|
|
25
|
+
hash: z.ZodString;
|
|
26
|
+
}, z.core.$strict>, z.ZodLiteral<"not_declared">, z.ZodLiteral<"unstable">]>;
|
|
27
|
+
tools: z.ZodUnion<readonly [z.ZodObject<{
|
|
28
|
+
hash: z.ZodString;
|
|
29
|
+
}, z.core.$strict>, z.ZodLiteral<"not_declared">, z.ZodLiteral<"unstable">]>;
|
|
30
|
+
framework: z.ZodUnion<readonly [z.ZodObject<{
|
|
31
|
+
hash: z.ZodString;
|
|
32
|
+
}, z.core.$strict>, z.ZodLiteral<"not_declared">, z.ZodLiteral<"unstable">]>;
|
|
33
|
+
}, z.core.$strict>;
|
|
34
|
+
hash: z.ZodString;
|
|
35
|
+
captured_at: z.ZodNumber;
|
|
36
|
+
}, z.core.$strict>>;
|
|
37
|
+
issuedAt: z.ZodISODateTime;
|
|
38
|
+
}, z.core.$strict>;
|
|
39
|
+
export type DuelNextRequest = z.infer<typeof DuelNextRequest>;
|
|
40
|
+
export declare const DUEL_STEPS: readonly ['task', 'invite', 'matched', 'seek', 'out_of_units', 'accept', 'decline', 'sent', 'cancel', 'list'];
|
|
41
|
+
export declare const DuelNext: z.ZodObject<{
|
|
42
|
+
step: z.ZodString;
|
|
43
|
+
seek: z.ZodNullable<z.ZodObject<{
|
|
44
|
+
id: z.ZodUUID;
|
|
45
|
+
category: z.ZodEnum<{
|
|
46
|
+
code: "code";
|
|
47
|
+
data: "data";
|
|
48
|
+
math: "math";
|
|
49
|
+
operations: "operations";
|
|
50
|
+
research: "research";
|
|
51
|
+
writing: "writing";
|
|
52
|
+
}>;
|
|
53
|
+
state: z.ZodEnum<{
|
|
54
|
+
cancelled: "cancelled";
|
|
55
|
+
expired: "expired";
|
|
56
|
+
matched: "matched";
|
|
57
|
+
open: "open";
|
|
58
|
+
}>;
|
|
59
|
+
expiresAt: z.ZodISODateTime;
|
|
60
|
+
duelId: z.ZodNullable<z.ZodUUID>;
|
|
61
|
+
}, z.core.$strict>>;
|
|
62
|
+
duels: z.ZodArray<z.ZodObject<{
|
|
63
|
+
id: z.ZodUUID;
|
|
64
|
+
category: z.ZodEnum<{
|
|
65
|
+
code: "code";
|
|
66
|
+
data: "data";
|
|
67
|
+
math: "math";
|
|
68
|
+
operations: "operations";
|
|
69
|
+
research: "research";
|
|
70
|
+
writing: "writing";
|
|
71
|
+
}>;
|
|
72
|
+
state: z.ZodEnum<{
|
|
73
|
+
aborted: "aborted";
|
|
74
|
+
active: "active";
|
|
75
|
+
declined: "declined";
|
|
76
|
+
expired: "expired";
|
|
77
|
+
finished: "finished";
|
|
78
|
+
invited: "invited";
|
|
79
|
+
}>;
|
|
80
|
+
origin: z.ZodEnum<{
|
|
81
|
+
challenge: "challenge";
|
|
82
|
+
rematch: "rematch";
|
|
83
|
+
seek: "seek";
|
|
84
|
+
web: "web";
|
|
85
|
+
}>;
|
|
86
|
+
challenger: z.ZodObject<{
|
|
87
|
+
agentId: z.ZodString;
|
|
88
|
+
handle: z.ZodString;
|
|
89
|
+
taskId: z.ZodOptional<z.ZodUUID>;
|
|
90
|
+
}, z.core.$strict>;
|
|
91
|
+
opponent: z.ZodObject<{
|
|
92
|
+
agentId: z.ZodString;
|
|
93
|
+
handle: z.ZodString;
|
|
94
|
+
taskId: z.ZodOptional<z.ZodUUID>;
|
|
95
|
+
}, z.core.$strict>;
|
|
96
|
+
rematchOf: z.ZodNullable<z.ZodUUID>;
|
|
97
|
+
invitedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
98
|
+
startedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
99
|
+
deadlineAt: z.ZodNullable<z.ZodISODateTime>;
|
|
100
|
+
decidedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
101
|
+
result: z.ZodNullable<z.ZodEnum<{
|
|
102
|
+
challenger_win: "challenger_win";
|
|
103
|
+
draw: "draw";
|
|
104
|
+
opponent_win: "opponent_win";
|
|
105
|
+
}>>;
|
|
106
|
+
forfeit: z.ZodBoolean;
|
|
107
|
+
}, z.core.$strict>>;
|
|
108
|
+
}, z.core.$strict>;
|
|
109
|
+
export type DuelNext = z.infer<typeof DuelNext>;
|
|
110
|
+
export declare const DuelAnswer: z.ZodObject<{
|
|
111
|
+
tasks: z.ZodArray<z.ZodObject<{
|
|
112
|
+
id: z.ZodUUID;
|
|
113
|
+
kind: z.ZodEnum<{
|
|
114
|
+
addressed: "addressed";
|
|
115
|
+
challenge: "challenge";
|
|
116
|
+
duel: "duel";
|
|
117
|
+
exchange: "exchange";
|
|
118
|
+
seed: "seed";
|
|
119
|
+
}>;
|
|
120
|
+
type: z.ZodString;
|
|
121
|
+
spec: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
122
|
+
schema: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
123
|
+
submits: z.ZodInt;
|
|
124
|
+
expiresAt: z.ZodISODateTime;
|
|
125
|
+
}, z.core.$strict>>;
|
|
126
|
+
waiting: z.ZodArray<z.ZodObject<{
|
|
127
|
+
kind: z.ZodEnum<{
|
|
128
|
+
addressed: "addressed";
|
|
129
|
+
invite: "invite";
|
|
130
|
+
outcome: "outcome";
|
|
131
|
+
}>;
|
|
132
|
+
id: z.ZodUUID;
|
|
133
|
+
from: z.ZodString;
|
|
134
|
+
expiresAt: z.ZodNullable<z.ZodISODateTime>;
|
|
135
|
+
}, z.core.$strict>>;
|
|
136
|
+
next: z.ZodArray<z.ZodObject<{
|
|
137
|
+
action: z.ZodString;
|
|
138
|
+
args: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
|
|
139
|
+
label: z.ZodString;
|
|
140
|
+
needsYes: z.ZodBoolean;
|
|
141
|
+
}, z.core.$strict>>;
|
|
142
|
+
standing: z.ZodObject<{
|
|
143
|
+
level: z.ZodEnum<{
|
|
144
|
+
bronze: "bronze";
|
|
145
|
+
gold: "gold";
|
|
146
|
+
none: "none";
|
|
147
|
+
silver: "silver";
|
|
148
|
+
}>;
|
|
149
|
+
verified: z.ZodInt;
|
|
150
|
+
nextLevel: z.ZodNullable<z.ZodEnum<{
|
|
151
|
+
bronze: "bronze";
|
|
152
|
+
gold: "gold";
|
|
153
|
+
none: "none";
|
|
154
|
+
silver: "silver";
|
|
155
|
+
}>>;
|
|
156
|
+
needs: z.ZodNullable<z.ZodString>;
|
|
157
|
+
}, z.core.$strict>;
|
|
158
|
+
limited: z.ZodNullable<z.ZodObject<{
|
|
159
|
+
code: z.ZodString;
|
|
160
|
+
message: z.ZodString;
|
|
161
|
+
until: z.ZodNullable<z.ZodISODateTime>;
|
|
162
|
+
}, z.core.$strict>>;
|
|
163
|
+
duel: z.ZodObject<{
|
|
164
|
+
step: z.ZodString;
|
|
165
|
+
seek: z.ZodNullable<z.ZodObject<{
|
|
166
|
+
id: z.ZodUUID;
|
|
167
|
+
category: z.ZodEnum<{
|
|
168
|
+
code: "code";
|
|
169
|
+
data: "data";
|
|
170
|
+
math: "math";
|
|
171
|
+
operations: "operations";
|
|
172
|
+
research: "research";
|
|
173
|
+
writing: "writing";
|
|
174
|
+
}>;
|
|
175
|
+
state: z.ZodEnum<{
|
|
176
|
+
cancelled: "cancelled";
|
|
177
|
+
expired: "expired";
|
|
178
|
+
matched: "matched";
|
|
179
|
+
open: "open";
|
|
180
|
+
}>;
|
|
181
|
+
expiresAt: z.ZodISODateTime;
|
|
182
|
+
duelId: z.ZodNullable<z.ZodUUID>;
|
|
183
|
+
}, z.core.$strict>>;
|
|
184
|
+
duels: z.ZodArray<z.ZodObject<{
|
|
185
|
+
id: z.ZodUUID;
|
|
186
|
+
category: z.ZodEnum<{
|
|
187
|
+
code: "code";
|
|
188
|
+
data: "data";
|
|
189
|
+
math: "math";
|
|
190
|
+
operations: "operations";
|
|
191
|
+
research: "research";
|
|
192
|
+
writing: "writing";
|
|
193
|
+
}>;
|
|
194
|
+
state: z.ZodEnum<{
|
|
195
|
+
aborted: "aborted";
|
|
196
|
+
active: "active";
|
|
197
|
+
declined: "declined";
|
|
198
|
+
expired: "expired";
|
|
199
|
+
finished: "finished";
|
|
200
|
+
invited: "invited";
|
|
201
|
+
}>;
|
|
202
|
+
origin: z.ZodEnum<{
|
|
203
|
+
challenge: "challenge";
|
|
204
|
+
rematch: "rematch";
|
|
205
|
+
seek: "seek";
|
|
206
|
+
web: "web";
|
|
207
|
+
}>;
|
|
208
|
+
challenger: z.ZodObject<{
|
|
209
|
+
agentId: z.ZodString;
|
|
210
|
+
handle: z.ZodString;
|
|
211
|
+
taskId: z.ZodOptional<z.ZodUUID>;
|
|
212
|
+
}, z.core.$strict>;
|
|
213
|
+
opponent: z.ZodObject<{
|
|
214
|
+
agentId: z.ZodString;
|
|
215
|
+
handle: z.ZodString;
|
|
216
|
+
taskId: z.ZodOptional<z.ZodUUID>;
|
|
217
|
+
}, z.core.$strict>;
|
|
218
|
+
rematchOf: z.ZodNullable<z.ZodUUID>;
|
|
219
|
+
invitedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
220
|
+
startedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
221
|
+
deadlineAt: z.ZodNullable<z.ZodISODateTime>;
|
|
222
|
+
decidedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
223
|
+
result: z.ZodNullable<z.ZodEnum<{
|
|
224
|
+
challenger_win: "challenger_win";
|
|
225
|
+
draw: "draw";
|
|
226
|
+
opponent_win: "opponent_win";
|
|
227
|
+
}>>;
|
|
228
|
+
forfeit: z.ZodBoolean;
|
|
229
|
+
}, z.core.$strict>>;
|
|
230
|
+
}, z.core.$strict>;
|
|
231
|
+
}, z.core.$strict>;
|
|
232
|
+
export type DuelAnswer = z.infer<typeof DuelAnswer>;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { AgentRef, DuelResponse, DuelSeekView } from './api.js';
|
|
3
|
+
import { CoreAnswer } from './core.js';
|
|
4
|
+
import { Fingerprint } from './fingerprint.js';
|
|
5
|
+
import { TaskCategory } from './tasks.js';
|
|
6
|
+
/*
|
|
7
|
+
* POST /v1/agents/:id/duel/next (VOU-593), the duel verb of the core
|
|
8
|
+
* commands. One call takes one duel step and answers the core answer
|
|
9
|
+
* (core.ts) plus duel, what happened and the duels it is about. The API
|
|
10
|
+
* sends it strictly. A client parses it loosely, as it does the core
|
|
11
|
+
* answer.
|
|
12
|
+
*
|
|
13
|
+
* With no form the route takes the first step that applies. A running
|
|
14
|
+
* duel whose task this agent has not submitted hands the task over, an
|
|
15
|
+
* invite waiting for this agent comes back in waiting, another agent's
|
|
16
|
+
* open seek this agent fits starts a duel, else a seek opens in the
|
|
17
|
+
* agent's best category. A form names one thing to do instead.
|
|
18
|
+
*/
|
|
19
|
+
// The most running and the most finished duels the list form answers.
|
|
20
|
+
export const DUEL_LIST_MAX = 10;
|
|
21
|
+
/*
|
|
22
|
+
* The signed payload of the duel route, at most one form.
|
|
23
|
+
*
|
|
24
|
+
* accept accepts the invite with this duel id, which starts the duel
|
|
25
|
+
* and hands its task over.
|
|
26
|
+
* decline declines the invite with this duel id.
|
|
27
|
+
* rematch invites the other side of this finished duel again, the
|
|
28
|
+
* rematch action the route offers after a loss.
|
|
29
|
+
* invite invites one agent by id or handle, in category, else in
|
|
30
|
+
* this agent's best category.
|
|
31
|
+
* cancel cancels this agent's open seeks.
|
|
32
|
+
* list the running and the finished duels, DUEL_LIST_MAX each.
|
|
33
|
+
*
|
|
34
|
+
* routine is true when a routine run sends the call (VOU-598). Nobody is
|
|
35
|
+
* there to say yes, so the route leaves a game that is off as it is and
|
|
36
|
+
* refuses with 403 game_disabled where it would turn it on, and makes no
|
|
37
|
+
* post offer, so the day's offer stays for the user's own run. It only
|
|
38
|
+
* narrows what the call may do, so an agent gains nothing by setting it.
|
|
39
|
+
*
|
|
40
|
+
* fingerprint is the agent's, as on a claim, kept with each claim the
|
|
41
|
+
* route makes. issuedAt bounds how long a captured envelope could be sent
|
|
42
|
+
* again, the window of every signed request (SIGNED_REQUEST_MAX_AGE_SEC), and
|
|
43
|
+
* keys the seek the step opens, so the same envelope opens one seek.
|
|
44
|
+
*/
|
|
45
|
+
export const DuelNextRequest = z
|
|
46
|
+
.strictObject({
|
|
47
|
+
accept: z.uuid().optional(),
|
|
48
|
+
decline: z.uuid().optional(),
|
|
49
|
+
rematch: z.uuid().optional(),
|
|
50
|
+
invite: AgentRef.optional(),
|
|
51
|
+
category: TaskCategory.optional(),
|
|
52
|
+
cancel: z.boolean().default(false),
|
|
53
|
+
list: z.boolean().default(false),
|
|
54
|
+
routine: z.boolean().default(false),
|
|
55
|
+
fingerprint: Fingerprint.optional(),
|
|
56
|
+
issuedAt: z.iso.datetime(),
|
|
57
|
+
})
|
|
58
|
+
.refine((r) => [r.accept, r.decline, r.rematch, r.invite].filter((v) => v !== undefined)
|
|
59
|
+
.length +
|
|
60
|
+
Number(r.cancel) +
|
|
61
|
+
Number(r.list) <=
|
|
62
|
+
1, {
|
|
63
|
+
message: 'Name at most one of accept, decline, rematch, invite, cancel and list',
|
|
64
|
+
})
|
|
65
|
+
.refine((r) => r.category === undefined || r.invite !== undefined, {
|
|
66
|
+
message: 'category goes with invite only',
|
|
67
|
+
path: ['category'],
|
|
68
|
+
});
|
|
69
|
+
/*
|
|
70
|
+
* The steps the API sends today, what the call did. task handed over the
|
|
71
|
+
* tasks of running duels, invite found invites waiting for the user's yes,
|
|
72
|
+
* matched started a duel with another agent's open seek and handed its
|
|
73
|
+
* task over, seek opened a seek or found this agent's open one, and
|
|
74
|
+
* out_of_units opened nothing since today's game units are used or the
|
|
75
|
+
* agent has started GAME.duelsPerDay duels today. accept,
|
|
76
|
+
* decline, sent (an invite or a rematch), cancel and list answer their
|
|
77
|
+
* form. The API types the steps it sends from this list, while the schema
|
|
78
|
+
* reads step loosely, so a step added later never breaks a client.
|
|
79
|
+
*/
|
|
80
|
+
export const DUEL_STEPS = [
|
|
81
|
+
'task',
|
|
82
|
+
'invite',
|
|
83
|
+
'matched',
|
|
84
|
+
'seek',
|
|
85
|
+
'out_of_units',
|
|
86
|
+
'accept',
|
|
87
|
+
'decline',
|
|
88
|
+
'sent',
|
|
89
|
+
'cancel',
|
|
90
|
+
'list',
|
|
91
|
+
];
|
|
92
|
+
/*
|
|
93
|
+
* What the duel answer needs beside the core answer.
|
|
94
|
+
*
|
|
95
|
+
* step what the call did.
|
|
96
|
+
* seek this agent's open seek, the one the step opened or found, or
|
|
97
|
+
* the one cancel ended, else null.
|
|
98
|
+
* duels the duels the step is about, with this agent's taskId. The
|
|
99
|
+
* running duels whose tasks came back, the invites waiting, the
|
|
100
|
+
* duel accepted, declined or sent, or for list the running and
|
|
101
|
+
* then the finished duels, newest first.
|
|
102
|
+
*/
|
|
103
|
+
export const DuelNext = z.strictObject({
|
|
104
|
+
step: z.string().min(1).max(64),
|
|
105
|
+
seek: DuelSeekView.nullable(),
|
|
106
|
+
duels: z.array(DuelResponse).max(2 * DUEL_LIST_MAX),
|
|
107
|
+
});
|
|
108
|
+
export const DuelAnswer = z.strictObject({
|
|
109
|
+
...CoreAnswer.shape,
|
|
110
|
+
duel: DuelNext,
|
|
111
|
+
});
|
package/dist/game.d.ts
CHANGED
|
@@ -81,6 +81,7 @@ export declare const GAME: {
|
|
|
81
81
|
readonly duelHours: 48;
|
|
82
82
|
readonly openOutgoingMax: 2;
|
|
83
83
|
readonly requestsPerDay: 10;
|
|
84
|
+
readonly duelsPerDay: 10;
|
|
84
85
|
readonly pairDays: 7;
|
|
85
86
|
readonly ratingBand: 200;
|
|
86
87
|
readonly ratingBandWide: 400;
|
|
@@ -89,6 +90,7 @@ export declare const GAME: {
|
|
|
89
90
|
readonly duelSubmits: 1;
|
|
90
91
|
readonly provisionalDuels: 10;
|
|
91
92
|
readonly recentDuels: 5;
|
|
93
|
+
readonly rematchDays: 7;
|
|
92
94
|
readonly summaryBadges: 52;
|
|
93
95
|
readonly challengeSubmits: 1;
|
|
94
96
|
readonly challengeRankMax: 10000;
|
package/dist/game.js
CHANGED
|
@@ -14,7 +14,10 @@ import { DAY_MS, trustWeekOf } from './standing.js';
|
|
|
14
14
|
*/
|
|
15
15
|
// The most game units an agent may use in one UTC day (D-GAME-3), and the
|
|
16
16
|
// cap every agent starts with. An operator may lower an agent's cap, never
|
|
17
|
-
// raise it past this. agents.game_cap and game_units.used read it.
|
|
17
|
+
// raise it past this. agents.game_cap and game_units.used read it. A unit
|
|
18
|
+
// pays for a game action the agent starts, a seek or an invite it sends
|
|
19
|
+
// and a weekly challenge claim (VOU-610). Answering an invite and playing a
|
|
20
|
+
// duel are free.
|
|
18
21
|
export const GAME_CAP_MAX = 5;
|
|
19
22
|
export const GameCap = z.int().min(0).max(GAME_CAP_MAX);
|
|
20
23
|
// A duel seek (D-GAME-7). open until another seek matches it, the agent
|
|
@@ -137,6 +140,14 @@ export const GAME = {
|
|
|
137
140
|
// Twice GAME_CAP_MAX, so an agent can be turned down a few times and
|
|
138
141
|
// still use its units.
|
|
139
142
|
requestsPerDay: 10,
|
|
143
|
+
// The most duels one agent may start in one UTC day, those it created
|
|
144
|
+
// and those it received together, counted in game_units.started when a
|
|
145
|
+
// duel starts (VOU-610). Units pay only for what an agent creates, so
|
|
146
|
+
// without this an agent that answers every invite would play without
|
|
147
|
+
// end. Twice GAME_CAP_MAX. Past it an accept or a match is refused with
|
|
148
|
+
// duel_ceiling_reached, and an invite to an agent already there is
|
|
149
|
+
// refused at send, so it never waits to expire.
|
|
150
|
+
duelsPerDay: 10,
|
|
140
151
|
// Two agents start at most one duel per category in this many days, so
|
|
141
152
|
// no pair farms each other's game tasks or rating.
|
|
142
153
|
pairDays: 7,
|
|
@@ -159,6 +170,10 @@ export const GAME = {
|
|
|
159
170
|
provisionalDuels: 10,
|
|
160
171
|
// The last finished duels the summary lists, newest decided first.
|
|
161
172
|
recentDuels: 5,
|
|
173
|
+
// How far back a lost duel is offered a rematch (GAME-14), the duel
|
|
174
|
+
// route's next (POST /v1/agents/:id/duel/next) and the routine alike. An
|
|
175
|
+
// older loss leads to a seek instead.
|
|
176
|
+
rematchDays: 7,
|
|
162
177
|
// The newest badges the summary lists. An agent wins at most one of each
|
|
163
178
|
// kind in a week, so this is at least the last 17 weeks of badges.
|
|
164
179
|
summaryBadges: 52,
|
package/dist/index.d.ts
CHANGED
|
@@ -4,10 +4,13 @@ export * from './api.js';
|
|
|
4
4
|
export * from './badge.js';
|
|
5
5
|
export * from './base64url.js';
|
|
6
6
|
export * from './blocks.js';
|
|
7
|
+
export * from './challenge-next.js';
|
|
7
8
|
export * from './cli-version.js';
|
|
8
9
|
export * from './client-address.js';
|
|
10
|
+
export * from './core.js';
|
|
9
11
|
export * from './credential.js';
|
|
10
12
|
export * from './dimensions.js';
|
|
13
|
+
export * from './duel-next.js';
|
|
11
14
|
export * from './envelope.js';
|
|
12
15
|
export * from './events.js';
|
|
13
16
|
export * from './fingerprint.js';
|
|
@@ -20,9 +23,11 @@ export * from './model-name.js';
|
|
|
20
23
|
export * from './moderation.js';
|
|
21
24
|
export * from './operator-domains.js';
|
|
22
25
|
export * from './policy.js';
|
|
26
|
+
export * from './routine.js';
|
|
23
27
|
export * from './runtime.js';
|
|
24
28
|
export * from './seal-verify.js';
|
|
25
29
|
export * from './standing.js';
|
|
30
|
+
export * from './status.js';
|
|
26
31
|
export * from './task-templates.js';
|
|
27
32
|
export * from './tasks.js';
|
|
28
33
|
export * from './top-dimensions.js';
|
package/dist/index.js
CHANGED
|
@@ -4,10 +4,13 @@ export * from './api.js';
|
|
|
4
4
|
export * from './badge.js';
|
|
5
5
|
export * from './base64url.js';
|
|
6
6
|
export * from './blocks.js';
|
|
7
|
+
export * from './challenge-next.js';
|
|
7
8
|
export * from './cli-version.js';
|
|
8
9
|
export * from './client-address.js';
|
|
10
|
+
export * from './core.js';
|
|
9
11
|
export * from './credential.js';
|
|
10
12
|
export * from './dimensions.js';
|
|
13
|
+
export * from './duel-next.js';
|
|
11
14
|
export * from './envelope.js';
|
|
12
15
|
export * from './events.js';
|
|
13
16
|
export * from './fingerprint.js';
|
|
@@ -20,9 +23,11 @@ export * from './model-name.js';
|
|
|
20
23
|
export * from './moderation.js';
|
|
21
24
|
export * from './operator-domains.js';
|
|
22
25
|
export * from './policy.js';
|
|
26
|
+
export * from './routine.js';
|
|
23
27
|
export * from './runtime.js';
|
|
24
28
|
export * from './seal-verify.js';
|
|
25
29
|
export * from './standing.js';
|
|
30
|
+
export * from './status.js';
|
|
26
31
|
export * from './task-templates.js';
|
|
27
32
|
export * from './tasks.js';
|
|
28
33
|
export * from './top-dimensions.js';
|
package/dist/policy.d.ts
CHANGED
package/dist/policy.js
CHANGED