@usenaive-sdk/blueprints 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/index.d.ts +238 -66
- package/dist/index.js +1275 -678
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -3,9 +3,9 @@ var ALPHABET = "0123456789abcdefghjkmnpqrstvwxyz";
|
|
|
3
3
|
var SUFFIX_LENGTH = 26;
|
|
4
4
|
var SUFFIX_PATTERN = new RegExp(`^[${ALPHABET}]{${SUFFIX_LENGTH},}$`);
|
|
5
5
|
function isId(prefix, value) {
|
|
6
|
-
const
|
|
7
|
-
if (!value.startsWith(
|
|
8
|
-
return SUFFIX_PATTERN.test(value.slice(
|
|
6
|
+
const head2 = `${prefix}_`;
|
|
7
|
+
if (!value.startsWith(head2)) return false;
|
|
8
|
+
return SUFFIX_PATTERN.test(value.slice(head2.length).toLowerCase());
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
// ../core/src/errors.ts
|
|
@@ -15,6 +15,8 @@ var CODES = {
|
|
|
15
15
|
unauthorized: ["authentication", 401],
|
|
16
16
|
forbidden: ["permission", 403],
|
|
17
17
|
not_found: ["not_found", 404],
|
|
18
|
+
/** The path exists; the method does not. The response carries `Allow` (§3). */
|
|
19
|
+
method_not_allowed: ["invalid_request", 405],
|
|
18
20
|
budget_exceeded: ["quota", 402],
|
|
19
21
|
insufficient_credits: ["quota", 402],
|
|
20
22
|
/**
|
|
@@ -143,6 +145,8 @@ var AUDIT_ACTIONS_P1 = [
|
|
|
143
145
|
"computer.resumed",
|
|
144
146
|
"computer.snapshot_created",
|
|
145
147
|
"computer.updated",
|
|
148
|
+
"computer.taken_over",
|
|
149
|
+
"computer.handed_back",
|
|
146
150
|
"browser.live_view_opened",
|
|
147
151
|
"deployment.created",
|
|
148
152
|
"deployment.updated",
|
|
@@ -278,7 +282,7 @@ var JsonSchemaDocument = z.record(z.string(), z.unknown()).refine((schema) => sc
|
|
|
278
282
|
var WindowSchema = z.enum(["immediate", "priority", "loose"]);
|
|
279
283
|
var TOKEN_TIERS = ["input", "cache_write", "cache_read", "output", "reasoning"];
|
|
280
284
|
var TokenTierSchema = z.enum(TOKEN_TIERS);
|
|
281
|
-
var TOOL_TIERS = ["search", "media", "social", "browser", "storage"];
|
|
285
|
+
var TOOL_TIERS = ["search", "media", "social", "browser", "storage", "email"];
|
|
282
286
|
var LINE_ITEM_TIERS = [...TOKEN_TIERS, "computer", ...TOOL_TIERS];
|
|
283
287
|
var LineItemTierSchema = z.enum(LINE_ITEM_TIERS);
|
|
284
288
|
var TokenUsageSchema = z.object({
|
|
@@ -308,11 +312,41 @@ import { z as z4 } from "zod";
|
|
|
308
312
|
|
|
309
313
|
// ../core/src/schema/org.ts
|
|
310
314
|
import { z as z3 } from "zod";
|
|
315
|
+
var DEFAULT_ORG_TIMEZONE = "America/New_York";
|
|
316
|
+
function canonicalZone(name) {
|
|
317
|
+
if (!name.includes("/") && name !== "UTC") return void 0;
|
|
318
|
+
try {
|
|
319
|
+
const zone = new Intl.DateTimeFormat("en-US", { timeZone: name }).resolvedOptions().timeZone;
|
|
320
|
+
return zone === "UTC" || Intl.supportedValuesOf("timeZone").includes(zone) ? zone : void 0;
|
|
321
|
+
} catch {
|
|
322
|
+
return void 0;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
var TimezoneSchema = z3.string().transform((name, ctx) => {
|
|
326
|
+
const zone = canonicalZone(name);
|
|
327
|
+
if (zone === void 0) {
|
|
328
|
+
ctx.addIssue({ code: "custom", message: "not a timezone; use an IANA name such as America/Los_Angeles" });
|
|
329
|
+
return z3.NEVER;
|
|
330
|
+
}
|
|
331
|
+
return zone;
|
|
332
|
+
});
|
|
311
333
|
var OrganizationSchema = z3.object({
|
|
312
334
|
id: idOf("org"),
|
|
313
335
|
object: z3.literal("organization"),
|
|
314
336
|
name: z3.string(),
|
|
315
337
|
balance_micro_usd: MicroUsdField,
|
|
338
|
+
/**
|
|
339
|
+
* The company's timezone, an IANA name (`America/New_York`, §20.6). Times the company chooses or
|
|
340
|
+
* reads are in it: a new routine's zone, when a post goes out. `America/New_York` until changed.
|
|
341
|
+
* Defaulted so a reply from a control plane older than 0088 (or a rolled-back Worker) still parses
|
|
342
|
+
* in a newer SDK/CLI rather than throwing on every `orgs.get/list/update`.
|
|
343
|
+
*/
|
|
344
|
+
timezone: z3.string().min(1).default(DEFAULT_ORG_TIMEZONE),
|
|
345
|
+
/**
|
|
346
|
+
* The company's logo, an SVG a person or an agent drew (§20.7), passed by `checkLogoSvg`. `null`
|
|
347
|
+
* until one is set. Defaulted so a reply from a control plane older than 0093 still parses.
|
|
348
|
+
*/
|
|
349
|
+
logo_svg: z3.string().nullable().default(null),
|
|
316
350
|
created_at: Timestamp
|
|
317
351
|
});
|
|
318
352
|
var RoleSchema = z3.enum(["owner", "admin", "member"]);
|
|
@@ -429,7 +463,7 @@ var BROWSER_TOOL_ACTIONS = [
|
|
|
429
463
|
"save_context"
|
|
430
464
|
];
|
|
431
465
|
var BrowserOptionsSchema = z4.object({
|
|
432
|
-
allowed_domains: z4.array(z4.string().min(1)).min(1),
|
|
466
|
+
allowed_domains: z4.array(z4.string().min(1)).min(1).default(["*"]),
|
|
433
467
|
timeout_minutes: z4.number().int().min(1).max(BROWSER_MAX_TIMEOUT_MINUTES).default(15),
|
|
434
468
|
region: z4.enum(BROWSER_REGIONS).default("us-west"),
|
|
435
469
|
keep_alive: z4.boolean().default(false),
|
|
@@ -664,7 +698,7 @@ function normaliseMultiagent(value) {
|
|
|
664
698
|
}
|
|
665
699
|
var HandoffsField = z6.union([z6.boolean(), z6.literal("team"), z6.array(z6.string().min(1)).max(50)]);
|
|
666
700
|
var handoffsOf = (config) => config.handoffs ?? true;
|
|
667
|
-
var handoffsEnabled = (handoffs) => handoffs
|
|
701
|
+
var handoffsEnabled = (handoffs) => handoffs !== false;
|
|
668
702
|
var agentConfigShape = {
|
|
669
703
|
model: z6.string(),
|
|
670
704
|
window: WindowSchema,
|
|
@@ -710,6 +744,22 @@ var SessionStatusSchema = z7.enum([
|
|
|
710
744
|
"failed",
|
|
711
745
|
"cancelled"
|
|
712
746
|
]);
|
|
747
|
+
var SessionModeSchema = z7.enum(["plan", "build"]);
|
|
748
|
+
var PLAN_MAX_CHARS = 2e4;
|
|
749
|
+
var PlanSchema = z7.object({
|
|
750
|
+
object: z7.literal("plan"),
|
|
751
|
+
markdown: z7.string().max(PLAN_MAX_CHARS),
|
|
752
|
+
version: z7.number().int().nonnegative(),
|
|
753
|
+
by: z7.enum(["agent", "owner"]).nullable()
|
|
754
|
+
});
|
|
755
|
+
var PlanWriteSchema = z7.object({
|
|
756
|
+
markdown: z7.string().max(PLAN_MAX_CHARS),
|
|
757
|
+
base_version: z7.number().int().nonnegative()
|
|
758
|
+
});
|
|
759
|
+
var ProposePlanSchema = z7.object({
|
|
760
|
+
version: z7.number().int().positive(),
|
|
761
|
+
spends_or_publishes: z7.array(z7.string().min(1).max(200)).max(10).optional()
|
|
762
|
+
});
|
|
713
763
|
var StopReasonSchema = z7.enum([
|
|
714
764
|
"end_turn",
|
|
715
765
|
"awaiting_input",
|
|
@@ -743,7 +793,8 @@ var MessageSchema = z7.object({
|
|
|
743
793
|
tool_call_id: z7.string().optional()
|
|
744
794
|
});
|
|
745
795
|
var ToolImageSchema = z7.object({
|
|
746
|
-
|
|
796
|
+
file_id: idOf("fil"),
|
|
797
|
+
url: z7.string().url().describe("A short-lived signed read for the file's bytes."),
|
|
747
798
|
media_type: z7.enum(["image/png", "image/jpeg", "image/gif", "image/webp"])
|
|
748
799
|
});
|
|
749
800
|
var ToolResultSchema = z7.object({
|
|
@@ -801,16 +852,26 @@ var QuestionFieldSchema = z7.discriminatedUnion("type", [
|
|
|
801
852
|
other: z7.boolean().default(true)
|
|
802
853
|
})
|
|
803
854
|
]);
|
|
855
|
+
var QUESTION_FIELDS_MAX = 3;
|
|
804
856
|
var QuestionSchema = z7.object({
|
|
805
857
|
prompt: z7.string().min(1).max(1e3),
|
|
806
|
-
fields: z7.array(QuestionFieldSchema).min(1).max(
|
|
858
|
+
fields: z7.array(QuestionFieldSchema).min(1).max(QUESTION_FIELDS_MAX, {
|
|
859
|
+
message: `a question has at most ${QUESTION_FIELDS_MAX} fields \u2014 ask the rest in a second question once these are answered`
|
|
860
|
+
})
|
|
807
861
|
});
|
|
808
|
-
var
|
|
862
|
+
var answersOf = (max, message3) => z7.record(
|
|
809
863
|
z7.string().min(1).max(64),
|
|
810
864
|
z7.union([z7.string().max(2e3), z7.array(z7.string().max(2e3)).min(1).max(12)])
|
|
811
|
-
).refine((answers) => Object.keys(answers).length <=
|
|
812
|
-
|
|
813
|
-
|
|
865
|
+
).refine((answers) => Object.keys(answers).length <= max, { message: message3 });
|
|
866
|
+
var AnswersSchema = answersOf(
|
|
867
|
+
QUESTION_FIELDS_MAX,
|
|
868
|
+
`a question has at most ${QUESTION_FIELDS_MAX} fields, so an answer has at most ${QUESTION_FIELDS_MAX} keys`
|
|
869
|
+
);
|
|
870
|
+
var TEMPLATE_QUESTIONS_MAX = 4;
|
|
871
|
+
var InstallAnswersSchema = answersOf(
|
|
872
|
+
TEMPLATE_QUESTIONS_MAX,
|
|
873
|
+
`a template asks at most ${TEMPLATE_QUESTIONS_MAX} questions, so an install has at most ${TEMPLATE_QUESTIONS_MAX} answers`
|
|
874
|
+
);
|
|
814
875
|
var PendingActionSchema = z7.object({
|
|
815
876
|
kind: z7.enum(["tool", "question"]).default("tool"),
|
|
816
877
|
tool_call_id: z7.string(),
|
|
@@ -851,6 +912,13 @@ var SessionSchema = z7.object({
|
|
|
851
912
|
parent_session_id: idOf("ses").nullable(),
|
|
852
913
|
root_session_id: idOf("ses").nullable(),
|
|
853
914
|
thread_role: ThreadRoleSchema.nullable(),
|
|
915
|
+
/**
|
|
916
|
+
* The model the latest send picked (§7 `model`), or `null` when none has and the session runs its
|
|
917
|
+
* pinned version's model (§10, ADR-0832). Defaulted so a reply from an older control plane parses.
|
|
918
|
+
*/
|
|
919
|
+
model: z7.string().nullable().default(null),
|
|
920
|
+
/** Plan mode (§7.5, §10): defaulted so a reply from an older control plane parses as `build`. */
|
|
921
|
+
mode: SessionModeSchema.default("build"),
|
|
854
922
|
status: SessionStatusSchema,
|
|
855
923
|
stop_reason: StopReasonSchema.nullable(),
|
|
856
924
|
window: WindowSchema,
|
|
@@ -870,6 +938,10 @@ var SendMessageSchema = z7.object({
|
|
|
870
938
|
message: z7.string(),
|
|
871
939
|
interrupt: z7.boolean().optional(),
|
|
872
940
|
queue: z7.boolean().optional(),
|
|
941
|
+
/** A catalogue id: this session runs on it from this message's turn on (§7, ADR-0832). */
|
|
942
|
+
model: z7.string().min(1).optional(),
|
|
943
|
+
/** Plan mode from this message's turn on (§7.5, ADR-0905). */
|
|
944
|
+
mode: SessionModeSchema.optional(),
|
|
873
945
|
idempotency_key: z7.string().optional()
|
|
874
946
|
}).refine((body) => !(body.interrupt === true && body.queue === true), {
|
|
875
947
|
message: "a send is either an interrupt or queued, not both",
|
|
@@ -884,7 +956,14 @@ var ToolConfirmationSchema = z7.object({
|
|
|
884
956
|
tool_call_id: z7.string(),
|
|
885
957
|
decision: z7.enum(["allow", "deny"]),
|
|
886
958
|
reason: z7.string().optional(),
|
|
887
|
-
scope: z7.enum(["call", "session"]).default("call")
|
|
959
|
+
scope: z7.enum(["call", "session"]).default("call"),
|
|
960
|
+
/**
|
|
961
|
+
* THE PERSON'S OWN ANSWERS for a template install they approve (ADR-1030): the call runs with
|
|
962
|
+
* these in place of the `answers` the agent proposed, and with nothing else changed. A modifier on
|
|
963
|
+
* `allow`, like `scope`: absent is the call as proposed. The route refuses it on a deny, on a session
|
|
964
|
+
* grant, on any other tool, and on answers the template's questions refuse (`answerProblems`).
|
|
965
|
+
*/
|
|
966
|
+
answers: InstallAnswersSchema.optional()
|
|
888
967
|
});
|
|
889
968
|
var SessionAnswerSchema = z7.object({
|
|
890
969
|
tool_call_id: z7.string(),
|
|
@@ -895,6 +974,11 @@ var SessionAnswerSchema = z7.object({
|
|
|
895
974
|
import { z as z8 } from "zod";
|
|
896
975
|
var EventTypeSchema = z8.enum([
|
|
897
976
|
"message.delta",
|
|
977
|
+
/**
|
|
978
|
+
* The agent's answer (no `role`), or a user row `{ role: "user", content, client_message_id? }` (§8).
|
|
979
|
+
* A user row the runtime wrote itself — a media job's result, a tool grant — carries
|
|
980
|
+
* `from: "platform"` and is the platform's notice, not a caller's words (§8, ADR-0870).
|
|
981
|
+
*/
|
|
898
982
|
"message.completed",
|
|
899
983
|
/** A caller's message, durable in the inbox and not yet admitted to a turn (§7, §8): `{ client_message_id, content }`. */
|
|
900
984
|
"message.accepted",
|
|
@@ -903,19 +987,28 @@ var EventTypeSchema = z8.enum([
|
|
|
903
987
|
"tool.started",
|
|
904
988
|
"tool.completed",
|
|
905
989
|
"tool.confirm",
|
|
990
|
+
/** A person's decision on a parked call, stamped with the inbox write that delivers it (§8, ADR-0764). */
|
|
991
|
+
"tool.confirm.resolved",
|
|
992
|
+
/** A person's answer to a parked question, stamped the same way (§7.1, §8, ADR-1049). */
|
|
993
|
+
"tool.confirm.answered",
|
|
906
994
|
"session.running",
|
|
907
995
|
"session.usage",
|
|
908
996
|
"session.idle",
|
|
909
997
|
/** A failed attempt the loop will retry (§8): `{ attempt, in_ms, code }`. */
|
|
910
998
|
"session.retrying",
|
|
999
|
+
/** The session's mode changed (§7.5): `{ mode: "plan" | "build" }`. */
|
|
1000
|
+
"session.mode",
|
|
1001
|
+
/** A write to the session's plan, by the agent or its owner (§7.5): the plan object. */
|
|
1002
|
+
"plan.updated",
|
|
911
1003
|
/**
|
|
912
1004
|
* The turn ran, but without something it needed (§8): `{ reason, detail? }`.
|
|
913
1005
|
*
|
|
914
1006
|
* Emitted for a turn whose sandbox could not be woken. That turn used to be indistinguishable
|
|
915
1007
|
* from a success — the model was handed the failure as a tool result, answered around it from the
|
|
916
1008
|
* transcript, and the session ended `idle`/`end_turn` with no field anywhere saying the
|
|
917
|
-
* filesystem had been unavailable. This is the field. `reason` is open on purpose; today
|
|
918
|
-
*
|
|
1009
|
+
* filesystem had been unavailable. This is the field. `reason` is open on purpose; today it is
|
|
1010
|
+
* `"sandbox_unavailable"`, `"vendor_resume_unavailable"`, or `"app_tools_unavailable"` — an app the
|
|
1011
|
+
* agent's toolset names gave no tools this turn (§29.5, `runtime-do app-mcp-tools.ts`).
|
|
919
1012
|
*
|
|
920
1013
|
* `detail` is the boot failure's own message, and it is here because `reason` alone reads the
|
|
921
1014
|
* same for a vendor outage and for a fault of ours. Staging round 3 spent its whole budget
|
|
@@ -1003,6 +1096,21 @@ var EventSchema = z8.object({
|
|
|
1003
1096
|
created_at: Timestamp
|
|
1004
1097
|
});
|
|
1005
1098
|
var ThreadEventDataSchema = z8.looseObject({ thread_id: idOf("ses") });
|
|
1099
|
+
var ToolConfirmResolvedDataSchema = z8.object({
|
|
1100
|
+
tool_call_id: z8.string(),
|
|
1101
|
+
decision: z8.enum(["allow", "deny"]),
|
|
1102
|
+
reason: z8.string().nullable(),
|
|
1103
|
+
scope: z8.enum(["call", "session"]),
|
|
1104
|
+
actor: PrincipalSchema.nullable(),
|
|
1105
|
+
decided_at: Timestamp,
|
|
1106
|
+
proposed_args: z8.record(z8.string(), z8.unknown()).nullable(),
|
|
1107
|
+
final_args: z8.record(z8.string(), z8.unknown()).nullable()
|
|
1108
|
+
});
|
|
1109
|
+
var ToolConfirmAnsweredDataSchema = z8.object({
|
|
1110
|
+
tool_call_id: z8.string(),
|
|
1111
|
+
answers: AnswersSchema,
|
|
1112
|
+
answered_at: Timestamp
|
|
1113
|
+
});
|
|
1006
1114
|
var SessionUsageDataSchema = z8.object({
|
|
1007
1115
|
token_usage: TokenUsageSchema,
|
|
1008
1116
|
consumed_micro_usd: MicroUsdField.nonnegative(),
|
|
@@ -1107,7 +1215,10 @@ var FileSourceTypeSchema = z11.enum(FILE_SOURCE_TYPES);
|
|
|
1107
1215
|
var FileSourceSchema = z11.object({
|
|
1108
1216
|
type: FileSourceTypeSchema,
|
|
1109
1217
|
job_id: z11.union([idOf("med"), idOf("clj")]).nullable(),
|
|
1110
|
-
url: z11.string().url().nullable()
|
|
1218
|
+
url: z11.string().url().nullable(),
|
|
1219
|
+
/** What a generator was asked with (§36.1, ADR-0886); absent on every other writer's row. */
|
|
1220
|
+
model: z11.string().nullable().optional(),
|
|
1221
|
+
prompt: z11.string().nullable().optional()
|
|
1111
1222
|
});
|
|
1112
1223
|
var FileTagsSchema = z11.array(z11.string().min(1).max(64)).max(32);
|
|
1113
1224
|
var FileLibraryFieldsSchema = z11.object({
|
|
@@ -1152,6 +1263,11 @@ var ComputerSchema = z12.object({
|
|
|
1152
1263
|
browser: BrowserOptionsSchema.nullable(),
|
|
1153
1264
|
volume: VolumeSchema.nullable(),
|
|
1154
1265
|
snapshot_id: idOf("snp").nullable(),
|
|
1266
|
+
/**
|
|
1267
|
+
* The agent this computer belongs to (§41.8, ADR-0849); `null` for one made by `POST /v1/computers`.
|
|
1268
|
+
* Defaulted so a reply from an older control plane parses.
|
|
1269
|
+
*/
|
|
1270
|
+
agent_id: idOf("agt").nullable().default(null),
|
|
1155
1271
|
created_at: Timestamp
|
|
1156
1272
|
});
|
|
1157
1273
|
var SnapshotSchema = z12.object({
|
|
@@ -1260,7 +1376,9 @@ var FileSchema = z12.object({
|
|
|
1260
1376
|
sha256: z12.string().regex(/^[0-9a-f]{64}$/),
|
|
1261
1377
|
created_at: Timestamp,
|
|
1262
1378
|
// The asset-library fields (`canonical-spec §36.1`), all nullable or defaulted.
|
|
1263
|
-
...FileLibraryFieldsSchema.shape
|
|
1379
|
+
...FileLibraryFieldsSchema.shape,
|
|
1380
|
+
/** The agent of `session_id`, joined at read (§36.1, ADR-0887); a writer never sets it. */
|
|
1381
|
+
agent_id: idOf("agt").nullable().optional()
|
|
1264
1382
|
});
|
|
1265
1383
|
var ScheduleStatusSchema = z12.enum(["scheduled", "paused", "unscheduled"]);
|
|
1266
1384
|
var DeploymentSchema = z12.object({
|
|
@@ -1382,7 +1500,27 @@ var InboundMessageSchema = z13.object({
|
|
|
1382
1500
|
auth: z13.record(z13.string(), z13.string()),
|
|
1383
1501
|
/** The session this message woke. Null until the wake seam lands (see ADR-0120). */
|
|
1384
1502
|
session_id: idOf("ses").nullable(),
|
|
1385
|
-
received_at: Timestamp
|
|
1503
|
+
received_at: Timestamp,
|
|
1504
|
+
/**
|
|
1505
|
+
* When a person marked it read (`POST …/messages/{mid}/read`); `null` is unread. Defaulted so a
|
|
1506
|
+
* reply from an older control plane parses (ADR-1076).
|
|
1507
|
+
*/
|
|
1508
|
+
read_at: Timestamp.nullable().default(null)
|
|
1509
|
+
});
|
|
1510
|
+
var OutboundMessageSchema = z13.object({
|
|
1511
|
+
id: idOf("out"),
|
|
1512
|
+
object: z13.literal("outbound_message"),
|
|
1513
|
+
channel: InboundMessageSchema.shape.channel,
|
|
1514
|
+
identity_id: idOf("idn"),
|
|
1515
|
+
/** The `eml_` endpoint it was sent from. */
|
|
1516
|
+
endpoint_id: z13.string(),
|
|
1517
|
+
from: z13.string(),
|
|
1518
|
+
to: z13.array(z13.string()),
|
|
1519
|
+
subject: z13.string().nullable(),
|
|
1520
|
+
text: z13.string(),
|
|
1521
|
+
sent_by_agent_id: idOf("agt").nullable(),
|
|
1522
|
+
actor: PrincipalSchema.nullable(),
|
|
1523
|
+
sent_at: Timestamp
|
|
1386
1524
|
});
|
|
1387
1525
|
|
|
1388
1526
|
// ../core/src/schema/app.ts
|
|
@@ -1462,6 +1600,11 @@ var AppDomainSchema = z14.object({
|
|
|
1462
1600
|
});
|
|
1463
1601
|
var ENV_NAME = /^[A-Z_][A-Z0-9_]*$/;
|
|
1464
1602
|
var APP_NAME = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
1603
|
+
var AppPermissionsSchema = z14.object({
|
|
1604
|
+
object: z14.literal("app_permissions"),
|
|
1605
|
+
app_id: idOf("app"),
|
|
1606
|
+
scopes: z14.array(z14.string())
|
|
1607
|
+
});
|
|
1465
1608
|
|
|
1466
1609
|
// ../core/src/schema/install.ts
|
|
1467
1610
|
import { z as z15 } from "zod";
|
|
@@ -1561,7 +1704,10 @@ var BlueprintInstallSchema = z15.object({
|
|
|
1561
1704
|
*/
|
|
1562
1705
|
report: BlueprintReportSchema.nullable(),
|
|
1563
1706
|
status: BlueprintInstallStatusSchema,
|
|
1564
|
-
/**
|
|
1707
|
+
/**
|
|
1708
|
+
* Why a `failed` run threw, in one sentence — or, on an `applied` row, which `required` agent or
|
|
1709
|
+
* app the apply refused and why (§29.6). `null` otherwise. Never a stack or a key.
|
|
1710
|
+
*/
|
|
1565
1711
|
failure: z15.string().nullable(),
|
|
1566
1712
|
/**
|
|
1567
1713
|
* The `selection` the apply carried, or `null` — every row written before §31.2 and every apply
|
|
@@ -1681,6 +1827,39 @@ var SocialCommentSchema = z16.object({
|
|
|
1681
1827
|
posted_at: Timestamp.nullable(),
|
|
1682
1828
|
data: z16.unknown()
|
|
1683
1829
|
});
|
|
1830
|
+
var POST_STATUSES = ["pending", "scheduled", "posted", "failed"];
|
|
1831
|
+
var PostStatusSchema = z16.enum(POST_STATUSES);
|
|
1832
|
+
var PostSchema = z16.object({
|
|
1833
|
+
object: z16.literal("post"),
|
|
1834
|
+
id: z16.string().min(1),
|
|
1835
|
+
status: PostStatusSchema,
|
|
1836
|
+
identity_id: z16.string().nullable(),
|
|
1837
|
+
agent_id: z16.string().nullable(),
|
|
1838
|
+
session_id: z16.string().nullable(),
|
|
1839
|
+
tool_call_id: z16.string().nullable(),
|
|
1840
|
+
content: z16.string().nullable(),
|
|
1841
|
+
platforms: z16.array(z16.string()),
|
|
1842
|
+
file_ids: z16.array(z16.string()),
|
|
1843
|
+
media_urls: z16.array(z16.string()),
|
|
1844
|
+
visibility: SocialVisibilitySchema.nullable(),
|
|
1845
|
+
scheduled_at: Timestamp.nullable(),
|
|
1846
|
+
posted_at: Timestamp.nullable(),
|
|
1847
|
+
url: z16.string().nullable(),
|
|
1848
|
+
error: z16.string().nullable(),
|
|
1849
|
+
/** The latest stored reading, `{metric: value}`; `null` before `social.post_metrics` read any. */
|
|
1850
|
+
metrics: z16.record(z16.string(), z16.number()).nullable(),
|
|
1851
|
+
measured_at: Timestamp.nullable(),
|
|
1852
|
+
/** Pending only: the earlier post this call would repeat — same identity, network and file. */
|
|
1853
|
+
duplicate_of: z16.object({
|
|
1854
|
+
id: z16.string(),
|
|
1855
|
+
status: PostStatusSchema,
|
|
1856
|
+
platform: z16.string(),
|
|
1857
|
+
at: Timestamp.nullable(),
|
|
1858
|
+
agent_id: z16.string().nullable(),
|
|
1859
|
+
session_id: z16.string().nullable()
|
|
1860
|
+
}).nullable(),
|
|
1861
|
+
created_at: Timestamp
|
|
1862
|
+
});
|
|
1684
1863
|
|
|
1685
1864
|
// ../core/src/schema/blueprint.ts
|
|
1686
1865
|
var BlueprintScheduleSchema = z17.object({
|
|
@@ -1714,16 +1893,9 @@ var BlueprintAppSchema = z17.object({
|
|
|
1714
1893
|
/** Whether an install may deselect it (§31.2). Optional: the rollout argument above. */
|
|
1715
1894
|
required: z17.boolean().optional()
|
|
1716
1895
|
});
|
|
1717
|
-
var BlueprintIdentityConnectionsSchema = z17.object({
|
|
1718
|
-
social: z17.object({
|
|
1719
|
-
from: z17.string().min(1),
|
|
1720
|
-
map: z17.record(z17.string().min(1), SocialPlatformSchema)
|
|
1721
|
-
}).optional()
|
|
1722
|
-
});
|
|
1723
1896
|
var BlueprintIdentitySchema = z17.object({
|
|
1724
1897
|
name: z17.string().min(1),
|
|
1725
|
-
description: z17.string().nullable()
|
|
1726
|
-
connections: BlueprintIdentityConnectionsSchema.optional()
|
|
1898
|
+
description: z17.string().nullable()
|
|
1727
1899
|
});
|
|
1728
1900
|
var ContentHashSchema = z17.string().regex(/^[0-9a-f]{64}$/, "a lowercase sha-256 hex digest");
|
|
1729
1901
|
var BlueprintTreeSchema = z17.object({
|
|
@@ -1741,11 +1913,18 @@ var BlueprintArtifactSchema = z17.object({
|
|
|
1741
1913
|
/** The blueprint repository's own released version. Stored, never parsed (ADR-0401). */
|
|
1742
1914
|
version: z17.string().min(1),
|
|
1743
1915
|
/**
|
|
1744
|
-
*
|
|
1745
|
-
*
|
|
1746
|
-
*
|
|
1916
|
+
* What a person calls the template, one line on what its crew does, and the networks it publishes
|
|
1917
|
+
* to — printed, never provisioned (§31.5, ADR-0921). `platforms` is decoration: where the crew
|
|
1918
|
+
* posts is the accounts connected to its persona. Optional for the §31.5 rollout reason.
|
|
1747
1919
|
*/
|
|
1748
|
-
|
|
1920
|
+
title: z17.string().min(1).optional(),
|
|
1921
|
+
description: z17.string().min(1).optional(),
|
|
1922
|
+
platforms: z17.array(SocialPlatformSchema).optional(),
|
|
1923
|
+
/**
|
|
1924
|
+
* The built trees, one per deployable app, ordered as the declaration orders its apps. Empty for
|
|
1925
|
+
* a data-only blueprint: it declares no app, builds nothing, and still ships a crew (ADR-0900).
|
|
1926
|
+
*/
|
|
1927
|
+
trees: z17.array(BlueprintTreeSchema),
|
|
1749
1928
|
/**
|
|
1750
1929
|
* The setup questions, asked by the studio **before** provisioning. `QuestionField` (§7.1) is
|
|
1751
1930
|
* reused rather than restated: a setup question and a question a parked agent asks are the same
|
|
@@ -1857,37 +2036,241 @@ var ChannelPostSchema = z19.object({
|
|
|
1857
2036
|
queued: z19.boolean()
|
|
1858
2037
|
});
|
|
1859
2038
|
|
|
1860
|
-
// ../core/src/schema/
|
|
2039
|
+
// ../core/src/schema/show.ts
|
|
1861
2040
|
import { z as z20 } from "zod";
|
|
1862
|
-
var
|
|
1863
|
-
var
|
|
1864
|
-
var
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
2041
|
+
var SHOW_SOURCES = ["spend_by_day", "post_views", "roadmap", "schedule"];
|
|
2042
|
+
var ShowSourceSchema = z20.enum(SHOW_SOURCES);
|
|
2043
|
+
var ShowArgsSchema = z20.object({
|
|
2044
|
+
source: ShowSourceSchema.describe(
|
|
2045
|
+
"What to show: spend_by_day (company spend per day, a line), post_views (views per recent post, bars), roadmap (the board's work by status), schedule (routines and scheduled posts over the next 7 days)."
|
|
2046
|
+
),
|
|
2047
|
+
days: z20.number().int().min(2).max(30).optional().describe("spend_by_day only: days back, today included. Default 14.")
|
|
2048
|
+
});
|
|
2049
|
+
var Day = z20.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
2050
|
+
var Count = z20.number().int().nonnegative();
|
|
2051
|
+
var head = { title: z20.string().min(1), as_of: Timestamp, timezone: z20.string().min(1) };
|
|
2052
|
+
var SpendByDayViewSchema = z20.object({
|
|
2053
|
+
source: z20.literal("spend_by_day"),
|
|
2054
|
+
...head,
|
|
2055
|
+
days: z20.array(z20.object({ day: Day, micro_usd: Count })).min(2).max(30)
|
|
2056
|
+
});
|
|
2057
|
+
var PostViewsViewSchema = z20.object({
|
|
2058
|
+
source: z20.literal("post_views"),
|
|
2059
|
+
...head,
|
|
2060
|
+
posts: z20.array(z20.object({ post_id: z20.string().min(1), label: z20.string(), networks: z20.array(z20.string()), posted_at: Timestamp, views: Count })).max(12)
|
|
2061
|
+
});
|
|
2062
|
+
var RoadmapViewSchema = z20.object({
|
|
2063
|
+
source: z20.literal("roadmap"),
|
|
2064
|
+
...head,
|
|
2065
|
+
groups: z20.array(
|
|
2066
|
+
z20.object({
|
|
2067
|
+
status: BoardStatusSchema,
|
|
2068
|
+
count: Count,
|
|
2069
|
+
cards: z20.array(z20.object({ title: z20.string(), assignee: z20.string().nullable(), waits_on: z20.array(z20.string()) })).max(5)
|
|
2070
|
+
})
|
|
2071
|
+
)
|
|
2072
|
+
});
|
|
2073
|
+
var ScheduleViewSchema = z20.object({
|
|
2074
|
+
source: z20.literal("schedule"),
|
|
2075
|
+
...head,
|
|
2076
|
+
days: z20.array(
|
|
1870
2077
|
z20.object({
|
|
2078
|
+
day: Day,
|
|
2079
|
+
count: Count,
|
|
2080
|
+
items: z20.array(
|
|
2081
|
+
z20.discriminatedUnion("kind", [
|
|
2082
|
+
z20.object({ kind: z20.literal("routine"), at: Timestamp, agent: z20.string(), text: z20.string(), runs: z20.number().int().min(1).max(100) }),
|
|
2083
|
+
z20.object({ kind: z20.literal("post"), at: Timestamp, networks: z20.array(z20.string()), text: z20.string() })
|
|
2084
|
+
])
|
|
2085
|
+
).max(8)
|
|
2086
|
+
})
|
|
2087
|
+
).max(7)
|
|
2088
|
+
});
|
|
2089
|
+
var ShowViewSchema = z20.discriminatedUnion("source", [
|
|
2090
|
+
SpendByDayViewSchema,
|
|
2091
|
+
PostViewsViewSchema,
|
|
2092
|
+
RoadmapViewSchema,
|
|
2093
|
+
ScheduleViewSchema
|
|
2094
|
+
]);
|
|
2095
|
+
|
|
2096
|
+
// ../core/src/schema/compose.ts
|
|
2097
|
+
import { z as z22 } from "zod";
|
|
2098
|
+
|
|
2099
|
+
// ../core/src/schema/catalog.ts
|
|
2100
|
+
import { z as z21 } from "zod";
|
|
2101
|
+
var Key = z21.string().regex(/^[A-Za-z][A-Za-z0-9_-]{0,39}$/, "an element key is a short name: a letter, then letters, digits, - or _");
|
|
2102
|
+
var Count2 = z21.number().int().nonnegative();
|
|
2103
|
+
var DIGIT = "words only: a digit is refused, because every number on the card is read by code from a $source binding";
|
|
2104
|
+
var words = (max) => z21.string().trim().min(1).max(max).regex(/^[^0-9]*$/, DIGIT).refine((text) => !new RegExp("\\p{N}", "u").test(text), DIGIT);
|
|
2105
|
+
var Days = z21.number().int().min(1).max(30).default(7).describe("The window: today and the days before it, on the company's clock. Default 7.");
|
|
2106
|
+
function bound(sources2, shape) {
|
|
2107
|
+
const example = JSON.stringify({ $source: sources2[0] });
|
|
2108
|
+
return z21.strictObject(
|
|
2109
|
+
{ $source: z21.enum(sources2), ...shape },
|
|
2110
|
+
{ error: (issue) => issue.code === "invalid_type" ? `must be a binding such as ${example}: a literal value is refused, code reads every number` : void 0 }
|
|
2111
|
+
);
|
|
2112
|
+
}
|
|
2113
|
+
var Bound = {
|
|
2114
|
+
value: bound(["views_total", "spend_total"], { days: Days }).describe(
|
|
2115
|
+
"views_total: the latest views of the posts published in the window. spend_total: the company's spend in the window (the CEO only)."
|
|
2116
|
+
),
|
|
2117
|
+
delta: bound(["views_change"], {}).describe(
|
|
2118
|
+
"views_change: the value's views_total against the same number of days before it, as a percentage. Its window is the value's."
|
|
2119
|
+
),
|
|
2120
|
+
series: bound(["spend_by_day"], { days: z21.number().int().min(2).max(30).default(14) }).describe("spend_by_day: the company's spend per day (the CEO only)."),
|
|
2121
|
+
bars: bound(["post_views"], { limit: z21.number().int().min(1).max(12).default(5).describe("How many posts, newest first. Default 5.") }).describe(
|
|
2122
|
+
"post_views: each recent post's latest views, newest first."
|
|
2123
|
+
),
|
|
2124
|
+
progress: bound(["posts_this_week"], {}).describe("posts_this_week: posts published since Monday against the weekly cadence from the company's setup."),
|
|
2125
|
+
board: bound(["roadmap"], {}).describe("roadmap: the board's work by status."),
|
|
2126
|
+
week: bound(["schedule"], {}).describe("schedule: routines and scheduled posts over the next 7 days."),
|
|
2127
|
+
media: z21.union([bound(["latest_media"], { count: z21.number().int().min(1).max(4).default(1) }), z21.array(idOf("fil")).min(1).max(4)]).describe('{"$source":"latest_media","count":1} for the newest posted pictures or clips, or up to 4 fil_ ids.')
|
|
2128
|
+
};
|
|
2129
|
+
var SpendDay = z21.strictObject({ day: z21.string().regex(/^\d{4}-\d{2}-\d{2}$/), micro_usd: Count2 });
|
|
2130
|
+
var Resolved = {
|
|
2131
|
+
value: z21.discriminatedUnion("$source", [
|
|
2132
|
+
z21.strictObject({ $source: z21.literal("views_total"), days: z21.number().int(), value: Count2, posts: Count2 }),
|
|
2133
|
+
z21.strictObject({ $source: z21.literal("spend_total"), days: z21.number().int(), value: Count2 })
|
|
2134
|
+
]),
|
|
2135
|
+
delta: z21.strictObject({ $source: z21.literal("views_change"), days: z21.number().int(), current: Count2, previous: Count2 }),
|
|
2136
|
+
series: z21.strictObject({ $source: z21.literal("spend_by_day"), days: z21.number().int(), points: z21.array(SpendDay).min(2).max(30) }),
|
|
2137
|
+
bars: z21.strictObject({ $source: z21.literal("post_views"), limit: z21.number().int(), posts: PostViewsViewSchema.shape.posts }),
|
|
2138
|
+
progress: z21.strictObject({ $source: z21.literal("posts_this_week"), value: Count2, max: z21.number().int().positive(), cadence: z21.string() }),
|
|
2139
|
+
board: z21.strictObject({ $source: z21.literal("roadmap"), groups: RoadmapViewSchema.shape.groups }),
|
|
2140
|
+
week: z21.strictObject({ $source: z21.literal("schedule"), days: ScheduleViewSchema.shape.days }),
|
|
2141
|
+
media: z21.array(z21.strictObject({ id: idOf("fil"), kind: z21.enum(["image", "video"]) })).min(1).max(4)
|
|
2142
|
+
};
|
|
2143
|
+
var box = { children: z21.array(Key).min(1).max(12) };
|
|
2144
|
+
var leaf = { children: z21.array(Key).max(0).optional() };
|
|
2145
|
+
var label = words(40).optional();
|
|
2146
|
+
var element = (type, props, children, about) => z21.strictObject({ type: z21.literal(type), props: z21.strictObject(props), ...children }).describe(about);
|
|
2147
|
+
function catalog(slot) {
|
|
2148
|
+
return {
|
|
2149
|
+
Card: element("Card", { title: words(60) }, box, "The card, with a short title. It is the root, and only the root."),
|
|
2150
|
+
Stack: element("Stack", {}, box, "Children one under another."),
|
|
2151
|
+
Grid: element("Grid", { columns: z21.literal([1, 2, 3]) }, box, "Children side by side, 1 to 3 columns."),
|
|
2152
|
+
Metric: element("Metric", { label: words(40), value: slot.value, delta: slot.delta.optional() }, leaf, "One big number with a label, and optionally its change."),
|
|
2153
|
+
LineChart: element("LineChart", { label, series: slot.series }, leaf, "A line over days."),
|
|
2154
|
+
BarList: element("BarList", { label, bars: slot.bars }, leaf, "One bar per post."),
|
|
2155
|
+
Progress: element("Progress", { label: words(40), progress: slot.progress }, leaf, "A value against its goal, as a bar."),
|
|
2156
|
+
Roadmap: element("Roadmap", { label, board: slot.board }, leaf, "The board grouped by status."),
|
|
2157
|
+
Schedule: element("Schedule", { label, week: slot.week }, leaf, "The week ahead, day by day."),
|
|
2158
|
+
Media: element("Media", { label, files: slot.media }, leaf, "Pictures or clips the company holds."),
|
|
2159
|
+
Text: element("Text", { text: words(240) }, leaf, "A short note in words.")
|
|
2160
|
+
};
|
|
2161
|
+
}
|
|
2162
|
+
var unknownComponent = (names) => ({
|
|
2163
|
+
error: (issue) => issue.code === "invalid_union" ? `unknown component: use one of ${names.join(", ")}` : void 0
|
|
2164
|
+
});
|
|
2165
|
+
function tree(rootType, max, spec2, ctx) {
|
|
2166
|
+
const refuse2 = (message3, path = []) => ctx.addIssue({ code: "custom", message: message3, path });
|
|
2167
|
+
const keys = Object.keys(spec2.elements);
|
|
2168
|
+
const has = (key) => Object.hasOwn(spec2.elements, key);
|
|
2169
|
+
if (keys.length > max) return refuse2(`at most ${max} elements`, ["elements"]);
|
|
2170
|
+
const root = has(spec2.root) ? spec2.elements[spec2.root] : void 0;
|
|
2171
|
+
if (!root) return refuse2(`root names "${spec2.root}", which is not in elements`, ["root"]);
|
|
2172
|
+
if (root.type !== rootType) return refuse2(`the root must be a ${rootType}`, ["root"]);
|
|
2173
|
+
const parent = /* @__PURE__ */ new Map();
|
|
2174
|
+
for (const key of keys) {
|
|
2175
|
+
for (const child of spec2.elements[key].children ?? []) {
|
|
2176
|
+
if (!has(child)) return refuse2(`"${child}" is not in elements`, ["elements", key, "children"]);
|
|
2177
|
+
if (child === spec2.root || parent.has(child)) return refuse2(`"${child}" has more than one parent`, ["elements", key, "children"]);
|
|
2178
|
+
if (spec2.elements[child].type === rootType) return refuse2(`a ${rootType} is the root only; group with Stack or Grid`, ["elements", child, "type"]);
|
|
2179
|
+
parent.set(child, key);
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
const reached = /* @__PURE__ */ new Set([spec2.root]);
|
|
2183
|
+
for (const key of reached) for (const child of spec2.elements[key].children ?? []) reached.add(child);
|
|
2184
|
+
const lost = keys.find((key) => !reached.has(key));
|
|
2185
|
+
if (lost) refuse2(`"${lost}" is not under the root`, ["elements", lost]);
|
|
2186
|
+
}
|
|
2187
|
+
var spec = (element2, rootType, max) => z21.strictObject({ root: Key, elements: z21.record(Key, element2) }).superRefine((value, ctx) => tree(rootType, max, value, ctx));
|
|
2188
|
+
|
|
2189
|
+
// ../core/src/schema/compose.ts
|
|
2190
|
+
var COMPOSE_COMPONENTS = ["Card", "Stack", "Grid", "Metric", "LineChart", "BarList", "Progress", "Roadmap", "Schedule", "Media", "Text"];
|
|
2191
|
+
var MAX_COMPOSE_ELEMENTS = 24;
|
|
2192
|
+
var BoundComponents = catalog(Bound);
|
|
2193
|
+
var ComposeSpecSchema = spec(
|
|
2194
|
+
z22.discriminatedUnion(
|
|
2195
|
+
"type",
|
|
2196
|
+
[
|
|
2197
|
+
BoundComponents.Card,
|
|
2198
|
+
BoundComponents.Stack,
|
|
2199
|
+
BoundComponents.Grid,
|
|
2200
|
+
BoundComponents.Metric,
|
|
2201
|
+
BoundComponents.LineChart,
|
|
2202
|
+
BoundComponents.BarList,
|
|
2203
|
+
BoundComponents.Progress,
|
|
2204
|
+
BoundComponents.Roadmap,
|
|
2205
|
+
BoundComponents.Schedule,
|
|
2206
|
+
BoundComponents.Media,
|
|
2207
|
+
BoundComponents.Text
|
|
2208
|
+
],
|
|
2209
|
+
unknownComponent(COMPOSE_COMPONENTS)
|
|
2210
|
+
),
|
|
2211
|
+
"Card",
|
|
2212
|
+
MAX_COMPOSE_ELEMENTS
|
|
2213
|
+
);
|
|
2214
|
+
var ComposeArgsSchema = z22.object({
|
|
2215
|
+
spec: ComposeSpecSchema.describe(
|
|
2216
|
+
'A json-render spec: { "root": key, "elements": { key: { "type", "props", "children"? } } }. The root is one Card.'
|
|
2217
|
+
)
|
|
2218
|
+
});
|
|
2219
|
+
var ComposedComponents = catalog(Resolved);
|
|
2220
|
+
var ComposedSpecSchema = spec(
|
|
2221
|
+
z22.discriminatedUnion(
|
|
2222
|
+
"type",
|
|
2223
|
+
[
|
|
2224
|
+
ComposedComponents.Card,
|
|
2225
|
+
ComposedComponents.Stack,
|
|
2226
|
+
ComposedComponents.Grid,
|
|
2227
|
+
ComposedComponents.Metric,
|
|
2228
|
+
ComposedComponents.LineChart,
|
|
2229
|
+
ComposedComponents.BarList,
|
|
2230
|
+
ComposedComponents.Progress,
|
|
2231
|
+
ComposedComponents.Roadmap,
|
|
2232
|
+
ComposedComponents.Schedule,
|
|
2233
|
+
ComposedComponents.Media,
|
|
2234
|
+
ComposedComponents.Text
|
|
2235
|
+
],
|
|
2236
|
+
unknownComponent(COMPOSE_COMPONENTS)
|
|
2237
|
+
),
|
|
2238
|
+
"Card",
|
|
2239
|
+
MAX_COMPOSE_ELEMENTS
|
|
2240
|
+
);
|
|
2241
|
+
var ComposedSchema = z22.object({ as_of: Timestamp, timezone: z22.string().min(1), spec: ComposedSpecSchema });
|
|
2242
|
+
|
|
2243
|
+
// ../core/src/schema/media.ts
|
|
2244
|
+
import { z as z23 } from "zod";
|
|
2245
|
+
var MEDIA_JOB_KINDS = ["video", "clip", "transcription"];
|
|
2246
|
+
var MediaJobKindSchema = z23.enum(MEDIA_JOB_KINDS);
|
|
2247
|
+
var MediaJobStatusSchema = z23.enum(["queued", "processing", "completed", "failed"]);
|
|
2248
|
+
var PublicUrl = z23.string().url().startsWith("http");
|
|
2249
|
+
var Score = z23.number().int().min(0).max(100);
|
|
2250
|
+
var Seconds = z23.number().nonnegative();
|
|
2251
|
+
var VideoResultSchema = z23.object({
|
|
2252
|
+
files: z23.array(
|
|
2253
|
+
z23.object({
|
|
1871
2254
|
file_id: idOf("fil"),
|
|
1872
|
-
content_type:
|
|
1873
|
-
width:
|
|
1874
|
-
height:
|
|
2255
|
+
content_type: z23.string(),
|
|
2256
|
+
width: z23.number().int().positive().nullable(),
|
|
2257
|
+
height: z23.number().int().positive().nullable(),
|
|
1875
2258
|
duration_seconds: Seconds.nullable()
|
|
1876
2259
|
})
|
|
1877
2260
|
)
|
|
1878
2261
|
});
|
|
1879
|
-
var ViralityScoreSchema =
|
|
2262
|
+
var ViralityScoreSchema = z23.object({
|
|
1880
2263
|
total: Score,
|
|
1881
2264
|
shareability: Score,
|
|
1882
2265
|
hook_strength: Score,
|
|
1883
2266
|
story_quality: Score,
|
|
1884
2267
|
emotional_impact: Score
|
|
1885
2268
|
});
|
|
1886
|
-
var ClipResultSchema =
|
|
1887
|
-
clips:
|
|
1888
|
-
|
|
2269
|
+
var ClipResultSchema = z23.object({
|
|
2270
|
+
clips: z23.array(
|
|
2271
|
+
z23.object({
|
|
1889
2272
|
file_id: idOf("fil"),
|
|
1890
|
-
title:
|
|
2273
|
+
title: z23.string(),
|
|
1891
2274
|
start_seconds: Seconds,
|
|
1892
2275
|
end_seconds: Seconds,
|
|
1893
2276
|
duration_seconds: Seconds,
|
|
@@ -1895,189 +2278,192 @@ var ClipResultSchema = z20.object({
|
|
|
1895
2278
|
})
|
|
1896
2279
|
)
|
|
1897
2280
|
});
|
|
1898
|
-
var TranscriptSchema =
|
|
1899
|
-
text:
|
|
1900
|
-
language:
|
|
2281
|
+
var TranscriptSchema = z23.object({
|
|
2282
|
+
text: z23.string(),
|
|
2283
|
+
language: z23.string().nullable(),
|
|
1901
2284
|
duration_seconds: Seconds.nullable(),
|
|
1902
|
-
segments:
|
|
2285
|
+
segments: z23.array(z23.object({ start_seconds: Seconds, end_seconds: Seconds, text: z23.string() }))
|
|
1903
2286
|
});
|
|
1904
|
-
var MediaJobResultSchema =
|
|
1905
|
-
var MediaJobSchema =
|
|
2287
|
+
var MediaJobResultSchema = z23.union([VideoResultSchema, ClipResultSchema, TranscriptSchema]);
|
|
2288
|
+
var MediaJobSchema = z23.object({
|
|
1906
2289
|
id: idOf("med"),
|
|
1907
|
-
object:
|
|
2290
|
+
object: z23.literal("media_job"),
|
|
1908
2291
|
kind: MediaJobKindSchema,
|
|
1909
2292
|
status: MediaJobStatusSchema,
|
|
1910
|
-
model:
|
|
1911
|
-
input:
|
|
2293
|
+
model: z23.string().nullable(),
|
|
2294
|
+
input: z23.record(z23.string(), z23.unknown()),
|
|
1912
2295
|
result: MediaJobResultSchema.nullable(),
|
|
1913
|
-
error:
|
|
2296
|
+
error: z23.object({ code: z23.string(), message: z23.string() }).nullable(),
|
|
1914
2297
|
cost_micro_usd: MicroUsdField.nullable(),
|
|
1915
2298
|
session_id: idOf("ses").nullable(),
|
|
1916
2299
|
created_at: Timestamp,
|
|
1917
2300
|
completed_at: Timestamp.nullable()
|
|
1918
2301
|
});
|
|
1919
|
-
var ImageRequestSchema =
|
|
1920
|
-
model:
|
|
1921
|
-
prompt:
|
|
1922
|
-
image_urls:
|
|
1923
|
-
aspect_ratio:
|
|
1924
|
-
seed:
|
|
1925
|
-
n:
|
|
1926
|
-
});
|
|
1927
|
-
var VideoRequestSchema =
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
2302
|
+
var ImageRequestSchema = z23.object({
|
|
2303
|
+
model: z23.string().min(1).optional(),
|
|
2304
|
+
prompt: z23.string().min(1),
|
|
2305
|
+
image_urls: z23.array(PublicUrl).max(4).optional(),
|
|
2306
|
+
aspect_ratio: z23.string().optional(),
|
|
2307
|
+
seed: z23.number().int().optional(),
|
|
2308
|
+
n: z23.number().int().min(1).max(4).default(1)
|
|
2309
|
+
});
|
|
2310
|
+
var VideoRequestSchema = z23.object({
|
|
2311
|
+
/** Omitted: the platform's video default while the catalogue publishes it (`resolveModel`, §33.2). */
|
|
2312
|
+
model: z23.string().min(1).optional(),
|
|
2313
|
+
prompt: z23.string().min(1),
|
|
2314
|
+
image_urls: z23.array(PublicUrl).max(1).optional(),
|
|
2315
|
+
/** The source clip of a video-to-video edit (ADR-0814). */
|
|
2316
|
+
video_url: PublicUrl.optional(),
|
|
2317
|
+
aspect_ratio: z23.string().optional(),
|
|
2318
|
+
seed: z23.number().int().optional(),
|
|
2319
|
+
seconds: z23.number().int().min(1).max(60).optional()
|
|
2320
|
+
});
|
|
2321
|
+
var ImageGenerationSchema = z23.object({
|
|
2322
|
+
object: z23.literal("image_generation"),
|
|
2323
|
+
model: z23.string(),
|
|
2324
|
+
files: z23.array(FileSchema),
|
|
1939
2325
|
cost_micro_usd: MicroUsdField
|
|
1940
2326
|
});
|
|
1941
|
-
var ClipLength =
|
|
1942
|
-
var ClipRequestSchema =
|
|
2327
|
+
var ClipLength = z23.number().int().min(5).max(180);
|
|
2328
|
+
var ClipRequestSchema = z23.object({
|
|
1943
2329
|
video_url: PublicUrl,
|
|
1944
|
-
aspect_ratio:
|
|
1945
|
-
remove_silence:
|
|
1946
|
-
caption_preset:
|
|
1947
|
-
language:
|
|
2330
|
+
aspect_ratio: z23.enum(["9:16", "16:9"]).default("9:16"),
|
|
2331
|
+
remove_silence: z23.boolean().default(false),
|
|
2332
|
+
caption_preset: z23.enum(["none", "clean", "bold", "karaoke"]).default("none"),
|
|
2333
|
+
language: z23.string().min(2).optional(),
|
|
1948
2334
|
min_seconds: ClipLength.default(15),
|
|
1949
2335
|
max_seconds: ClipLength.default(60),
|
|
1950
|
-
title:
|
|
2336
|
+
title: z23.string().min(1).optional()
|
|
1951
2337
|
});
|
|
1952
|
-
var AudioFormatSchema =
|
|
1953
|
-
var TranscriptionRequestSchema =
|
|
1954
|
-
model:
|
|
2338
|
+
var AudioFormatSchema = z23.enum(["mp3", "wav", "ogg"]);
|
|
2339
|
+
var TranscriptionRequestSchema = z23.object({
|
|
2340
|
+
model: z23.string().min(1).optional(),
|
|
1955
2341
|
file_id: idOf("fil").optional(),
|
|
1956
2342
|
url: PublicUrl.optional(),
|
|
1957
|
-
language:
|
|
1958
|
-
timestamps:
|
|
2343
|
+
language: z23.string().min(2).optional(),
|
|
2344
|
+
timestamps: z23.boolean().default(true)
|
|
1959
2345
|
}).refine((request) => request.file_id === void 0 !== (request.url === void 0), {
|
|
1960
2346
|
error: "exactly one of file_id or url",
|
|
1961
2347
|
path: ["file_id"]
|
|
1962
2348
|
});
|
|
1963
|
-
var SpeechRequestSchema =
|
|
1964
|
-
model:
|
|
1965
|
-
text:
|
|
1966
|
-
voice:
|
|
2349
|
+
var SpeechRequestSchema = z23.object({
|
|
2350
|
+
model: z23.string().min(1).optional(),
|
|
2351
|
+
text: z23.string().min(1).max(4096),
|
|
2352
|
+
voice: z23.string().min(1).optional(),
|
|
1967
2353
|
format: AudioFormatSchema.default("mp3"),
|
|
1968
|
-
speed:
|
|
2354
|
+
speed: z23.number().min(0.5).max(2).optional()
|
|
1969
2355
|
});
|
|
1970
|
-
var SpeechToSpeechRequestSchema =
|
|
1971
|
-
model:
|
|
2356
|
+
var SpeechToSpeechRequestSchema = z23.object({
|
|
2357
|
+
model: z23.string().min(1).optional(),
|
|
1972
2358
|
file_id: idOf("fil"),
|
|
1973
|
-
voice:
|
|
2359
|
+
voice: z23.string().min(1).optional(),
|
|
1974
2360
|
format: AudioFormatSchema.default("mp3")
|
|
1975
2361
|
});
|
|
1976
|
-
var SpeechGenerationSchema =
|
|
1977
|
-
object:
|
|
1978
|
-
model:
|
|
2362
|
+
var SpeechGenerationSchema = z23.object({
|
|
2363
|
+
object: z23.literal("speech_generation"),
|
|
2364
|
+
model: z23.string(),
|
|
1979
2365
|
file: FileSchema,
|
|
1980
2366
|
duration_seconds: Seconds.nullable(),
|
|
1981
2367
|
cost_micro_usd: MicroUsdField
|
|
1982
2368
|
});
|
|
1983
2369
|
|
|
1984
2370
|
// ../core/src/schema/app-data.ts
|
|
1985
|
-
import { z as
|
|
1986
|
-
var DbTableSchema =
|
|
1987
|
-
object:
|
|
1988
|
-
name:
|
|
1989
|
-
schema:
|
|
1990
|
-
rows:
|
|
1991
|
-
size_bytes:
|
|
1992
|
-
});
|
|
1993
|
-
var DbMigrationSchema =
|
|
2371
|
+
import { z as z24 } from "zod";
|
|
2372
|
+
var DbTableSchema = z24.object({
|
|
2373
|
+
object: z24.literal("db_table"),
|
|
2374
|
+
name: z24.string(),
|
|
2375
|
+
schema: z24.string().default("public"),
|
|
2376
|
+
rows: z24.number().int().nonnegative().nullable(),
|
|
2377
|
+
size_bytes: z24.number().int().nonnegative().nullable()
|
|
2378
|
+
});
|
|
2379
|
+
var DbMigrationSchema = z24.object({
|
|
1994
2380
|
id: idOf("dbm"),
|
|
1995
|
-
object:
|
|
1996
|
-
name:
|
|
1997
|
-
sha256:
|
|
2381
|
+
object: z24.literal("db_migration"),
|
|
2382
|
+
name: z24.string(),
|
|
2383
|
+
sha256: z24.string().regex(/^[0-9a-f]{64}$/),
|
|
1998
2384
|
applied_at: Timestamp,
|
|
1999
|
-
statements:
|
|
2385
|
+
statements: z24.number().int().nonnegative()
|
|
2000
2386
|
});
|
|
2001
|
-
var ApplyDbMigrationSchema =
|
|
2002
|
-
name:
|
|
2003
|
-
sql:
|
|
2387
|
+
var ApplyDbMigrationSchema = z24.object({
|
|
2388
|
+
name: z24.string().min(1).max(128).regex(/^[a-z0-9][a-z0-9_-]*$/),
|
|
2389
|
+
sql: z24.string().min(1)
|
|
2004
2390
|
});
|
|
2005
2391
|
var DB_REST_METHODS = ["GET", "POST", "PATCH", "PUT", "DELETE", "HEAD"];
|
|
2006
|
-
var DbRestMethodSchema =
|
|
2392
|
+
var DbRestMethodSchema = z24.enum(DB_REST_METHODS);
|
|
2007
2393
|
var BUCKET_NAME = /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;
|
|
2008
|
-
var BucketSchema =
|
|
2009
|
-
object:
|
|
2010
|
-
name:
|
|
2011
|
-
public:
|
|
2394
|
+
var BucketSchema = z24.object({
|
|
2395
|
+
object: z24.literal("bucket"),
|
|
2396
|
+
name: z24.string().regex(BUCKET_NAME),
|
|
2397
|
+
public: z24.boolean(),
|
|
2012
2398
|
created_at: Timestamp
|
|
2013
2399
|
});
|
|
2014
|
-
var CreateBucketSchema =
|
|
2015
|
-
name:
|
|
2016
|
-
public:
|
|
2017
|
-
});
|
|
2018
|
-
var StorageObjectSchema =
|
|
2019
|
-
object:
|
|
2020
|
-
bucket:
|
|
2021
|
-
key:
|
|
2022
|
-
size_bytes:
|
|
2023
|
-
content_type:
|
|
2024
|
-
etag:
|
|
2400
|
+
var CreateBucketSchema = z24.object({
|
|
2401
|
+
name: z24.string().regex(BUCKET_NAME, { error: "3\u201363 lowercase letters, digits and hyphens" }),
|
|
2402
|
+
public: z24.boolean().default(false)
|
|
2403
|
+
});
|
|
2404
|
+
var StorageObjectSchema = z24.object({
|
|
2405
|
+
object: z24.literal("storage_object"),
|
|
2406
|
+
bucket: z24.string(),
|
|
2407
|
+
key: z24.string().min(1),
|
|
2408
|
+
size_bytes: z24.number().int().nonnegative(),
|
|
2409
|
+
content_type: z24.string(),
|
|
2410
|
+
etag: z24.string().nullable(),
|
|
2025
2411
|
updated_at: Timestamp
|
|
2026
2412
|
});
|
|
2027
|
-
var SignedUrlMethodSchema =
|
|
2028
|
-
var SignedUrlSchema =
|
|
2029
|
-
object:
|
|
2030
|
-
url:
|
|
2413
|
+
var SignedUrlMethodSchema = z24.enum(["PUT", "GET"]);
|
|
2414
|
+
var SignedUrlSchema = z24.object({
|
|
2415
|
+
object: z24.literal("signed_url"),
|
|
2416
|
+
url: z24.string().url(),
|
|
2031
2417
|
method: SignedUrlMethodSchema,
|
|
2032
2418
|
expires_at: Timestamp
|
|
2033
2419
|
});
|
|
2034
|
-
var CreateUploadUrlSchema =
|
|
2035
|
-
content_type:
|
|
2036
|
-
expires_seconds:
|
|
2420
|
+
var CreateUploadUrlSchema = z24.object({
|
|
2421
|
+
content_type: z24.string().min(1),
|
|
2422
|
+
expires_seconds: z24.number().int().min(60).max(3600).default(900)
|
|
2037
2423
|
});
|
|
2038
2424
|
|
|
2039
2425
|
// ../core/src/schema/stock-photo.ts
|
|
2040
|
-
import { z as
|
|
2426
|
+
import { z as z25 } from "zod";
|
|
2041
2427
|
var STOCK_PHOTO_ORIENTATIONS = ["landscape", "portrait", "square"];
|
|
2042
2428
|
var STOCK_PHOTO_SIZES = ["small", "medium", "large"];
|
|
2043
|
-
var StockPhotoQuerySchema =
|
|
2044
|
-
query:
|
|
2045
|
-
count:
|
|
2046
|
-
orientation:
|
|
2047
|
-
color:
|
|
2048
|
-
size:
|
|
2049
|
-
});
|
|
2050
|
-
var StockPhotoSchema =
|
|
2051
|
-
object:
|
|
2052
|
-
id:
|
|
2053
|
-
width:
|
|
2054
|
-
height:
|
|
2055
|
-
url:
|
|
2056
|
-
preview_url:
|
|
2057
|
-
alt:
|
|
2058
|
-
photographer:
|
|
2059
|
-
attribution_url:
|
|
2060
|
-
dominant_color:
|
|
2429
|
+
var StockPhotoQuerySchema = z25.object({
|
|
2430
|
+
query: z25.string().min(1).max(200),
|
|
2431
|
+
count: z25.coerce.number().int().min(1).max(30).default(10),
|
|
2432
|
+
orientation: z25.enum(STOCK_PHOTO_ORIENTATIONS).optional(),
|
|
2433
|
+
color: z25.string().min(1).max(32).optional(),
|
|
2434
|
+
size: z25.enum(STOCK_PHOTO_SIZES).optional()
|
|
2435
|
+
});
|
|
2436
|
+
var StockPhotoSchema = z25.object({
|
|
2437
|
+
object: z25.literal("stock_photo"),
|
|
2438
|
+
id: z25.string().min(1),
|
|
2439
|
+
width: z25.number().int().positive(),
|
|
2440
|
+
height: z25.number().int().positive(),
|
|
2441
|
+
url: z25.string().url(),
|
|
2442
|
+
preview_url: z25.string().url(),
|
|
2443
|
+
alt: z25.string().nullable(),
|
|
2444
|
+
photographer: z25.string().nullable(),
|
|
2445
|
+
attribution_url: z25.string().url().nullable(),
|
|
2446
|
+
dominant_color: z25.string().nullable()
|
|
2061
2447
|
});
|
|
2062
2448
|
|
|
2063
2449
|
// ../core/src/schema/creator.ts
|
|
2064
|
-
import { z as
|
|
2065
|
-
var CreatorCodeSchema =
|
|
2066
|
-
var PayoutMethodSchema =
|
|
2067
|
-
var PayoutDetailsSchema =
|
|
2450
|
+
import { z as z26 } from "zod";
|
|
2451
|
+
var CreatorCodeSchema = z26.string().regex(/^[a-z0-9]{3,24}$/, "3 to 24 lowercase letters or digits");
|
|
2452
|
+
var PayoutMethodSchema = z26.enum(["wise", "paypal"]);
|
|
2453
|
+
var PayoutDetailsSchema = z26.object({
|
|
2068
2454
|
method: PayoutMethodSchema,
|
|
2069
|
-
account:
|
|
2455
|
+
account: z26.string().min(1).max(320)
|
|
2070
2456
|
});
|
|
2071
|
-
var CreatorStatusSchema =
|
|
2072
|
-
var CreatorSchema =
|
|
2457
|
+
var CreatorStatusSchema = z26.enum(["active", "suspended"]);
|
|
2458
|
+
var CreatorSchema = z26.object({
|
|
2073
2459
|
id: idOf("crt"),
|
|
2074
|
-
object:
|
|
2075
|
-
email:
|
|
2076
|
-
display_name:
|
|
2460
|
+
object: z26.literal("creator"),
|
|
2461
|
+
email: z26.email(),
|
|
2462
|
+
display_name: z26.string().min(1).max(80),
|
|
2077
2463
|
code: CreatorCodeSchema,
|
|
2078
2464
|
status: CreatorStatusSchema,
|
|
2079
2465
|
payout: PayoutDetailsSchema.nullable(),
|
|
2080
|
-
clicks:
|
|
2466
|
+
clicks: z26.number().int().nonnegative(),
|
|
2081
2467
|
created_at: Timestamp,
|
|
2082
2468
|
updated_at: Timestamp
|
|
2083
2469
|
});
|
|
@@ -2085,28 +2471,28 @@ var IdentityCreatorSchema = CreatorSchema.pick({
|
|
|
2085
2471
|
id: true,
|
|
2086
2472
|
status: true
|
|
2087
2473
|
});
|
|
2088
|
-
var CreatorApplicationStatusSchema =
|
|
2474
|
+
var CreatorApplicationStatusSchema = z26.enum([
|
|
2089
2475
|
"pending",
|
|
2090
2476
|
"approved",
|
|
2091
2477
|
"rejected"
|
|
2092
2478
|
]);
|
|
2093
|
-
var CreatorApplicationSchema =
|
|
2479
|
+
var CreatorApplicationSchema = z26.object({
|
|
2094
2480
|
id: idOf("cra"),
|
|
2095
|
-
object:
|
|
2096
|
-
email:
|
|
2097
|
-
display_name:
|
|
2098
|
-
pitch:
|
|
2099
|
-
links:
|
|
2481
|
+
object: z26.literal("creator_application"),
|
|
2482
|
+
email: z26.email(),
|
|
2483
|
+
display_name: z26.string().min(1).max(80),
|
|
2484
|
+
pitch: z26.string().min(1).max(2e3),
|
|
2485
|
+
links: z26.array(z26.url({ protocol: /^https$/ })).max(5),
|
|
2100
2486
|
status: CreatorApplicationStatusSchema,
|
|
2101
|
-
note:
|
|
2487
|
+
note: z26.string().nullable(),
|
|
2102
2488
|
creator_id: idOf("crt").nullable(),
|
|
2103
2489
|
created_at: Timestamp,
|
|
2104
2490
|
decided_at: Timestamp.nullable()
|
|
2105
2491
|
});
|
|
2106
|
-
var ReferralStatusSchema =
|
|
2107
|
-
var ReferralSchema =
|
|
2492
|
+
var ReferralStatusSchema = z26.enum(["pending", "active", "expired"]);
|
|
2493
|
+
var ReferralSchema = z26.object({
|
|
2108
2494
|
id: idOf("crf"),
|
|
2109
|
-
object:
|
|
2495
|
+
object: z26.literal("referral"),
|
|
2110
2496
|
creator_id: idOf("crt"),
|
|
2111
2497
|
organization_id: idOf("org"),
|
|
2112
2498
|
status: ReferralStatusSchema,
|
|
@@ -2114,16 +2500,16 @@ var ReferralSchema = z23.object({
|
|
|
2114
2500
|
first_paid_at: Timestamp.nullable(),
|
|
2115
2501
|
commission_until: Timestamp.nullable()
|
|
2116
2502
|
});
|
|
2117
|
-
var CommissionKindSchema =
|
|
2118
|
-
var CommissionStatusSchema =
|
|
2503
|
+
var CommissionKindSchema = z26.enum(["referral", "template"]);
|
|
2504
|
+
var CommissionStatusSchema = z26.enum([
|
|
2119
2505
|
"pending",
|
|
2120
2506
|
"available",
|
|
2121
2507
|
"claimed",
|
|
2122
2508
|
"paid"
|
|
2123
2509
|
]);
|
|
2124
|
-
var CommissionSchema =
|
|
2510
|
+
var CommissionSchema = z26.object({
|
|
2125
2511
|
id: idOf("crc"),
|
|
2126
|
-
object:
|
|
2512
|
+
object: z26.literal("commission"),
|
|
2127
2513
|
creator_id: idOf("crt"),
|
|
2128
2514
|
kind: CommissionKindSchema,
|
|
2129
2515
|
referral_id: idOf("crf").nullable(),
|
|
@@ -2136,18 +2522,18 @@ var CommissionSchema = z23.object({
|
|
|
2136
2522
|
available_at: Timestamp,
|
|
2137
2523
|
payout_id: idOf("crp").nullable()
|
|
2138
2524
|
});
|
|
2139
|
-
var PayoutStatusSchema =
|
|
2140
|
-
var PayoutSchema =
|
|
2525
|
+
var PayoutStatusSchema = z26.enum(["requested", "paid", "rejected"]);
|
|
2526
|
+
var PayoutSchema = z26.object({
|
|
2141
2527
|
id: idOf("crp"),
|
|
2142
|
-
object:
|
|
2528
|
+
object: z26.literal("payout"),
|
|
2143
2529
|
creator_id: idOf("crt"),
|
|
2144
2530
|
amount_micro_usd: MicroUsdField.positive(),
|
|
2145
|
-
currency:
|
|
2531
|
+
currency: z26.literal("USD"),
|
|
2146
2532
|
method: PayoutMethodSchema,
|
|
2147
|
-
account:
|
|
2533
|
+
account: z26.string().min(1),
|
|
2148
2534
|
status: PayoutStatusSchema,
|
|
2149
|
-
reference:
|
|
2150
|
-
note:
|
|
2535
|
+
reference: z26.string().nullable(),
|
|
2536
|
+
note: z26.string().nullable(),
|
|
2151
2537
|
requested_at: Timestamp,
|
|
2152
2538
|
decided_at: Timestamp.nullable()
|
|
2153
2539
|
});
|
|
@@ -2159,100 +2545,100 @@ var CREATOR_PROGRAM = {
|
|
|
2159
2545
|
attribution_days: 30,
|
|
2160
2546
|
minimum_payout_micro_usd: 2e7
|
|
2161
2547
|
};
|
|
2162
|
-
var CreatorTemplateSlugSchema =
|
|
2548
|
+
var CreatorTemplateSlugSchema = z26.string().max(32).regex(
|
|
2163
2549
|
/^[a-z0-9]+(-[a-z0-9]+)*$/,
|
|
2164
2550
|
"lowercase letters, digits and single dashes"
|
|
2165
2551
|
);
|
|
2166
|
-
var CreatorSkillSchema =
|
|
2167
|
-
slug:
|
|
2168
|
-
body:
|
|
2552
|
+
var CreatorSkillSchema = z26.object({
|
|
2553
|
+
slug: z26.string().regex(/^[a-z0-9][a-z0-9-]*$/, "lowercase letters, digits and dashes"),
|
|
2554
|
+
body: z26.string().min(1).max(64 * 1024)
|
|
2169
2555
|
});
|
|
2170
|
-
var CreatorDeclarationSchema =
|
|
2171
|
-
agents:
|
|
2172
|
-
questions:
|
|
2173
|
-
skills:
|
|
2556
|
+
var CreatorDeclarationSchema = z26.object({
|
|
2557
|
+
agents: z26.array(z26.unknown()),
|
|
2558
|
+
questions: z26.array(z26.unknown()),
|
|
2559
|
+
skills: z26.array(CreatorSkillSchema).max(16)
|
|
2174
2560
|
});
|
|
2175
|
-
var CreatorTemplateVersionStatusSchema =
|
|
2561
|
+
var CreatorTemplateVersionStatusSchema = z26.enum([
|
|
2176
2562
|
"in_review",
|
|
2177
2563
|
"approved",
|
|
2178
2564
|
"changes_requested"
|
|
2179
2565
|
]);
|
|
2180
|
-
var VersionNumber =
|
|
2181
|
-
var CreatorTemplateSchema =
|
|
2566
|
+
var VersionNumber = z26.number().int().positive();
|
|
2567
|
+
var CreatorTemplateSchema = z26.object({
|
|
2182
2568
|
id: idOf("ctp"),
|
|
2183
|
-
object:
|
|
2569
|
+
object: z26.literal("creator_template"),
|
|
2184
2570
|
creator_id: idOf("crt"),
|
|
2185
|
-
blueprint:
|
|
2186
|
-
base_template:
|
|
2571
|
+
blueprint: z26.string().min(1),
|
|
2572
|
+
base_template: z26.string().min(1),
|
|
2187
2573
|
slug: CreatorTemplateSlugSchema,
|
|
2188
|
-
template:
|
|
2189
|
-
name:
|
|
2190
|
-
description:
|
|
2574
|
+
template: z26.string().min(1).max(64),
|
|
2575
|
+
name: z26.string().min(1).max(80),
|
|
2576
|
+
description: z26.string().max(2e3),
|
|
2191
2577
|
declaration: CreatorDeclarationSchema,
|
|
2192
2578
|
published_version: VersionNumber.nullable(),
|
|
2193
|
-
latest_version:
|
|
2579
|
+
latest_version: z26.object({
|
|
2194
2580
|
version: VersionNumber,
|
|
2195
2581
|
status: CreatorTemplateVersionStatusSchema
|
|
2196
2582
|
}).nullable(),
|
|
2197
2583
|
created_at: Timestamp,
|
|
2198
2584
|
updated_at: Timestamp
|
|
2199
2585
|
});
|
|
2200
|
-
var CreatorTemplateVersionSchema =
|
|
2201
|
-
object:
|
|
2586
|
+
var CreatorTemplateVersionSchema = z26.object({
|
|
2587
|
+
object: z26.literal("creator_template_version"),
|
|
2202
2588
|
template_id: idOf("ctp"),
|
|
2203
2589
|
version: VersionNumber,
|
|
2204
2590
|
declaration: CreatorDeclarationSchema,
|
|
2205
2591
|
status: CreatorTemplateVersionStatusSchema,
|
|
2206
|
-
note:
|
|
2592
|
+
note: z26.string().nullable(),
|
|
2207
2593
|
artifact_id: idOf("bpa").nullable(),
|
|
2208
2594
|
submitted_at: Timestamp,
|
|
2209
2595
|
decided_at: Timestamp.nullable()
|
|
2210
2596
|
});
|
|
2211
|
-
var CreatorBalanceSchema =
|
|
2212
|
-
object:
|
|
2597
|
+
var CreatorBalanceSchema = z26.object({
|
|
2598
|
+
object: z26.literal("creator_balance"),
|
|
2213
2599
|
pending_micro_usd: MicroUsdField.nonnegative(),
|
|
2214
2600
|
available_micro_usd: MicroUsdField.nonnegative(),
|
|
2215
2601
|
claimed_micro_usd: MicroUsdField.nonnegative(),
|
|
2216
2602
|
paid_micro_usd: MicroUsdField.nonnegative(),
|
|
2217
|
-
minimum_payout_micro_usd:
|
|
2603
|
+
minimum_payout_micro_usd: z26.literal(CREATOR_PROGRAM.minimum_payout_micro_usd)
|
|
2218
2604
|
});
|
|
2219
|
-
var ReferralClickSchema =
|
|
2220
|
-
object:
|
|
2605
|
+
var ReferralClickSchema = z26.object({
|
|
2606
|
+
object: z26.literal("referral_click"),
|
|
2221
2607
|
code: CreatorCodeSchema,
|
|
2222
|
-
creator:
|
|
2608
|
+
creator: z26.object({ display_name: z26.string().min(1) }),
|
|
2223
2609
|
expires_at: Timestamp
|
|
2224
2610
|
});
|
|
2225
|
-
var
|
|
2226
|
-
var CreatorAnalyticsSchema =
|
|
2227
|
-
object:
|
|
2228
|
-
days:
|
|
2229
|
-
from:
|
|
2230
|
-
to:
|
|
2231
|
-
clicks:
|
|
2232
|
-
referrals:
|
|
2233
|
-
installs:
|
|
2234
|
-
active_installs:
|
|
2235
|
-
usage_by_day:
|
|
2236
|
-
|
|
2611
|
+
var Day2 = z26.iso.date();
|
|
2612
|
+
var CreatorAnalyticsSchema = z26.object({
|
|
2613
|
+
object: z26.literal("creator_analytics"),
|
|
2614
|
+
days: z26.number().int().min(1).max(90),
|
|
2615
|
+
from: Day2,
|
|
2616
|
+
to: Day2,
|
|
2617
|
+
clicks: z26.number().int().nonnegative(),
|
|
2618
|
+
referrals: z26.number().int().nonnegative(),
|
|
2619
|
+
installs: z26.number().int().nonnegative(),
|
|
2620
|
+
active_installs: z26.number().int().nonnegative(),
|
|
2621
|
+
usage_by_day: z26.array(
|
|
2622
|
+
z26.object({ day: Day2, debit_micro_usd: MicroUsdField.nonnegative() })
|
|
2237
2623
|
),
|
|
2238
|
-
commission_micro_usd:
|
|
2624
|
+
commission_micro_usd: z26.object({
|
|
2239
2625
|
pending: MicroUsdField.nonnegative(),
|
|
2240
2626
|
available: MicroUsdField.nonnegative(),
|
|
2241
2627
|
claimed: MicroUsdField.nonnegative(),
|
|
2242
2628
|
paid: MicroUsdField.nonnegative()
|
|
2243
2629
|
}),
|
|
2244
|
-
commissions_by_template:
|
|
2245
|
-
|
|
2630
|
+
commissions_by_template: z26.array(
|
|
2631
|
+
z26.object({
|
|
2246
2632
|
creator_template_id: idOf("ctp"),
|
|
2247
2633
|
amount_micro_usd: MicroUsdField.nonnegative()
|
|
2248
2634
|
})
|
|
2249
2635
|
),
|
|
2250
2636
|
/** Every install covered, newest first: the day it was created and the day its twelve months end. */
|
|
2251
|
-
install_windows:
|
|
2637
|
+
install_windows: z26.array(z26.object({ install_id: idOf("bpi"), from: Day2, until: Day2 }))
|
|
2252
2638
|
});
|
|
2253
2639
|
|
|
2254
2640
|
// ../core/src/schema/legal.ts
|
|
2255
|
-
import { z as
|
|
2641
|
+
import { z as z27 } from "zod";
|
|
2256
2642
|
var LEGAL_MEMBER_STATUSES = [
|
|
2257
2643
|
"pending",
|
|
2258
2644
|
"link_ready",
|
|
@@ -2262,16 +2648,16 @@ var LEGAL_MEMBER_STATUSES = [
|
|
|
2262
2648
|
"verified",
|
|
2263
2649
|
"failed"
|
|
2264
2650
|
];
|
|
2265
|
-
var LegalMemberStatusSchema =
|
|
2651
|
+
var LegalMemberStatusSchema = z27.enum(LEGAL_MEMBER_STATUSES);
|
|
2266
2652
|
var LEGAL_VERIFICATION_STATUSES = ["in_progress", "pending_review", "verified", "failed"];
|
|
2267
|
-
var LegalVerificationStatusSchema =
|
|
2653
|
+
var LegalVerificationStatusSchema = z27.enum(LEGAL_VERIFICATION_STATUSES);
|
|
2268
2654
|
var LEGAL_COMPANY_STATUSES = ["awaiting_payment", "paid", "submitted", "formed", "failed"];
|
|
2269
|
-
var LegalCompanyStatusSchema =
|
|
2655
|
+
var LegalCompanyStatusSchema = z27.enum(LEGAL_COMPANY_STATUSES);
|
|
2270
2656
|
var LEGAL_DOCUMENT_KINDS = ["articles", "ein_letter", "operating_agreement", "other"];
|
|
2271
|
-
var LegalDocumentKindSchema =
|
|
2272
|
-
var LegalMemberRoleSchema =
|
|
2273
|
-
var LegalEinStatusSchema =
|
|
2274
|
-
var LegalRequiredActionKindSchema =
|
|
2657
|
+
var LegalDocumentKindSchema = z27.enum(LEGAL_DOCUMENT_KINDS);
|
|
2658
|
+
var LegalMemberRoleSchema = z27.enum(["primary", "secondary"]);
|
|
2659
|
+
var LegalEinStatusSchema = z27.enum(["none", "pending", "issued"]);
|
|
2660
|
+
var LegalRequiredActionKindSchema = z27.enum(["signature", "information", "payment", "other"]);
|
|
2275
2661
|
var US_STATES = [
|
|
2276
2662
|
"AL",
|
|
2277
2663
|
"AK",
|
|
@@ -2325,105 +2711,105 @@ var US_STATES = [
|
|
|
2325
2711
|
"WI",
|
|
2326
2712
|
"WY"
|
|
2327
2713
|
];
|
|
2328
|
-
var UsStateSchema =
|
|
2329
|
-
var LegalMemberInputSchema =
|
|
2330
|
-
first_name:
|
|
2331
|
-
last_name:
|
|
2332
|
-
email:
|
|
2714
|
+
var UsStateSchema = z27.enum(US_STATES);
|
|
2715
|
+
var LegalMemberInputSchema = z27.object({
|
|
2716
|
+
first_name: z27.string().min(1).max(128),
|
|
2717
|
+
last_name: z27.string().min(1).max(128),
|
|
2718
|
+
email: z27.string().min(1).max(320),
|
|
2333
2719
|
role: LegalMemberRoleSchema,
|
|
2334
|
-
is_responsible_party:
|
|
2335
|
-
ownership_percent:
|
|
2720
|
+
is_responsible_party: z27.boolean(),
|
|
2721
|
+
ownership_percent: z27.number().int()
|
|
2336
2722
|
});
|
|
2337
2723
|
var LegalMemberSchema = LegalMemberInputSchema.extend({
|
|
2338
2724
|
id: idOf("lgm"),
|
|
2339
|
-
object:
|
|
2725
|
+
object: z27.literal("legal_member"),
|
|
2340
2726
|
verification_id: idOf("lgv"),
|
|
2341
2727
|
status: LegalMemberStatusSchema,
|
|
2342
|
-
link_url:
|
|
2728
|
+
link_url: z27.url().nullable(),
|
|
2343
2729
|
link_expires_at: Timestamp.nullable(),
|
|
2344
2730
|
completed_at: Timestamp.nullable()
|
|
2345
2731
|
});
|
|
2346
|
-
var LegalVerificationSchema =
|
|
2732
|
+
var LegalVerificationSchema = z27.object({
|
|
2347
2733
|
id: idOf("lgv"),
|
|
2348
|
-
object:
|
|
2734
|
+
object: z27.literal("legal_verification"),
|
|
2349
2735
|
identity_id: idOf("idn"),
|
|
2350
2736
|
status: LegalVerificationStatusSchema,
|
|
2351
|
-
members:
|
|
2352
|
-
ready_for_formation:
|
|
2737
|
+
members: z27.array(LegalMemberSchema),
|
|
2738
|
+
ready_for_formation: z27.boolean(),
|
|
2353
2739
|
started_at: Timestamp,
|
|
2354
2740
|
completed_at: Timestamp.nullable(),
|
|
2355
2741
|
created_at: Timestamp,
|
|
2356
2742
|
updated_at: Timestamp
|
|
2357
2743
|
});
|
|
2358
|
-
var StartLegalVerificationSchema =
|
|
2359
|
-
var CompleteLegalMemberSchema =
|
|
2360
|
-
var LegalNameOptionSchema =
|
|
2361
|
-
var LegalMailingAddressSchema =
|
|
2362
|
-
line1:
|
|
2363
|
-
line2:
|
|
2364
|
-
city:
|
|
2744
|
+
var StartLegalVerificationSchema = z27.object({ members: z27.array(LegalMemberInputSchema) });
|
|
2745
|
+
var CompleteLegalMemberSchema = z27.object({ token: z27.string().min(1) });
|
|
2746
|
+
var LegalNameOptionSchema = z27.object({ name: z27.string().min(1).max(200), ending: z27.literal("LLC") });
|
|
2747
|
+
var LegalMailingAddressSchema = z27.object({
|
|
2748
|
+
line1: z27.string().min(1).max(200),
|
|
2749
|
+
line2: z27.string().max(200).nullable(),
|
|
2750
|
+
city: z27.string().min(1).max(100),
|
|
2365
2751
|
state: UsStateSchema,
|
|
2366
|
-
postal_code:
|
|
2367
|
-
country:
|
|
2752
|
+
postal_code: z27.string().min(1).max(16),
|
|
2753
|
+
country: z27.literal("US")
|
|
2368
2754
|
});
|
|
2369
|
-
var LegalRequiredActionSchema =
|
|
2755
|
+
var LegalRequiredActionSchema = z27.object({
|
|
2370
2756
|
kind: LegalRequiredActionKindSchema,
|
|
2371
|
-
description:
|
|
2372
|
-
url:
|
|
2757
|
+
description: z27.string(),
|
|
2758
|
+
url: z27.url().nullable()
|
|
2373
2759
|
});
|
|
2374
2760
|
var LEGAL_DESCRIPTION_MAX = 50;
|
|
2375
|
-
var CreateLegalCompanySchema =
|
|
2761
|
+
var CreateLegalCompanySchema = z27.object({
|
|
2376
2762
|
verification_id: idOf("lgv"),
|
|
2377
2763
|
state: UsStateSchema,
|
|
2378
|
-
name_options:
|
|
2379
|
-
naics_code:
|
|
2380
|
-
description:
|
|
2764
|
+
name_options: z27.array(z27.string().min(1).max(200)).min(1).max(3),
|
|
2765
|
+
naics_code: z27.string().regex(/^\d{2,6}$/),
|
|
2766
|
+
description: z27.string().min(1).max(LEGAL_DESCRIPTION_MAX),
|
|
2381
2767
|
mailing_address: LegalMailingAddressSchema
|
|
2382
2768
|
});
|
|
2383
2769
|
var LegalCompanySchema = CreateLegalCompanySchema.omit({ name_options: true }).extend({
|
|
2384
2770
|
id: idOf("lgc"),
|
|
2385
|
-
object:
|
|
2771
|
+
object: z27.literal("legal_company"),
|
|
2386
2772
|
identity_id: idOf("idn"),
|
|
2387
2773
|
status: LegalCompanyStatusSchema,
|
|
2388
|
-
entity_type:
|
|
2389
|
-
name_options:
|
|
2390
|
-
legal_name:
|
|
2774
|
+
entity_type: z27.literal("llc"),
|
|
2775
|
+
name_options: z27.array(LegalNameOptionSchema),
|
|
2776
|
+
legal_name: z27.string().nullable(),
|
|
2391
2777
|
ein_status: LegalEinStatusSchema,
|
|
2392
2778
|
price_micro_usd: MicroUsdField,
|
|
2393
|
-
required_actions:
|
|
2394
|
-
failure_reason:
|
|
2779
|
+
required_actions: z27.array(LegalRequiredActionSchema),
|
|
2780
|
+
failure_reason: z27.string().max(256).nullable(),
|
|
2395
2781
|
submitted_at: Timestamp.nullable(),
|
|
2396
2782
|
formed_at: Timestamp.nullable(),
|
|
2397
2783
|
created_at: Timestamp,
|
|
2398
2784
|
updated_at: Timestamp
|
|
2399
2785
|
});
|
|
2400
|
-
var LegalDocumentSchema =
|
|
2786
|
+
var LegalDocumentSchema = z27.object({
|
|
2401
2787
|
id: idOf("lgd"),
|
|
2402
|
-
object:
|
|
2788
|
+
object: z27.literal("legal_document"),
|
|
2403
2789
|
company_id: idOf("lgc"),
|
|
2404
2790
|
kind: LegalDocumentKindSchema,
|
|
2405
|
-
name:
|
|
2791
|
+
name: z27.string(),
|
|
2406
2792
|
created_at: Timestamp
|
|
2407
2793
|
});
|
|
2408
|
-
var LegalDocumentLinkSchema =
|
|
2409
|
-
object:
|
|
2410
|
-
url:
|
|
2794
|
+
var LegalDocumentLinkSchema = z27.object({
|
|
2795
|
+
object: z27.literal("legal_document_link"),
|
|
2796
|
+
url: z27.url(),
|
|
2411
2797
|
expires_at: Timestamp
|
|
2412
2798
|
});
|
|
2413
|
-
var NaicsCodeSchema =
|
|
2414
|
-
object:
|
|
2415
|
-
code:
|
|
2416
|
-
title:
|
|
2799
|
+
var NaicsCodeSchema = z27.object({
|
|
2800
|
+
object: z27.literal("naics_code"),
|
|
2801
|
+
code: z27.string().regex(/^\d{2,6}$/),
|
|
2802
|
+
title: z27.string()
|
|
2417
2803
|
});
|
|
2418
|
-
var LegalStateSchema =
|
|
2419
|
-
object:
|
|
2804
|
+
var LegalStateSchema = z27.object({
|
|
2805
|
+
object: z27.literal("legal_state"),
|
|
2420
2806
|
code: UsStateSchema,
|
|
2421
|
-
name:
|
|
2807
|
+
name: z27.string(),
|
|
2422
2808
|
formation_fee_micro_usd: MicroUsdField
|
|
2423
2809
|
});
|
|
2424
|
-
var LegalWebhookEventSchema =
|
|
2425
|
-
provider_session_ref:
|
|
2426
|
-
status:
|
|
2810
|
+
var LegalWebhookEventSchema = z27.object({
|
|
2811
|
+
provider_session_ref: z27.string().min(1),
|
|
2812
|
+
status: z27.enum(["verified", "failed", "pending_review"]),
|
|
2427
2813
|
metadata: Metadata
|
|
2428
2814
|
});
|
|
2429
2815
|
var LLC_ENDING = /\s*(?:,\s*)?(?:l\.?l\.?c\.?|limited\s+liability\s+company)\s*$/i;
|
|
@@ -2434,233 +2820,437 @@ function canonicalName(raw) {
|
|
|
2434
2820
|
}
|
|
2435
2821
|
|
|
2436
2822
|
// ../core/src/schema/wallet.ts
|
|
2437
|
-
import { z as
|
|
2823
|
+
import { z as z28 } from "zod";
|
|
2438
2824
|
var WALLET_NETWORKS = ["eip155:84532", "eip155:8453"];
|
|
2439
|
-
var WalletNetworkSchema =
|
|
2825
|
+
var WalletNetworkSchema = z28.enum(WALLET_NETWORKS);
|
|
2440
2826
|
var DEFAULT_WALLET_NETWORK = "eip155:84532";
|
|
2441
|
-
var WalletSelectSchema =
|
|
2827
|
+
var WalletSelectSchema = z28.object({ network: WalletNetworkSchema.optional() });
|
|
2442
2828
|
var WALLET_STATUSES = ["active", "frozen", "swept"];
|
|
2443
|
-
var WalletStatusSchema =
|
|
2829
|
+
var WalletStatusSchema = z28.enum(WALLET_STATUSES);
|
|
2444
2830
|
var WALLET_TRANSACTION_KINDS = ["fund", "transfer", "pay", "sweep"];
|
|
2445
|
-
var WalletTransactionKindSchema =
|
|
2831
|
+
var WalletTransactionKindSchema = z28.enum(WALLET_TRANSACTION_KINDS);
|
|
2446
2832
|
var WALLET_TRANSACTION_STATUSES = ["pending", "confirmed", "failed"];
|
|
2447
|
-
var WalletTransactionStatusSchema =
|
|
2448
|
-
var WalletDirectionSchema =
|
|
2449
|
-
var WalletFundSourceSchema =
|
|
2450
|
-
var EvmAddressSchema =
|
|
2451
|
-
var TxHashSchema =
|
|
2452
|
-
var WalletPolicySchema =
|
|
2833
|
+
var WalletTransactionStatusSchema = z28.enum(WALLET_TRANSACTION_STATUSES);
|
|
2834
|
+
var WalletDirectionSchema = z28.enum(["in", "out"]);
|
|
2835
|
+
var WalletFundSourceSchema = z28.enum(["faucet", "treasury"]);
|
|
2836
|
+
var EvmAddressSchema = z28.string().regex(/^0x[0-9a-fA-F]{40}$/, "expected a 0x address");
|
|
2837
|
+
var TxHashSchema = z28.string().regex(/^0x[0-9a-fA-F]{64}$/, "expected a 0x transaction hash");
|
|
2838
|
+
var WalletPolicySchema = z28.object({
|
|
2453
2839
|
per_tx_cap_micro_usd: MicroUsdField.nonnegative(),
|
|
2454
2840
|
daily_cap_micro_usd: MicroUsdField.positive().nullable(),
|
|
2455
2841
|
low_balance_micro_usd: MicroUsdField.nonnegative().nullable()
|
|
2456
2842
|
});
|
|
2457
|
-
var WalletSchema =
|
|
2843
|
+
var WalletSchema = z28.object({
|
|
2458
2844
|
id: idOf("wlt"),
|
|
2459
|
-
object:
|
|
2845
|
+
object: z28.literal("wallet"),
|
|
2460
2846
|
identity_id: idOf("idn"),
|
|
2461
2847
|
status: WalletStatusSchema,
|
|
2462
2848
|
network: WalletNetworkSchema,
|
|
2463
2849
|
address: EvmAddressSchema,
|
|
2464
|
-
asset:
|
|
2850
|
+
asset: z28.literal("usdc"),
|
|
2465
2851
|
balance_micro_usd: MicroUsdField,
|
|
2466
2852
|
policy: WalletPolicySchema,
|
|
2467
2853
|
spent_today_micro_usd: MicroUsdField,
|
|
2468
2854
|
created_at: Timestamp,
|
|
2469
2855
|
updated_at: Timestamp
|
|
2470
2856
|
});
|
|
2471
|
-
var CreateWalletSchema =
|
|
2857
|
+
var CreateWalletSchema = z28.object({
|
|
2472
2858
|
network: WalletNetworkSchema.optional(),
|
|
2473
2859
|
policy: WalletPolicySchema.partial().optional()
|
|
2474
2860
|
});
|
|
2475
2861
|
var UpdateWalletPolicySchema = WalletPolicySchema.partial();
|
|
2476
|
-
var FundWalletSchema =
|
|
2862
|
+
var FundWalletSchema = z28.object({
|
|
2477
2863
|
amount_micro_usd: MicroUsdField.positive(),
|
|
2478
2864
|
source: WalletFundSourceSchema
|
|
2479
2865
|
});
|
|
2480
|
-
var TransferWalletSchema =
|
|
2481
|
-
to:
|
|
2866
|
+
var TransferWalletSchema = z28.object({
|
|
2867
|
+
to: z28.union([EvmAddressSchema, idOf("idn")]),
|
|
2482
2868
|
amount_micro_usd: MicroUsdField.positive(),
|
|
2483
|
-
purpose:
|
|
2869
|
+
purpose: z28.string().min(1).max(256)
|
|
2484
2870
|
});
|
|
2485
|
-
var SweepWalletSchema =
|
|
2486
|
-
var WalletTransactionSchema =
|
|
2871
|
+
var SweepWalletSchema = z28.object({ to: EvmAddressSchema.optional() });
|
|
2872
|
+
var WalletTransactionSchema = z28.object({
|
|
2487
2873
|
id: idOf("wtx"),
|
|
2488
|
-
object:
|
|
2874
|
+
object: z28.literal("wallet_transaction"),
|
|
2489
2875
|
wallet_id: idOf("wlt"),
|
|
2490
2876
|
kind: WalletTransactionKindSchema,
|
|
2491
2877
|
direction: WalletDirectionSchema,
|
|
2492
2878
|
amount_micro_usd: MicroUsdField,
|
|
2493
|
-
counterparty:
|
|
2494
|
-
origin:
|
|
2495
|
-
purpose:
|
|
2879
|
+
counterparty: z28.string().nullable(),
|
|
2880
|
+
origin: z28.string().nullable(),
|
|
2881
|
+
purpose: z28.string().nullable(),
|
|
2496
2882
|
tx_hash: TxHashSchema.nullable(),
|
|
2497
2883
|
session_id: idOf("ses").nullable(),
|
|
2498
2884
|
status: WalletTransactionStatusSchema,
|
|
2499
2885
|
created_at: Timestamp
|
|
2500
2886
|
});
|
|
2501
|
-
var ListWalletTransactionsSchema =
|
|
2887
|
+
var ListWalletTransactionsSchema = z28.object({
|
|
2502
2888
|
kind: WalletTransactionKindSchema.optional(),
|
|
2503
2889
|
direction: WalletDirectionSchema.optional(),
|
|
2504
|
-
origin:
|
|
2890
|
+
origin: z28.string().optional(),
|
|
2505
2891
|
since: Timestamp.optional()
|
|
2506
2892
|
});
|
|
2507
|
-
var HttpMethodSchema =
|
|
2508
|
-
var WalletQuoteRequestSchema =
|
|
2509
|
-
var WalletQuoteSchema =
|
|
2510
|
-
object:
|
|
2511
|
-
url:
|
|
2512
|
-
payable:
|
|
2893
|
+
var HttpMethodSchema = z28.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]);
|
|
2894
|
+
var WalletQuoteRequestSchema = z28.object({ url: z28.url(), method: HttpMethodSchema.optional() });
|
|
2895
|
+
var WalletQuoteSchema = z28.object({
|
|
2896
|
+
object: z28.literal("wallet_quote"),
|
|
2897
|
+
url: z28.url(),
|
|
2898
|
+
payable: z28.boolean(),
|
|
2513
2899
|
network: WalletNetworkSchema.nullable(),
|
|
2514
|
-
asset:
|
|
2900
|
+
asset: z28.literal("usdc").nullable(),
|
|
2515
2901
|
amount_micro_usd: MicroUsdField.nullable(),
|
|
2516
2902
|
pay_to: EvmAddressSchema.nullable(),
|
|
2517
|
-
description:
|
|
2518
|
-
max_timeout_seconds:
|
|
2903
|
+
description: z28.string().nullable(),
|
|
2904
|
+
max_timeout_seconds: z28.number().int().nullable()
|
|
2519
2905
|
});
|
|
2520
2906
|
var WalletPayRequestSchema = WalletQuoteRequestSchema.extend({
|
|
2521
2907
|
max_amount_micro_usd: MicroUsdField.positive().optional()
|
|
2522
2908
|
});
|
|
2523
2909
|
var WALLET_RESPONSE_BODY_MAX = 64 * 1024;
|
|
2524
|
-
var WalletPaymentSchema =
|
|
2525
|
-
object:
|
|
2526
|
-
paid:
|
|
2910
|
+
var WalletPaymentSchema = z28.object({
|
|
2911
|
+
object: z28.literal("wallet_payment"),
|
|
2912
|
+
paid: z28.boolean(),
|
|
2527
2913
|
transaction_id: idOf("wtx").nullable(),
|
|
2528
2914
|
amount_micro_usd: MicroUsdField.nullable(),
|
|
2529
|
-
response_status:
|
|
2530
|
-
response_body:
|
|
2915
|
+
response_status: z28.number().int(),
|
|
2916
|
+
response_body: z28.string().max(WALLET_RESPONSE_BODY_MAX)
|
|
2531
2917
|
});
|
|
2532
2918
|
|
|
2533
2919
|
// ../core/src/schema/cards.ts
|
|
2534
|
-
import { z as
|
|
2920
|
+
import { z as z29 } from "zod";
|
|
2535
2921
|
var CARD_STATUSES = ["pending_payment", "issuing", "active", "failed", "cancelled", "refunded"];
|
|
2536
|
-
var CardStatusSchema =
|
|
2922
|
+
var CardStatusSchema = z29.enum(CARD_STATUSES);
|
|
2537
2923
|
var CARD_MIN_LOAD_MICRO_USD = 1e6;
|
|
2538
2924
|
var CARD_MAX_LOAD_MICRO_USD = 15e7;
|
|
2539
2925
|
var CARD_LOAD_GRANULARITY_MICRO_USD = 1e4;
|
|
2540
|
-
var CardSchema =
|
|
2926
|
+
var CardSchema = z29.object({
|
|
2541
2927
|
id: idOf("vcd"),
|
|
2542
|
-
object:
|
|
2928
|
+
object: z29.literal("card"),
|
|
2543
2929
|
identity_id: idOf("idn"),
|
|
2544
|
-
kind:
|
|
2930
|
+
kind: z29.literal("prepaid"),
|
|
2545
2931
|
status: CardStatusSchema,
|
|
2546
|
-
label:
|
|
2547
|
-
brand:
|
|
2548
|
-
last4:
|
|
2932
|
+
label: z29.string().min(1).max(128),
|
|
2933
|
+
brand: z29.string().nullable(),
|
|
2934
|
+
last4: z29.string().regex(/^\d{4}$/).nullable(),
|
|
2549
2935
|
load_micro_usd: MicroUsdField,
|
|
2550
2936
|
spent_micro_usd: MicroUsdField,
|
|
2551
|
-
currency:
|
|
2937
|
+
currency: z29.literal("usd"),
|
|
2552
2938
|
expires_at: Timestamp.nullable(),
|
|
2553
|
-
failure_reason:
|
|
2939
|
+
failure_reason: z29.string().max(256).nullable(),
|
|
2554
2940
|
created_at: Timestamp,
|
|
2555
2941
|
updated_at: Timestamp
|
|
2556
2942
|
});
|
|
2557
|
-
var IssueCardSchema =
|
|
2943
|
+
var IssueCardSchema = z29.object({
|
|
2558
2944
|
label: CardSchema.shape.label,
|
|
2559
2945
|
load_micro_usd: MicroUsdField.min(CARD_MIN_LOAD_MICRO_USD).max(CARD_MAX_LOAD_MICRO_USD).multipleOf(CARD_LOAD_GRANULARITY_MICRO_USD)
|
|
2560
2946
|
});
|
|
2561
2947
|
var CardQuoteRequestSchema = IssueCardSchema.pick({ load_micro_usd: true });
|
|
2562
|
-
var CardQuoteSchema =
|
|
2563
|
-
object:
|
|
2948
|
+
var CardQuoteSchema = z29.object({
|
|
2949
|
+
object: z29.literal("card_quote"),
|
|
2564
2950
|
load_micro_usd: MicroUsdField,
|
|
2565
2951
|
price_micro_usd: MicroUsdField,
|
|
2566
|
-
brand:
|
|
2952
|
+
brand: z29.string().nullable(),
|
|
2567
2953
|
min_load_micro_usd: MicroUsdField,
|
|
2568
2954
|
max_load_micro_usd: MicroUsdField
|
|
2569
2955
|
});
|
|
2570
|
-
var CardCredentialsSchema =
|
|
2571
|
-
object:
|
|
2956
|
+
var CardCredentialsSchema = z29.object({
|
|
2957
|
+
object: z29.literal("card_credentials"),
|
|
2572
2958
|
card_id: idOf("vcd"),
|
|
2573
|
-
number:
|
|
2574
|
-
pin:
|
|
2575
|
-
cvv:
|
|
2576
|
-
expiry:
|
|
2577
|
-
url:
|
|
2578
|
-
instructions:
|
|
2959
|
+
number: z29.string().min(1),
|
|
2960
|
+
pin: z29.string().nullable(),
|
|
2961
|
+
cvv: z29.string().nullable(),
|
|
2962
|
+
expiry: z29.string().nullable(),
|
|
2963
|
+
url: z29.url().nullable(),
|
|
2964
|
+
instructions: z29.string().nullable(),
|
|
2579
2965
|
revealed_at: Timestamp
|
|
2580
2966
|
});
|
|
2581
|
-
var CardTransactionSchema =
|
|
2967
|
+
var CardTransactionSchema = z29.object({
|
|
2582
2968
|
id: idOf("vct"),
|
|
2583
|
-
object:
|
|
2969
|
+
object: z29.literal("card_transaction"),
|
|
2584
2970
|
card_id: idOf("vcd"),
|
|
2585
2971
|
amount_micro_usd: MicroUsdField,
|
|
2586
|
-
merchant:
|
|
2587
|
-
description:
|
|
2972
|
+
merchant: z29.string().nullable(),
|
|
2973
|
+
description: z29.string().nullable(),
|
|
2588
2974
|
session_id: idOf("ses").nullable(),
|
|
2589
2975
|
metadata: Metadata,
|
|
2590
2976
|
created_at: Timestamp
|
|
2591
2977
|
});
|
|
2592
|
-
var LogCardTransactionSchema =
|
|
2978
|
+
var LogCardTransactionSchema = z29.object({
|
|
2593
2979
|
amount_micro_usd: MicroUsdField.positive(),
|
|
2594
|
-
merchant:
|
|
2595
|
-
description:
|
|
2980
|
+
merchant: z29.string().max(256).optional(),
|
|
2981
|
+
description: z29.string().max(1024).optional(),
|
|
2596
2982
|
metadata: Metadata.optional()
|
|
2597
2983
|
});
|
|
2598
|
-
var ListCardsSchema =
|
|
2984
|
+
var ListCardsSchema = z29.object({ status: CardStatusSchema.optional() });
|
|
2599
2985
|
|
|
2600
2986
|
// ../core/src/schema/proxy-trace.ts
|
|
2601
|
-
import { z as
|
|
2602
|
-
var ProxyDialectSchema =
|
|
2603
|
-
var ProxyTraceContentScopeSchema =
|
|
2604
|
-
var
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2987
|
+
import { z as z30 } from "zod";
|
|
2988
|
+
var ProxyDialectSchema = z30.enum(["anthropic", "openai", "native"]);
|
|
2989
|
+
var ProxyTraceContentScopeSchema = z30.enum(["full", "metadata", "object"]);
|
|
2990
|
+
var TraceToolCall = z30.object({ id: z30.string().optional(), name: z30.string(), arguments: z30.string() });
|
|
2991
|
+
var ProxyTraceRequestSchema = z30.object({
|
|
2992
|
+
model: z30.string().optional(),
|
|
2993
|
+
window: WindowSchema.optional(),
|
|
2994
|
+
system: z30.string(),
|
|
2995
|
+
messages: z30.array(
|
|
2996
|
+
z30.looseObject({
|
|
2997
|
+
role: z30.string(),
|
|
2998
|
+
content: z30.string(),
|
|
2999
|
+
tool_calls: z30.array(z30.looseObject({ id: z30.string(), name: z30.string() })).optional(),
|
|
3000
|
+
tool_call_id: z30.string().optional()
|
|
3001
|
+
})
|
|
3002
|
+
),
|
|
3003
|
+
tools: z30.array(z30.object({ name: z30.string(), description: z30.string(), parameters: z30.record(z30.string(), z30.unknown()) })).optional(),
|
|
3004
|
+
tool_schema_hash: z30.string().optional(),
|
|
3005
|
+
max_output_tokens: z30.number().int().optional(),
|
|
3006
|
+
tool_names: z30.array(z30.string()).optional()
|
|
3007
|
+
});
|
|
3008
|
+
var ProxyTraceResponseSchema = z30.object({
|
|
3009
|
+
text: z30.string(),
|
|
3010
|
+
reasoning: z30.string().optional(),
|
|
3011
|
+
reasoning_details: z30.array(z30.unknown()).optional(),
|
|
3012
|
+
tool_calls: z30.array(TraceToolCall),
|
|
3013
|
+
/** A call that threw, was abandoned or never completed (ADR-0794): the reply is what streamed before. */
|
|
3014
|
+
is_error: z30.literal(true).optional(),
|
|
3015
|
+
/** The error's class name — never its message — or `incomplete` for a stream that just stopped. */
|
|
3016
|
+
error_class: z30.string().optional(),
|
|
3017
|
+
partial: z30.literal(true).optional()
|
|
3018
|
+
});
|
|
3019
|
+
var Sha256 = z30.string().regex(/^[0-9a-f]{64}$/);
|
|
3020
|
+
var ProxyCallTraceSchema = z30.object({
|
|
2615
3021
|
/** The request id: also `x-request-id`, the reply's `id`, and the ledger entry's idempotency key. */
|
|
2616
3022
|
id: idOf("req"),
|
|
2617
|
-
object:
|
|
3023
|
+
object: z30.literal("proxy_call_trace"),
|
|
2618
3024
|
dialect: ProxyDialectSchema,
|
|
2619
3025
|
/** The principal that made the call (§17). An API key here is the answer to "who sent this". */
|
|
2620
3026
|
actor: PrincipalSchema,
|
|
2621
3027
|
/** The public model id the caller asked for. */
|
|
2622
|
-
model:
|
|
3028
|
+
model: z30.string(),
|
|
2623
3029
|
window: WindowSchema,
|
|
2624
3030
|
/** The model the reply said served it — where `vetta/auto` resolves — or null if it named none. */
|
|
2625
|
-
resolved_model:
|
|
3031
|
+
resolved_model: z30.string().nullable(),
|
|
2626
3032
|
/**
|
|
2627
3033
|
* The serving provider and the gateway's own generation id. Null on every row written before the
|
|
2628
3034
|
* adapter stops dropping them (Track A); together they are what lets an upstream invoice line be
|
|
2629
3035
|
* matched back to an organization, a key and a ledger entry.
|
|
2630
3036
|
*/
|
|
2631
|
-
provider:
|
|
2632
|
-
generation_id:
|
|
2633
|
-
stop:
|
|
3037
|
+
provider: z30.string().nullable(),
|
|
3038
|
+
generation_id: z30.string().nullable(),
|
|
3039
|
+
stop: z30.enum(["end_turn", "tool_use", "length"]).nullable(),
|
|
2634
3040
|
usage: TokenUsageSchema,
|
|
2635
3041
|
/** What the customer was charged, µUSD. The ledger entry is the authority; this is its copy. */
|
|
2636
3042
|
billed_micro_usd: MicroUsdField.nullable(),
|
|
2637
3043
|
/** What the vendor said it cost, µUSD. A CROSS-CHECK, NEVER A DEBIT. */
|
|
2638
3044
|
vendor_cost_micro_usd: MicroUsdField.nullable(),
|
|
2639
|
-
duration_ms:
|
|
3045
|
+
duration_ms: z30.number().int().nonnegative().nullable(),
|
|
2640
3046
|
content_scope: ProxyTraceContentScopeSchema,
|
|
3047
|
+
/** `proxy` — a `/v1/proxy/*` call; `harness` — a hosted harness's own model call (ADR-0762). */
|
|
3048
|
+
source: z30.enum(["proxy", "harness"]),
|
|
3049
|
+
/** The session the call belongs to: a harness call's, or a sandbox token's `sub` on the proxy. */
|
|
3050
|
+
session_id: z30.string().nullable(),
|
|
3051
|
+
/**
|
|
3052
|
+
* The `seq` of the call's `span.model_request.end` event — or of its `.start` when the call failed
|
|
3053
|
+
* or its `.end` was withheld (ADR-0794). Null on the proxy, which writes no event.
|
|
3054
|
+
*/
|
|
3055
|
+
seq: z30.number().int().nullable(),
|
|
3056
|
+
/** The board card the session was woken for (`session.metadata.board.card_id`), or null. */
|
|
3057
|
+
board_card_id: z30.string().nullable(),
|
|
3058
|
+
/** The ids of the tool calls this reply made — the join to the `tool.*` events they caused. */
|
|
3059
|
+
tool_call_ids: z30.array(z30.string()),
|
|
3060
|
+
/** sha-256 of the canonical JSON of the tool schema array the model was offered, or null. */
|
|
3061
|
+
tool_schema_hash: Sha256.nullable(),
|
|
2641
3062
|
request_sha256: Sha256,
|
|
2642
3063
|
response_sha256: Sha256,
|
|
2643
|
-
/** The size of each body
|
|
2644
|
-
request_bytes:
|
|
2645
|
-
response_bytes:
|
|
2646
|
-
/**
|
|
3064
|
+
/** The UTF-8 size of each stored body. */
|
|
3065
|
+
request_bytes: z30.number().int().nonnegative(),
|
|
3066
|
+
response_bytes: z30.number().int().nonnegative(),
|
|
3067
|
+
/** Inline in `full` scope — every new row. Null on a legacy `metadata` or `object` row. */
|
|
2647
3068
|
request: ProxyTraceRequestSchema.nullable(),
|
|
2648
3069
|
response: ProxyTraceResponseSchema.nullable(),
|
|
2649
|
-
|
|
3070
|
+
/** Always false since ADR-0762 (nothing is cut); true only on rows from before it. */
|
|
3071
|
+
truncated: z30.boolean(),
|
|
2650
3072
|
created_at: Timestamp,
|
|
2651
|
-
/** When the reaper deletes this row.
|
|
2652
|
-
expires_at: Timestamp
|
|
3073
|
+
/** When the reaper deletes this row. Null since ADR-0762: model I/O is kept, not expired. */
|
|
3074
|
+
expires_at: Timestamp.nullable()
|
|
3075
|
+
});
|
|
3076
|
+
|
|
3077
|
+
// ../core/src/schema/review.ts
|
|
3078
|
+
import { z as z31 } from "zod";
|
|
3079
|
+
var ReviewDecisionSchema = z31.enum(["approve", "reject", "edit"]);
|
|
3080
|
+
var Fields = z31.record(z31.string().max(100), z31.unknown()).nullable().optional();
|
|
3081
|
+
var CreateReviewSchema = z31.object({
|
|
3082
|
+
decision: ReviewDecisionSchema,
|
|
3083
|
+
reason: z31.string().max(4e3).nullable().optional(),
|
|
3084
|
+
file_ids: z31.array(idOf("fil")).max(50).optional(),
|
|
3085
|
+
session_id: idOf("ses").optional(),
|
|
3086
|
+
subject: z31.record(z31.string().max(100), z31.unknown()).optional(),
|
|
3087
|
+
before: Fields,
|
|
3088
|
+
after: Fields
|
|
3089
|
+
});
|
|
3090
|
+
|
|
3091
|
+
// ../core/src/schema/mini-app.ts
|
|
3092
|
+
import { z as z32 } from "zod";
|
|
3093
|
+
var PAGE_BLOCKS = [
|
|
3094
|
+
"Page",
|
|
3095
|
+
"Section",
|
|
3096
|
+
"Stack",
|
|
3097
|
+
"Grid",
|
|
3098
|
+
"Metric",
|
|
3099
|
+
"LineChart",
|
|
3100
|
+
"BarList",
|
|
3101
|
+
"Progress",
|
|
3102
|
+
"Roadmap",
|
|
3103
|
+
"Schedule",
|
|
3104
|
+
"Media",
|
|
3105
|
+
"Text",
|
|
3106
|
+
"Needs",
|
|
3107
|
+
"Activity",
|
|
3108
|
+
"Accounts",
|
|
3109
|
+
"Posts",
|
|
3110
|
+
"Answers",
|
|
3111
|
+
"MediaLibrary"
|
|
3112
|
+
];
|
|
3113
|
+
var MAX_PAGE_ELEMENTS = 48;
|
|
3114
|
+
var MINI_APP_ICONS = ["grid", "list", "chart", "calendar", "play"];
|
|
3115
|
+
var MiniAppIconSchema = z32.enum(MINI_APP_ICONS);
|
|
3116
|
+
var SLUG = "[a-z][a-z0-9-]{0,39}";
|
|
3117
|
+
var MiniAppSlugSchema = z32.string().regex(new RegExp(`^${SLUG}$`), "a slug is lowercase letters, digits and -");
|
|
3118
|
+
var Place = z32.string().regex(new RegExp(`^/(board|connections|apps/${SLUG}(\\?page=${SLUG})?)$`), "a section links to /board, /connections or /apps/<slug>[?page=<slug>]");
|
|
3119
|
+
var POSTS = ["waiting", "scheduled", "posted"];
|
|
3120
|
+
var PostStatus = z32.enum(POSTS);
|
|
3121
|
+
var PostLayout = z32.enum(["list", "row", "grid"]);
|
|
3122
|
+
var PostStatuses = z32.union([PostStatus, z32.array(PostStatus).min(1).max(3).refine((all) => new Set(all).size === all.length, "each status once")]);
|
|
3123
|
+
var PageBound = {
|
|
3124
|
+
...Bound,
|
|
3125
|
+
board: bound(["roadmap"], { per_group: z32.number().int().min(1).max(5).default(5) }),
|
|
3126
|
+
media: bound(["latest_media", "newest_media"], { count: z32.number().int().min(1).max(6).default(4) })
|
|
3127
|
+
};
|
|
3128
|
+
var PageResolved = {
|
|
3129
|
+
...Resolved,
|
|
3130
|
+
board: z32.strictObject({ $source: z32.literal("roadmap"), per_group: z32.number().int(), groups: RoadmapViewSchema.shape.groups }),
|
|
3131
|
+
media: z32.array(z32.strictObject({ id: z32.string(), kind: z32.enum(["image", "video"]) })).max(6)
|
|
3132
|
+
};
|
|
3133
|
+
function pageBlocks(slot) {
|
|
3134
|
+
return {
|
|
3135
|
+
Page: element("Page", {}, box, "The page itself, the root and only the root."),
|
|
3136
|
+
Section: element("Section", { title: words(40), to: Place.optional(), hide_empty: z32.boolean().optional() }, box, "A titled part of the page; hidden when every block in it is empty, if asked."),
|
|
3137
|
+
Needs: element("Needs", { label, needs: slot.needs }, leaf, "What waits on a person: approvals, questions, spent caps."),
|
|
3138
|
+
Activity: element("Activity", { label, agents: slot.agents }, leaf, "The agents working or waiting, and on what."),
|
|
3139
|
+
Accounts: element("Accounts", { accounts: slot.accounts }, leaf, "The template's networks: connected with a handle, or not."),
|
|
3140
|
+
Posts: element(
|
|
3141
|
+
"Posts",
|
|
3142
|
+
{ label, layout: PostLayout.optional(), posts: slot.posts },
|
|
3143
|
+
leaf,
|
|
3144
|
+
"Posts waiting on a person, scheduled, or posted; several statuses make one list. Drawn as rows (list, the default), one sideways row of cards (row), or a picture grid (grid)."
|
|
3145
|
+
),
|
|
3146
|
+
Answers: element("Answers", { answers: slot.answers }, leaf, "The setup's answers in one line, linking to the setup."),
|
|
3147
|
+
// No binding: the studio's gallery reads and pages the company's files itself (ADR-0987).
|
|
3148
|
+
MediaLibrary: element("MediaLibrary", {}, leaf, "Every picture and clip the company's agents made, with filters, sort and a viewer.")
|
|
3149
|
+
};
|
|
3150
|
+
}
|
|
3151
|
+
var OwnBound = pageBlocks({
|
|
3152
|
+
needs: bound(["needs"], {}),
|
|
3153
|
+
agents: bound(["agents_activity"], {}),
|
|
3154
|
+
accounts: bound(["accounts"], {}),
|
|
3155
|
+
posts: bound(["posts"], { status: PostStatuses, limit: z32.number().int().min(1).max(50).default(10) }),
|
|
3156
|
+
answers: bound(["answers"], { keys: z32.array(Key).min(1).max(TEMPLATE_QUESTIONS_MAX) })
|
|
3157
|
+
});
|
|
3158
|
+
var Need = z32.object({
|
|
3159
|
+
session_id: z32.string(),
|
|
3160
|
+
agent_id: z32.string(),
|
|
3161
|
+
agent: z32.string(),
|
|
3162
|
+
since: Timestamp,
|
|
3163
|
+
/** The chat's stored title, or `null`: the studio names it by when it began. */
|
|
3164
|
+
title: z32.string().nullable(),
|
|
3165
|
+
kind: z32.enum(["tool", "question", "budget"]),
|
|
3166
|
+
/** The call or question it is held on; `null` for a spent cap. */
|
|
3167
|
+
action: PendingActionSchema.nullable()
|
|
3168
|
+
});
|
|
3169
|
+
var Working = z32.object({
|
|
3170
|
+
agent_id: z32.string(),
|
|
3171
|
+
agent: z32.string(),
|
|
3172
|
+
state: z32.enum(["working", "waiting"]),
|
|
3173
|
+
session_id: z32.string().nullable(),
|
|
3174
|
+
title: z32.string().nullable(),
|
|
3175
|
+
at: Timestamp
|
|
3176
|
+
});
|
|
3177
|
+
var OwnResolved = pageBlocks({
|
|
3178
|
+
needs: z32.strictObject({ $source: z32.literal("needs"), items: z32.array(Need) }),
|
|
3179
|
+
agents: z32.strictObject({ $source: z32.literal("agents_activity"), agents: z32.array(Working) }),
|
|
3180
|
+
accounts: z32.strictObject({
|
|
3181
|
+
$source: z32.literal("accounts"),
|
|
3182
|
+
accounts: z32.array(z32.object({ platform: SocialPlatformSchema, connected: z32.boolean(), handle: z32.string().nullable() }))
|
|
3183
|
+
}),
|
|
3184
|
+
posts: z32.strictObject({ $source: z32.literal("posts"), status: z32.union([PostStatus, z32.array(PostStatus)]), limit: z32.number().int(), posts: z32.array(PostSchema), more: z32.boolean() }),
|
|
3185
|
+
answers: z32.strictObject({
|
|
3186
|
+
$source: z32.literal("answers"),
|
|
3187
|
+
keys: z32.array(z32.string()),
|
|
3188
|
+
values: z32.array(z32.string()),
|
|
3189
|
+
template: z32.object({ blueprint: z32.string(), template: z32.string() }).nullable()
|
|
3190
|
+
})
|
|
2653
3191
|
});
|
|
3192
|
+
var BoundBlocks = { ...catalog(PageBound), ...OwnBound };
|
|
3193
|
+
var ResolvedBlocks = { ...catalog(PageResolved), ...OwnResolved };
|
|
3194
|
+
var Unread = element("Unread", { of: z32.string(), label: z32.string().nullable(), reason: z32.string() }, leaf, "A block that could not be read.");
|
|
3195
|
+
var B = BoundBlocks;
|
|
3196
|
+
var PageSpecSchema = spec(
|
|
3197
|
+
z32.discriminatedUnion(
|
|
3198
|
+
"type",
|
|
3199
|
+
[B.Page, B.Section, B.Stack, B.Grid, B.Metric, B.LineChart, B.BarList, B.Progress, B.Roadmap, B.Schedule, B.Media, B.Text, B.Needs, B.Activity, B.Accounts, B.Posts, B.Answers, B.MediaLibrary],
|
|
3200
|
+
unknownComponent(PAGE_BLOCKS)
|
|
3201
|
+
),
|
|
3202
|
+
"Page",
|
|
3203
|
+
MAX_PAGE_ELEMENTS
|
|
3204
|
+
);
|
|
3205
|
+
var R = ResolvedBlocks;
|
|
3206
|
+
var ResolvedPageElementSchema = z32.discriminatedUnion(
|
|
3207
|
+
"type",
|
|
3208
|
+
[R.Page, R.Section, R.Stack, R.Grid, R.Metric, R.LineChart, R.BarList, R.Progress, R.Roadmap, R.Schedule, R.Media, R.Text, R.Needs, R.Activity, R.Accounts, R.Posts, R.Answers, R.MediaLibrary, Unread],
|
|
3209
|
+
unknownComponent(PAGE_BLOCKS)
|
|
3210
|
+
);
|
|
3211
|
+
var ResolvedPageSpecSchema = spec(ResolvedPageElementSchema, "Page", MAX_PAGE_ELEMENTS);
|
|
3212
|
+
var unique = (items) => new Set(items.map((item) => item.slug)).size === items.length;
|
|
3213
|
+
var MiniAppPageSchema = z32.strictObject({ slug: MiniAppSlugSchema, title: words(24), spec: PageSpecSchema });
|
|
3214
|
+
var MiniAppDeclSchema = z32.strictObject({
|
|
3215
|
+
slug: MiniAppSlugSchema,
|
|
3216
|
+
name: words(40),
|
|
3217
|
+
icon: MiniAppIconSchema,
|
|
3218
|
+
pages: z32.array(MiniAppPageSchema).min(1).max(6).refine(unique, "each page's slug is its own")
|
|
3219
|
+
});
|
|
3220
|
+
var MiniAppDeclsSchema = z32.array(MiniAppDeclSchema).max(8).refine(unique, "each mini app's slug is its own");
|
|
3221
|
+
var MiniAppSummarySchema = z32.object({
|
|
3222
|
+
object: z32.literal("mini_app"),
|
|
3223
|
+
slug: MiniAppSlugSchema,
|
|
3224
|
+
name: z32.string(),
|
|
3225
|
+
icon: MiniAppIconSchema,
|
|
3226
|
+
pages: z32.array(z32.object({ slug: MiniAppSlugSchema, title: z32.string() })).min(1),
|
|
3227
|
+
/** What it reads (`miniAppReads`). Absent from an older API: the Studio then claims nothing it cannot see. */
|
|
3228
|
+
reads: z32.array(z32.string()).optional()
|
|
3229
|
+
});
|
|
3230
|
+
var MiniAppSchema = MiniAppSummarySchema.extend({
|
|
3231
|
+
networks: z32.array(z32.object({ platform: SocialPlatformSchema, connected: z32.boolean().nullable() })),
|
|
3232
|
+
page: MiniAppSlugSchema,
|
|
3233
|
+
as_of: Timestamp,
|
|
3234
|
+
timezone: z32.string().min(1),
|
|
3235
|
+
spec: ResolvedPageSpecSchema
|
|
3236
|
+
});
|
|
3237
|
+
|
|
3238
|
+
// ../core/src/logo-svg.ts
|
|
3239
|
+
var MAX_BYTES = 16 * 1024;
|
|
3240
|
+
|
|
3241
|
+
// ../core/src/file-url.ts
|
|
3242
|
+
var encoder2 = new TextEncoder();
|
|
3243
|
+
var SESSION_FILE_URL_TTL_MS = 15 * 6e4;
|
|
2654
3244
|
|
|
2655
3245
|
// src/define.ts
|
|
2656
|
-
import { z as
|
|
3246
|
+
import { z as z35 } from "zod";
|
|
2657
3247
|
|
|
2658
3248
|
// src/roster.ts
|
|
2659
|
-
import { z as
|
|
3249
|
+
import { z as z34 } from "zod";
|
|
2660
3250
|
|
|
2661
3251
|
// src/report.ts
|
|
2662
3252
|
import { ApiError, send } from "@usenaive-sdk/vetta";
|
|
2663
|
-
import { z as
|
|
3253
|
+
import { z as z33 } from "zod";
|
|
2664
3254
|
function message(error) {
|
|
2665
3255
|
if (error instanceof ApiError && error.requestId !== "") return `${error.message} (request ${error.requestId})`;
|
|
2666
3256
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -2702,15 +3292,15 @@ async function absent(work) {
|
|
|
2702
3292
|
throw error;
|
|
2703
3293
|
}
|
|
2704
3294
|
}
|
|
2705
|
-
var PageShape =
|
|
2706
|
-
data:
|
|
2707
|
-
has_more:
|
|
2708
|
-
next_cursor:
|
|
3295
|
+
var PageShape = z33.object({
|
|
3296
|
+
data: z33.array(z33.unknown()),
|
|
3297
|
+
has_more: z33.boolean(),
|
|
3298
|
+
next_cursor: z33.string().nullable()
|
|
2709
3299
|
});
|
|
2710
3300
|
function rowLabel(row) {
|
|
2711
3301
|
const { object, id } = row ?? {};
|
|
2712
|
-
const
|
|
2713
|
-
return
|
|
3302
|
+
const words2 = [object, id].filter((one) => typeof one === "string");
|
|
3303
|
+
return words2.length > 0 ? words2.join(" ") : "a row";
|
|
2714
3304
|
}
|
|
2715
3305
|
var why = (error) => error.issues.map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`).join("; ");
|
|
2716
3306
|
async function listAll(config, path, item, skipped, query = {}) {
|
|
@@ -2737,17 +3327,17 @@ async function tombstone(name, current, remove, dryRun) {
|
|
|
2737
3327
|
}
|
|
2738
3328
|
|
|
2739
3329
|
// src/roster.ts
|
|
2740
|
-
var NAME =
|
|
2741
|
-
var RosterNameSchema =
|
|
3330
|
+
var NAME = z34.string().min(1);
|
|
3331
|
+
var RosterNameSchema = z34.union([
|
|
2742
3332
|
NAME.transform((name) => ({ type: "agent", name })),
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
3333
|
+
z34.object({ type: z34.literal("agent"), name: NAME, version: z34.number().int().positive().optional() }),
|
|
3334
|
+
z34.object({ type: z34.literal("self") }),
|
|
3335
|
+
z34.object({ type: z34.literal("advisor"), model: z34.string().min(1) })
|
|
2746
3336
|
]);
|
|
2747
|
-
var DeclMultiagentField =
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
3337
|
+
var DeclMultiagentField = z34.union([
|
|
3338
|
+
z34.boolean(),
|
|
3339
|
+
z34.object({ ...MultiagentSchema.shape, agents: z34.array(RosterNameSchema).min(1).max(20) }),
|
|
3340
|
+
z34.null()
|
|
2751
3341
|
]);
|
|
2752
3342
|
var hasRoster = (value) => typeof value === "object" && value !== null;
|
|
2753
3343
|
var rosterNames = (roster) => roster.agents.flatMap((entry) => entry.type === "agent" ? [entry.name] : []);
|
|
@@ -2800,8 +3390,12 @@ async function patchRoster(client, decl, roster, existing, ids, dryRun, lines) {
|
|
|
2800
3390
|
var BLUEPRINTS = {
|
|
2801
3391
|
/** Clients, pipeline, deliverables, calendar. */
|
|
2802
3392
|
agency: { templates: ["blank", "seo-geo"], default: "blank" },
|
|
2803
|
-
/**
|
|
2804
|
-
|
|
3393
|
+
/**
|
|
3394
|
+
* Post queue, accounts, calendar, analytics. The wire ids are frozen: `install.template` is a
|
|
3395
|
+
* stored string on every provisioned org, so the display names moved ("Naive Short Form v1",
|
|
3396
|
+
* "Naive Long Form v1", "Naive Clipping v1") and these did not.
|
|
3397
|
+
*/
|
|
3398
|
+
media: { templates: ["faceless", "longform", "clipping"] },
|
|
2805
3399
|
/** Pages, posts, forms, analytics — a published site with a crew behind it (`usenaive/web-blueprint`). */
|
|
2806
3400
|
web: { templates: ["publisher"], default: "publisher" }
|
|
2807
3401
|
};
|
|
@@ -2835,65 +3429,65 @@ function chooseTemplate(blueprint, template) {
|
|
|
2835
3429
|
var BlueprintRefusal = class extends Error {
|
|
2836
3430
|
name = "BlueprintRefusal";
|
|
2837
3431
|
};
|
|
2838
|
-
var EnvValueSchema =
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
3432
|
+
var EnvValueSchema = z35.union([
|
|
3433
|
+
z35.string(),
|
|
3434
|
+
z35.object({ from_env: z35.string().min(1) }),
|
|
3435
|
+
z35.object({ generate: z35.literal(true) })
|
|
2842
3436
|
]);
|
|
2843
|
-
var AppDeclSchema =
|
|
3437
|
+
var AppDeclSchema = z35.object({
|
|
2844
3438
|
/** Becomes a hostname, so the grammar is the platform's `APP_NAME` (a DNS label). */
|
|
2845
|
-
name:
|
|
3439
|
+
name: z35.string().regex(APP_NAME, "a lowercase DNS label, 63 characters or fewer"),
|
|
2846
3440
|
type: AppTypeSchema,
|
|
2847
|
-
description:
|
|
3441
|
+
description: z35.string().optional(),
|
|
2848
3442
|
/** A directory whose files are collected and shipped as the app's file-map deployment. */
|
|
2849
|
-
deploy_dir:
|
|
3443
|
+
deploy_dir: z35.string().min(1).optional(),
|
|
2850
3444
|
/** The path the app itself serves MCP on (§29.5); `fullstack` only. Absent means none. */
|
|
2851
3445
|
mcp: AppMcpPathSchema.optional(),
|
|
2852
3446
|
/** Written as the app's write-only secrets (§29.2) on every apply; names follow the platform's `ENV_NAME`. */
|
|
2853
|
-
env:
|
|
3447
|
+
env: z35.record(z35.string().regex(ENV_NAME), EnvValueSchema, { error: "keyed by environment variable name (A-Z, 0-9, _)" }).optional(),
|
|
2854
3448
|
/** An install may not leave this app out of its `selection` (§31.2). Absent means it may. */
|
|
2855
|
-
required:
|
|
3449
|
+
required: z35.boolean().optional(),
|
|
2856
3450
|
// core-gaps: U8-database
|
|
2857
3451
|
/** SQL files applied in order to the app's database after it is provisioned (§37); `fullstack` only. */
|
|
2858
|
-
migrations:
|
|
3452
|
+
migrations: z35.array(z35.string().min(1)).optional(),
|
|
2859
3453
|
// core-gaps: storage-stock
|
|
2860
3454
|
/** Buckets the app's object store must hold (§38.2); `fullstack` only. `public` defaults to false. */
|
|
2861
|
-
buckets:
|
|
3455
|
+
buckets: z35.array(CreateBucketSchema).optional()
|
|
2862
3456
|
});
|
|
2863
|
-
var ScheduleDeclSchema =
|
|
2864
|
-
cron:
|
|
2865
|
-
timezone:
|
|
3457
|
+
var ScheduleDeclSchema = z35.object({
|
|
3458
|
+
cron: z35.string().min(1),
|
|
3459
|
+
timezone: z35.string().min(1).optional(),
|
|
2866
3460
|
/** The message every fire opens its session with (`input_template` on the wire). */
|
|
2867
|
-
input:
|
|
3461
|
+
input: z35.string().min(1),
|
|
2868
3462
|
budget_micro_usd: MicroUsdField.nonnegative(),
|
|
2869
|
-
identity:
|
|
2870
|
-
enabled:
|
|
3463
|
+
identity: z35.string().min(1).optional(),
|
|
3464
|
+
enabled: z35.boolean().optional()
|
|
2871
3465
|
});
|
|
2872
3466
|
var ToolsDeclSchema = ToolsetSchema;
|
|
2873
|
-
var AgentDeclSchema =
|
|
2874
|
-
name:
|
|
2875
|
-
model:
|
|
3467
|
+
var AgentDeclSchema = z35.object({
|
|
3468
|
+
name: z35.string().min(1),
|
|
3469
|
+
model: z35.string().min(1),
|
|
2876
3470
|
budget: BudgetSchema,
|
|
2877
|
-
description:
|
|
3471
|
+
description: z35.string().optional(),
|
|
2878
3472
|
/** Two or three words the studio prints beside the name (§31.5) — "Head of content", not a sentence. */
|
|
2879
|
-
role:
|
|
3473
|
+
role: z35.string().min(1).optional(),
|
|
2880
3474
|
/** An install may not leave this agent out of its `selection` (§31.2). Absent means it may. */
|
|
2881
|
-
required:
|
|
2882
|
-
system:
|
|
3475
|
+
required: z35.boolean().optional(),
|
|
3476
|
+
system: z35.string().optional(),
|
|
2883
3477
|
tools: ToolsDeclSchema.optional(),
|
|
2884
|
-
skills:
|
|
2885
|
-
mcp_servers:
|
|
3478
|
+
skills: z35.array(SkillRefSchema).optional(),
|
|
3479
|
+
mcp_servers: z35.array(McpServerSchema).optional(),
|
|
2886
3480
|
/** The rest of the runtime's agent config (§31.6), each the core schema; absent means the route's default and never drift. */
|
|
2887
3481
|
window: WindowSchema.optional(),
|
|
2888
3482
|
/** A roster names crew members by declared *name*; `up` resolves them to `agt_` ids in a second pass (`roster.ts`). */
|
|
2889
3483
|
multiagent: DeclMultiagentField.optional(),
|
|
2890
3484
|
output_schema: JsonSchemaDocument.nullable().optional(),
|
|
2891
|
-
structured_output_required:
|
|
3485
|
+
structured_output_required: z35.boolean().optional(),
|
|
2892
3486
|
metadata: Metadata.optional(),
|
|
2893
3487
|
/** Declared app *names*; `up` resolves them to `app_` ids in `tools.configs.apps` (§29.3). */
|
|
2894
|
-
allowed_apps:
|
|
3488
|
+
allowed_apps: z35.array(z35.string()).optional(),
|
|
2895
3489
|
/** A declared identity *name*; `up` attaches it after the agent upsert (§22). */
|
|
2896
|
-
identity:
|
|
3490
|
+
identity: z35.string().min(1).optional(),
|
|
2897
3491
|
/**
|
|
2898
3492
|
* Who this agent may `send_to_agent` (§31.7, §28.12): `true` (anyone in the organization),
|
|
2899
3493
|
* `false` (nobody), `"team"` (its `multiagent` roster), or declared agent *names*, checked
|
|
@@ -2901,7 +3495,7 @@ var AgentDeclSchema = z30.object({
|
|
|
2901
3495
|
*/
|
|
2902
3496
|
handoffs: HandoffsField.optional(),
|
|
2903
3497
|
/** The agent's deployments as a complete set: declared → owned, and the rest are pruned (ADR-0355). */
|
|
2904
|
-
schedules:
|
|
3498
|
+
schedules: z35.array(ScheduleDeclSchema).optional(),
|
|
2905
3499
|
/**
|
|
2906
3500
|
* The first thing this agent reads, once, on the apply that **creates** it (`canonical-spec
|
|
2907
3501
|
* §31.4`). It is what turns a provisioned crew into a crew that has started working.
|
|
@@ -2914,66 +3508,79 @@ var AgentDeclSchema = z30.object({
|
|
|
2914
3508
|
* repeatedly and unattended while an intake spends once, at an apply a person is watching. Absent
|
|
2915
3509
|
* means the agent's own `budget` governs.
|
|
2916
3510
|
*/
|
|
2917
|
-
intake:
|
|
3511
|
+
intake: z35.object({ message: z35.string().min(1), budget_micro_usd: MicroUsdField.nonnegative().optional() }).optional()
|
|
2918
3512
|
});
|
|
2919
|
-
var CredentialDeclSchema =
|
|
3513
|
+
var CredentialDeclSchema = z35.object({
|
|
2920
3514
|
kind: VaultCredentialKindSchema,
|
|
2921
|
-
key:
|
|
3515
|
+
key: z35.string().min(1).max(128),
|
|
2922
3516
|
/** The one exact destination host an `env_var` is bound to. */
|
|
2923
|
-
host:
|
|
3517
|
+
host: z35.string().min(1).optional(),
|
|
2924
3518
|
/** The MCP server URL a `static_bearer` / `mcp_oauth` token is matched to. */
|
|
2925
|
-
mcp_server_url:
|
|
2926
|
-
value:
|
|
3519
|
+
mcp_server_url: z35.url().optional(),
|
|
3520
|
+
value: z35.object({ from_env: z35.string().min(1) })
|
|
2927
3521
|
});
|
|
2928
|
-
var VaultDeclSchema =
|
|
3522
|
+
var VaultDeclSchema = z35.object({
|
|
2929
3523
|
name: VaultSchema.shape.display_name,
|
|
2930
|
-
identity:
|
|
2931
|
-
credentials:
|
|
3524
|
+
identity: z35.string().min(1).optional(),
|
|
3525
|
+
credentials: z35.array(CredentialDeclSchema)
|
|
2932
3526
|
});
|
|
2933
|
-
var SkillDeclSchema =
|
|
2934
|
-
slug:
|
|
2935
|
-
file:
|
|
3527
|
+
var SkillDeclSchema = z35.object({
|
|
3528
|
+
slug: z35.string().regex(/^[a-z0-9][a-z0-9-]*$/, "lowercase letters, digits and dashes"),
|
|
3529
|
+
file: z35.string().min(1)
|
|
2936
3530
|
});
|
|
2937
3531
|
var LegalDeclSchema = CreateLegalCompanySchema.pick({
|
|
2938
3532
|
state: true,
|
|
2939
3533
|
name_options: true,
|
|
2940
3534
|
naics_code: true,
|
|
2941
3535
|
description: true
|
|
2942
|
-
}).extend({ label:
|
|
3536
|
+
}).extend({ label: z35.string().min(1).max(128) });
|
|
2943
3537
|
var WalletDeclSchema = CreateWalletSchema.or(
|
|
2944
|
-
|
|
3538
|
+
z35.array(CreateWalletSchema).refine(
|
|
2945
3539
|
(list2) => new Set(list2.map((w) => w.network ?? DEFAULT_WALLET_NETWORK)).size === list2.length,
|
|
2946
3540
|
{ message: "one wallet per network" }
|
|
2947
3541
|
)
|
|
2948
3542
|
);
|
|
2949
3543
|
var CardDeclSchema = IssueCardSchema;
|
|
2950
3544
|
var IdentityDeclSchema = IdentitySchema.pick({ name: true, description: true }).partial({ description: true }).extend({
|
|
2951
|
-
|
|
2952
|
-
legal: z30.array(LegalDeclSchema).optional(),
|
|
3545
|
+
legal: z35.array(LegalDeclSchema).optional(),
|
|
2953
3546
|
wallet: WalletDeclSchema.optional(),
|
|
2954
|
-
cards:
|
|
2955
|
-
});
|
|
2956
|
-
var RemovedSchema =
|
|
2957
|
-
apps:
|
|
2958
|
-
agents:
|
|
2959
|
-
skills:
|
|
2960
|
-
identities:
|
|
2961
|
-
vaults:
|
|
2962
|
-
});
|
|
2963
|
-
var KeptSchema =
|
|
2964
|
-
var TaskDeclSchema =
|
|
2965
|
-
key:
|
|
2966
|
-
title:
|
|
2967
|
-
body:
|
|
2968
|
-
assignee:
|
|
2969
|
-
blocked_by:
|
|
2970
|
-
});
|
|
2971
|
-
var ProjectSchema =
|
|
2972
|
-
name:
|
|
3547
|
+
cards: z35.array(CardDeclSchema).optional()
|
|
3548
|
+
});
|
|
3549
|
+
var RemovedSchema = z35.object({
|
|
3550
|
+
apps: z35.array(z35.string().min(1)).default([]),
|
|
3551
|
+
agents: z35.array(z35.string().min(1)).default([]),
|
|
3552
|
+
skills: z35.array(z35.string().min(1)).default([]),
|
|
3553
|
+
identities: z35.array(z35.string().min(1)).default([]),
|
|
3554
|
+
vaults: z35.array(z35.string().min(1)).default([])
|
|
3555
|
+
});
|
|
3556
|
+
var KeptSchema = z35.object({ agents: z35.array(z35.string().min(1)).default([]) });
|
|
3557
|
+
var TaskDeclSchema = z35.object({
|
|
3558
|
+
key: z35.string().min(1),
|
|
3559
|
+
title: z35.string().min(1).max(200),
|
|
3560
|
+
body: z35.string().max(8192).optional(),
|
|
3561
|
+
assignee: z35.string().min(1).optional(),
|
|
3562
|
+
blocked_by: z35.array(z35.string().min(1)).optional()
|
|
3563
|
+
});
|
|
3564
|
+
var ProjectSchema = z35.object({
|
|
3565
|
+
name: z35.string().min(1),
|
|
2973
3566
|
/** The machine this project runs: its repo, its screens, its `/api/*` (`template.ts`). */
|
|
2974
|
-
blueprint:
|
|
3567
|
+
blueprint: z35.string().min(1).optional(),
|
|
2975
3568
|
/** Which of that blueprint's templates provides the crew; a blueprint with a default may omit it. */
|
|
2976
|
-
template:
|
|
3569
|
+
template: z35.string().min(1).optional(),
|
|
3570
|
+
/**
|
|
3571
|
+
* What a person calls this template, one line on what its crew does, and the networks it
|
|
3572
|
+
* publishes to (`canonical-spec §31.5`). Printed on the artifact and never provisioned: where the
|
|
3573
|
+
* crew posts is the accounts connected to its persona, not this list.
|
|
3574
|
+
*/
|
|
3575
|
+
title: z35.string().min(1).max(80).optional(),
|
|
3576
|
+
description: z35.string().min(1).max(280).optional(),
|
|
3577
|
+
platforms: z35.array(SocialPlatformSchema).optional(),
|
|
3578
|
+
/**
|
|
3579
|
+
* The company's mini apps (`canonical-spec §50`): each a name, an icon and pages of the platform's
|
|
3580
|
+
* blocks — data only, checked with the platform's catalog here and again when a page is read. The
|
|
3581
|
+
* studio draws every one with one general UI, under Apps.
|
|
3582
|
+
*/
|
|
3583
|
+
mini_apps: MiniAppDeclsSchema.optional(),
|
|
2977
3584
|
/**
|
|
2978
3585
|
* What a person is asked BEFORE the crew is provisioned (`canonical-spec §31.2`).
|
|
2979
3586
|
*
|
|
@@ -2985,21 +3592,21 @@ var ProjectSchema = z30.object({
|
|
|
2985
3592
|
*
|
|
2986
3593
|
* **Configuration only.** A secret is a vault credential or an app secret; neither is an answer.
|
|
2987
3594
|
*/
|
|
2988
|
-
questions:
|
|
2989
|
-
skills:
|
|
2990
|
-
identities:
|
|
2991
|
-
vaults:
|
|
2992
|
-
apps:
|
|
2993
|
-
agents:
|
|
3595
|
+
questions: z35.array(QuestionFieldSchema).default([]),
|
|
3596
|
+
skills: z35.array(SkillDeclSchema).default([]),
|
|
3597
|
+
identities: z35.array(IdentityDeclSchema).default([]),
|
|
3598
|
+
vaults: z35.array(VaultDeclSchema).default([]),
|
|
3599
|
+
apps: z35.array(AppDeclSchema).default([]),
|
|
3600
|
+
agents: z35.array(AgentDeclSchema).default([]),
|
|
2994
3601
|
/**
|
|
2995
3602
|
* The agents this template creates PER CLIENT the operator signs (`canonical-spec §31.1`) —
|
|
2996
3603
|
* printed on the artifact so a person sees the whole company, never provisioned by an apply,
|
|
2997
3604
|
* because the apply does not know the clients yet. Names only: a model and a budget are the
|
|
2998
3605
|
* crew's business at the moment a client is signed, not the declaration's.
|
|
2999
3606
|
*/
|
|
3000
|
-
crew_per_client:
|
|
3607
|
+
crew_per_client: z35.array(z35.object({ name: z35.string().min(1), role: z35.string().min(1).optional(), description: z35.string().optional() })).optional(),
|
|
3001
3608
|
/** The crew's first work, as cards on the organization's board rather than N private intakes (§31.11). */
|
|
3002
|
-
tasks:
|
|
3609
|
+
tasks: z35.array(TaskDeclSchema).default([]),
|
|
3003
3610
|
removed: RemovedSchema.default({ apps: [], agents: [], skills: [], identities: [], vaults: [] }),
|
|
3004
3611
|
kept: KeptSchema.default({ agents: [] })
|
|
3005
3612
|
});
|
|
@@ -3054,8 +3661,8 @@ function parseProject(input) {
|
|
|
3054
3661
|
}
|
|
3055
3662
|
const config = parsed.data;
|
|
3056
3663
|
applyChoice(config);
|
|
3057
|
-
if (config.template !== void 0 && config.questions.length >
|
|
3058
|
-
refuse(`template "${config.template}" asks ${config.questions.length} questions, but a template asks at most
|
|
3664
|
+
if (config.template !== void 0 && config.questions.length > TEMPLATE_QUESTIONS_MAX) {
|
|
3665
|
+
refuse(`template "${config.template}" asks ${config.questions.length} questions, but a template asks at most ${TEMPLATE_QUESTIONS_MAX} before anything is provisioned \u2014 a fifth belongs to the crew's first conversation`);
|
|
3059
3666
|
}
|
|
3060
3667
|
assertUniqueNames("app", [...config.apps.map((a) => a.name), ...config.removed.apps]);
|
|
3061
3668
|
assertUniqueNames("agent", [...config.agents.map((a) => a.name), ...config.removed.agents, ...config.kept.agents]);
|
|
@@ -3076,20 +3683,6 @@ function parseProject(input) {
|
|
|
3076
3683
|
assertUniqueNames("bucket", (app.buckets ?? []).map((bucket) => bucket.name));
|
|
3077
3684
|
}
|
|
3078
3685
|
const identityNames = new Set(config.identities.map((i) => i.name));
|
|
3079
|
-
const connectable = config.identities.filter((i) => i.connections !== void 0).map((i) => i.name);
|
|
3080
|
-
if (connectable.length > 1) {
|
|
3081
|
-
refuse(`identities ${connectable.map((n) => `"${n}"`).join(", ")} each declare connections, but the studio's Add connections step connects one persona \u2014 declare connections on the one the crew publishes through`);
|
|
3082
|
-
}
|
|
3083
|
-
for (const identity of config.identities) {
|
|
3084
|
-
const social = identity.connections?.social;
|
|
3085
|
-
if (social === void 0) continue;
|
|
3086
|
-
const question = config.questions.find((q) => q.key === social.from);
|
|
3087
|
-
if (question === void 0) refuse(`identity "${identity.name}": connections.social.from names "${social.from}", but no question with that key is declared in this project`);
|
|
3088
|
-
if (question.type !== "choice") refuse(`identity "${identity.name}": connections.social.from names "${social.from}", which is a ${question.type} question \u2014 the map is keyed by a choice question's options`);
|
|
3089
|
-
for (const label of Object.keys(social.map)) {
|
|
3090
|
-
if (!question.options.includes(label)) refuse(`identity "${identity.name}": connections.social.map names "${label}", which is not one of question "${social.from}"'s options \u2014 a key no answer can equal is a row nobody can reach`);
|
|
3091
|
-
}
|
|
3092
|
-
}
|
|
3093
3686
|
for (const vault of config.vaults) {
|
|
3094
3687
|
if (vault.identity !== void 0 && !identityNames.has(vault.identity)) {
|
|
3095
3688
|
refuse(`vault "${vault.name}": identity names "${vault.identity}", but no identity with that name is declared in this project`);
|
|
@@ -3300,167 +3893,6 @@ import { createHash as createHash3 } from "node:crypto";
|
|
|
3300
3893
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
3301
3894
|
import { resolve as resolve4 } from "node:path";
|
|
3302
3895
|
|
|
3303
|
-
// src/agents.ts
|
|
3304
|
-
var PROJECT_CONTEXT_PREAMBLE = "Before anything else, read the project context with the `project_context` tool. The answers in it are the client's own \u2014 never invent, assume or restate them from memory; what the context does not say, you ask. Use the context's own words for the company, its offer and its audience.";
|
|
3305
|
-
function desiredMetadata(decl, of, current) {
|
|
3306
|
-
if (of.template === void 0) return decl.metadata;
|
|
3307
|
-
return {
|
|
3308
|
-
...current?.metadata,
|
|
3309
|
-
...decl.metadata,
|
|
3310
|
-
project: of.project,
|
|
3311
|
-
...of.blueprint !== void 0 ? { blueprint: of.blueprint } : {},
|
|
3312
|
-
template: of.template,
|
|
3313
|
-
group: of.template
|
|
3314
|
-
};
|
|
3315
|
-
}
|
|
3316
|
-
function desiredSystem(decl, of) {
|
|
3317
|
-
if (of.template === void 0) return decl.system;
|
|
3318
|
-
return decl.system === void 0 ? PROJECT_CONTEXT_PREAMBLE : `${PROJECT_CONTEXT_PREAMBLE}
|
|
3319
|
-
|
|
3320
|
-
${decl.system}`;
|
|
3321
|
-
}
|
|
3322
|
-
function desiredTools(decl, current, ids) {
|
|
3323
|
-
const handoff = decl.handoffs !== void 0 && handoffsEnabled(decl.handoffs);
|
|
3324
|
-
if (ids === void 0 && !handoff) return decl.tools;
|
|
3325
|
-
const base = decl.tools ?? current?.tools ?? { default_config: { permission: "allow" }, configs: {} };
|
|
3326
|
-
const appsTool = base.configs["apps"] ?? { enabled: true, permission: base.default_config.permission };
|
|
3327
|
-
const allowed = { enabled: true, permission: "allow" };
|
|
3328
|
-
return {
|
|
3329
|
-
default_config: base.default_config,
|
|
3330
|
-
configs: {
|
|
3331
|
-
...base.configs,
|
|
3332
|
-
...ids !== void 0 ? { apps: { ...appsTool, config: { ...appsTool.config, allowed_apps: ids } } } : {},
|
|
3333
|
-
...handoff ? { send_to_agent: allowed, list_agents: allowed } : {}
|
|
3334
|
-
}
|
|
3335
|
-
};
|
|
3336
|
-
}
|
|
3337
|
-
async function createAgent(client, decl, tools, team, identityId, system, metadata) {
|
|
3338
|
-
const created = await client.agents.create({
|
|
3339
|
-
name: decl.name,
|
|
3340
|
-
model: decl.model,
|
|
3341
|
-
budget: decl.budget,
|
|
3342
|
-
...decl.description !== void 0 ? { description: decl.description } : {},
|
|
3343
|
-
...system !== void 0 ? { system } : {},
|
|
3344
|
-
...decl.skills !== void 0 ? { skills: decl.skills } : {},
|
|
3345
|
-
...decl.mcp_servers !== void 0 ? { mcp_servers: decl.mcp_servers } : {},
|
|
3346
|
-
...tools !== void 0 ? { tools } : {},
|
|
3347
|
-
...decl.window !== void 0 ? { window: decl.window } : {},
|
|
3348
|
-
...team !== void 0 ? { multiagent: team } : {},
|
|
3349
|
-
...decl.handoffs !== void 0 ? { handoffs: decl.handoffs } : {},
|
|
3350
|
-
...decl.output_schema !== void 0 ? { output_schema: decl.output_schema } : {},
|
|
3351
|
-
...decl.structured_output_required !== void 0 ? { structured_output_required: decl.structured_output_required } : {},
|
|
3352
|
-
...metadata !== void 0 ? { metadata } : {}
|
|
3353
|
-
});
|
|
3354
|
-
if (identityId !== void 0) await client.identities.attach(created.id, identityId);
|
|
3355
|
-
return { name: decl.name, action: "created", id: created.id };
|
|
3356
|
-
}
|
|
3357
|
-
async function upsertAgent(client, decl, existing, ids, dryRun, scoped, of) {
|
|
3358
|
-
const unresolved = (decl.allowed_apps ?? []).filter((name) => !ids.apps.has(name));
|
|
3359
|
-
const identityId = decl.identity === void 0 ? void 0 : ids.identities.get(decl.identity);
|
|
3360
|
-
const missing = unresolved.length > 0 ? `allowed_apps needs app "${unresolved[0]}"` : decl.identity !== void 0 && identityId === void 0 ? `identity needs "${decl.identity}"` : null;
|
|
3361
|
-
if (missing !== null && !dryRun) {
|
|
3362
|
-
return { name: decl.name, action: "refused", reason: `${missing}, which was not provisioned in this run` };
|
|
3363
|
-
}
|
|
3364
|
-
const appIds = decl.allowed_apps !== void 0 ? decl.allowed_apps.flatMap((name) => ids.apps.get(name) ?? []) : scoped;
|
|
3365
|
-
const current = existing.find((agent) => agent.name === decl.name) ?? null;
|
|
3366
|
-
const tools = desiredTools(decl, current, appIds);
|
|
3367
|
-
const team = teamWithoutRoster(decl.multiagent);
|
|
3368
|
-
const system = desiredSystem(decl, of);
|
|
3369
|
-
const metadata = desiredMetadata(decl, of, current);
|
|
3370
|
-
if (!current) {
|
|
3371
|
-
return dryRun ? { name: decl.name, action: "created" } : createAgent(client, decl, tools, team, identityId, system, metadata);
|
|
3372
|
-
}
|
|
3373
|
-
const patch = drift(decl, current, tools, team, system, metadata);
|
|
3374
|
-
const held = identityId === void 0 ? [] : (await client.identities.held(current.id)).data;
|
|
3375
|
-
const grant = identityId === void 0 || held.some((one) => one.id === identityId) ? null : identityId;
|
|
3376
|
-
const drifted = Object.keys(patch).length > 0 || missing !== null || grant !== null;
|
|
3377
|
-
if (!drifted) return { name: decl.name, action: "unchanged", id: current.id };
|
|
3378
|
-
if (!dryRun) {
|
|
3379
|
-
if (Object.keys(patch).length > 0) await client.agents.update(current.id, patch);
|
|
3380
|
-
if (grant !== null) await client.identities.attach(current.id, grant);
|
|
3381
|
-
}
|
|
3382
|
-
return { name: decl.name, action: "updated", id: current.id };
|
|
3383
|
-
}
|
|
3384
|
-
function drift(decl, current, tools, team, system, metadata) {
|
|
3385
|
-
const patch = {};
|
|
3386
|
-
if (changed(decl.model, current.model)) patch.model = decl.model;
|
|
3387
|
-
if (changed(decl.budget, current.budget)) patch.budget = decl.budget;
|
|
3388
|
-
if (changed(decl.description, current.description)) patch.description = decl.description;
|
|
3389
|
-
if (changed(system, current.system)) patch.system = system;
|
|
3390
|
-
if (changed(decl.skills, current.skills)) patch.skills = decl.skills;
|
|
3391
|
-
if (changed(decl.mcp_servers, current.mcp_servers)) patch.mcp_servers = decl.mcp_servers;
|
|
3392
|
-
if (changed(tools, current.tools)) patch.tools = tools;
|
|
3393
|
-
if (changed(decl.window, current.window)) patch.window = decl.window;
|
|
3394
|
-
if (team !== void 0 && changed(normaliseMultiagent(team), normaliseMultiagent(current.multiagent))) patch.multiagent = team;
|
|
3395
|
-
if (changed(decl.handoffs, handoffsOf(current))) patch.handoffs = decl.handoffs;
|
|
3396
|
-
if (changed(decl.output_schema, current.output_schema)) patch.output_schema = decl.output_schema;
|
|
3397
|
-
if (changed(decl.structured_output_required, current.structured_output_required)) patch.structured_output_required = decl.structured_output_required;
|
|
3398
|
-
if (changed(metadata, current.metadata)) patch.metadata = metadata;
|
|
3399
|
-
return patch;
|
|
3400
|
-
}
|
|
3401
|
-
async function openIntake(client, agent, decl, dryRun) {
|
|
3402
|
-
if (dryRun || agent.id === void 0) return { name: agent.name, action: "created" };
|
|
3403
|
-
const started = await client.sessions.create({
|
|
3404
|
-
agent_id: agent.id,
|
|
3405
|
-
message: decl.message,
|
|
3406
|
-
...decl.budget_micro_usd !== void 0 ? { budget_micro_usd: decl.budget_micro_usd } : {}
|
|
3407
|
-
});
|
|
3408
|
-
return { name: agent.name, action: "created", id: started.id };
|
|
3409
|
-
}
|
|
3410
|
-
function brief(input) {
|
|
3411
|
-
const first = input.trim().split(/(?<=[.!?])\s|\n/)[0]?.trim() ?? "";
|
|
3412
|
-
const text = first.replace(/[.\s]+$/, "");
|
|
3413
|
-
return text.length > 72 ? `${text.slice(0, 71).trimEnd()}\u2026` : text;
|
|
3414
|
-
}
|
|
3415
|
-
async function upsertSchedule(client, agent, decl, current, identityIds, dryRun) {
|
|
3416
|
-
const name = `${agent.name} @ ${decl.cron}`;
|
|
3417
|
-
if (agent.action === "refused") throw new Error(`agent "${agent.name}" was not provisioned in this run`);
|
|
3418
|
-
const identity = decl.identity === void 0 ? void 0 : identityIds.get(decl.identity);
|
|
3419
|
-
const unresolved = decl.identity !== void 0 && identity === void 0;
|
|
3420
|
-
if (unresolved && !dryRun) throw new Error(`identity needs "${decl.identity}", which was not provisioned in this run`);
|
|
3421
|
-
if (!current) {
|
|
3422
|
-
if (dryRun || agent.id === void 0) return { name, action: "created" };
|
|
3423
|
-
const created = await client.deployments.create({
|
|
3424
|
-
agent_id: agent.id,
|
|
3425
|
-
cron: decl.cron,
|
|
3426
|
-
input_template: decl.input,
|
|
3427
|
-
budget_micro_usd: decl.budget_micro_usd,
|
|
3428
|
-
...decl.timezone !== void 0 ? { timezone: decl.timezone } : {},
|
|
3429
|
-
...identity !== void 0 ? { identity } : {},
|
|
3430
|
-
...decl.enabled !== void 0 ? { enabled: decl.enabled } : {}
|
|
3431
|
-
});
|
|
3432
|
-
return { name, action: "created", id: created.id };
|
|
3433
|
-
}
|
|
3434
|
-
const patch = {};
|
|
3435
|
-
if (changed(decl.timezone, current.timezone)) patch.timezone = decl.timezone;
|
|
3436
|
-
if (changed(decl.input, current.input_template)) patch.input_template = decl.input;
|
|
3437
|
-
if (changed(decl.budget_micro_usd, current.budget_micro_usd)) patch.budget_micro_usd = decl.budget_micro_usd;
|
|
3438
|
-
if (changed(identity, current.identity)) patch.identity = identity;
|
|
3439
|
-
if (changed(decl.enabled, current.enabled)) patch.enabled = decl.enabled;
|
|
3440
|
-
if (Object.keys(patch).length === 0 && !unresolved) return { name, action: "unchanged", id: current.id };
|
|
3441
|
-
if (!dryRun) await client.deployments.update(current.id, patch);
|
|
3442
|
-
return { name, action: "updated", id: current.id };
|
|
3443
|
-
}
|
|
3444
|
-
async function reconcileSchedules(client, agent, declared, live, identityIds, dryRun, into) {
|
|
3445
|
-
const rows = live.filter((row) => row.agent_id === agent.id);
|
|
3446
|
-
into.push(
|
|
3447
|
-
...await eachInFlight(declared, async (decl) => ({
|
|
3448
|
-
...await line(
|
|
3449
|
-
`${agent.name} @ ${decl.cron}`,
|
|
3450
|
-
() => upsertSchedule(client, agent, decl, rows.find((row) => row.cron === decl.cron), identityIds, dryRun)
|
|
3451
|
-
),
|
|
3452
|
-
// `<agent> @ <cron>` says WHEN a timer runs and nothing about what it does, so the dashboard's
|
|
3453
|
-
// opening message could only ever draw a timetable from these lines. The brief's first
|
|
3454
|
-
// sentence is what turns that timetable into a roadmap (§29.6).
|
|
3455
|
-
summary: brief(decl.input)
|
|
3456
|
-
}))
|
|
3457
|
-
);
|
|
3458
|
-
for (const row of rows.filter((row2) => !declared.some((decl) => decl.cron === row2.cron))) {
|
|
3459
|
-
const name = `${agent.name} @ ${row.cron}`;
|
|
3460
|
-
await attempt(into, name, () => tombstone(name, row, (id) => client.deployments.delete(id), dryRun));
|
|
3461
|
-
}
|
|
3462
|
-
}
|
|
3463
|
-
|
|
3464
3896
|
// src/apps.ts
|
|
3465
3897
|
import { createHash as createHash2, randomBytes } from "node:crypto";
|
|
3466
3898
|
import { resolve as resolve3 } from "node:path";
|
|
@@ -3520,10 +3952,10 @@ async function findApp(client, name, skipped) {
|
|
|
3520
3952
|
const rows = await listAll(client.config, "/v1/apps", AppSchema, skipped, { name });
|
|
3521
3953
|
return rows.find((app) => app.name === name) ?? null;
|
|
3522
3954
|
}
|
|
3523
|
-
function ownershipRefusal(name, project, owner) {
|
|
3955
|
+
function ownershipRefusal(name, project, owner, kind = "app") {
|
|
3524
3956
|
const held = owner === null ? "no project (it was created outside a blueprint)" : `project "${owner}"`;
|
|
3525
3957
|
const verb = owner === null ? "take" : "transfer";
|
|
3526
|
-
return
|
|
3958
|
+
return `${kind} "${name}" is owned by ${held}; this project is "${project}". Rename the ${kind} in your config, or re-run \`naive up --adopt\` to ${verb} it.`;
|
|
3527
3959
|
}
|
|
3528
3960
|
var ensureApp = (client, body) => client.apps.create(body);
|
|
3529
3961
|
var PLATFORM_ENV = {
|
|
@@ -3627,13 +4059,13 @@ function builtTree(decl, opts) {
|
|
|
3627
4059
|
const files = collectFiles(hosted?.[decl.name] ?? resolve3(opts.dir, decl.deploy_dir));
|
|
3628
4060
|
return { files, hash: contentHash(files) };
|
|
3629
4061
|
}
|
|
3630
|
-
async function writeApp(client, id, env,
|
|
4062
|
+
async function writeApp(client, id, env, tree2) {
|
|
3631
4063
|
await eachInFlight(
|
|
3632
4064
|
Object.entries(env),
|
|
3633
4065
|
([name, value]) => client.apps.setSecret(id, { name, value, value_hash: secretHash(name, value) })
|
|
3634
4066
|
);
|
|
3635
|
-
if (!
|
|
3636
|
-
await client.apps.deploy(id,
|
|
4067
|
+
if (!tree2) return;
|
|
4068
|
+
await client.apps.deploy(id, tree2.files, tree2.hash);
|
|
3637
4069
|
await settleDeploy(client, id);
|
|
3638
4070
|
}
|
|
3639
4071
|
var SETTLE_TRIES = 30;
|
|
@@ -3645,7 +4077,7 @@ async function settleDeploy(client, id) {
|
|
|
3645
4077
|
await new Promise((resolve5) => setTimeout(resolve5, SETTLE_MS));
|
|
3646
4078
|
}
|
|
3647
4079
|
}
|
|
3648
|
-
async function createApp(client, decl, env,
|
|
4080
|
+
async function createApp(client, decl, env, tree2, migrations, opts, appIds) {
|
|
3649
4081
|
const created = await ensureApp(client, {
|
|
3650
4082
|
name: decl.name,
|
|
3651
4083
|
type: decl.type,
|
|
@@ -3654,7 +4086,7 @@ async function createApp(client, decl, env, tree, migrations, opts, appIds) {
|
|
|
3654
4086
|
...decl.mcp !== void 0 ? { mcp: decl.mcp } : {}
|
|
3655
4087
|
});
|
|
3656
4088
|
appIds.set(decl.name, created.id);
|
|
3657
|
-
await writeApp(client, created.id, withAppId(env, decl, opts, created.id),
|
|
4089
|
+
await writeApp(client, created.id, withAppId(env, decl, opts, created.id), tree2);
|
|
3658
4090
|
const notes = [];
|
|
3659
4091
|
if (migrations.length > 0) notes.push((await applyMigrations(client, created.id, migrations)).note);
|
|
3660
4092
|
if (decl.buckets !== void 0) notes.push((await applyBuckets(client, created.id, decl.buckets)).note);
|
|
@@ -3725,9 +4157,9 @@ async function upsertApp(client, decl, opts, appIds) {
|
|
|
3725
4157
|
...(decl.mcp ?? null) !== current.mcp ? { mcp: decl.mcp ?? null } : {}
|
|
3726
4158
|
};
|
|
3727
4159
|
const drifted = Object.keys(patch).length > 0;
|
|
3728
|
-
const
|
|
3729
|
-
const newest =
|
|
3730
|
-
const stale =
|
|
4160
|
+
const tree2 = builtTree(decl, opts);
|
|
4161
|
+
const newest = tree2 ? (await client.apps.deployments(current.id, { limit: 1 })).data[0] : void 0;
|
|
4162
|
+
const stale = tree2 !== null && newest?.content_hash !== tree2.hash;
|
|
3731
4163
|
let action = !owned || drifted || stale || staleNames.length > 0 ? "updated" : "unchanged";
|
|
3732
4164
|
const plan = opts.dryRun ? [
|
|
3733
4165
|
...staleNames.length > 0 ? [`will set ${staleNames.join(", ")}`] : [],
|
|
@@ -3738,7 +4170,7 @@ async function upsertApp(client, decl, opts, appIds) {
|
|
|
3738
4170
|
] : [];
|
|
3739
4171
|
if (!opts.dryRun) {
|
|
3740
4172
|
if (drifted) await client.apps.update(current.id, { ...patch, project: opts.project });
|
|
3741
|
-
await writeApp(client, current.id, staleEnv, stale ?
|
|
4173
|
+
await writeApp(client, current.id, staleEnv, stale ? tree2 : null);
|
|
3742
4174
|
const migrations = declaredMigrations(decl, opts);
|
|
3743
4175
|
if (migrations.length > 0) {
|
|
3744
4176
|
const { fresh, note: note2 } = await applyMigrations(client, current.id, migrations);
|
|
@@ -3761,6 +4193,171 @@ async function upsertApp(client, decl, opts, appIds) {
|
|
|
3761
4193
|
};
|
|
3762
4194
|
}
|
|
3763
4195
|
|
|
4196
|
+
// src/agents.ts
|
|
4197
|
+
var PROJECT_CONTEXT_PREAMBLE = "Before anything else, read the project context with the `project_context` tool. The answers in it are the client's own \u2014 never invent, assume or restate them from memory; what the context does not say, you ask. Use the context's own words for the company, its offer and its audience.";
|
|
4198
|
+
function desiredMetadata(decl, of, current) {
|
|
4199
|
+
if (of.template === void 0) return decl.metadata;
|
|
4200
|
+
return {
|
|
4201
|
+
...current?.metadata,
|
|
4202
|
+
...decl.metadata,
|
|
4203
|
+
project: of.project,
|
|
4204
|
+
...of.blueprint !== void 0 ? { blueprint: of.blueprint } : {},
|
|
4205
|
+
template: of.template,
|
|
4206
|
+
group: of.template
|
|
4207
|
+
};
|
|
4208
|
+
}
|
|
4209
|
+
function desiredSystem(decl, of) {
|
|
4210
|
+
if (of.template === void 0) return decl.system;
|
|
4211
|
+
return decl.system === void 0 ? PROJECT_CONTEXT_PREAMBLE : `${PROJECT_CONTEXT_PREAMBLE}
|
|
4212
|
+
|
|
4213
|
+
${decl.system}`;
|
|
4214
|
+
}
|
|
4215
|
+
function desiredTools(decl, current, ids) {
|
|
4216
|
+
const handoff = decl.handoffs !== void 0 && handoffsEnabled(decl.handoffs);
|
|
4217
|
+
if (ids === void 0 && !handoff) return decl.tools;
|
|
4218
|
+
const base = decl.tools ?? current?.tools ?? { default_config: { permission: "allow" }, configs: {} };
|
|
4219
|
+
const appsTool = base.configs["apps"] ?? { enabled: true, permission: base.default_config.permission };
|
|
4220
|
+
const allowed = { enabled: true, permission: "allow" };
|
|
4221
|
+
return {
|
|
4222
|
+
default_config: base.default_config,
|
|
4223
|
+
configs: {
|
|
4224
|
+
...base.configs,
|
|
4225
|
+
...ids !== void 0 ? { apps: { ...appsTool, config: { ...appsTool.config, allowed_apps: ids } } } : {},
|
|
4226
|
+
...handoff ? { send_to_agent: allowed, list_agents: allowed } : {}
|
|
4227
|
+
}
|
|
4228
|
+
};
|
|
4229
|
+
}
|
|
4230
|
+
async function createAgent(client, decl, tools, team, identityId, system, metadata) {
|
|
4231
|
+
const created = await client.agents.create({
|
|
4232
|
+
name: decl.name,
|
|
4233
|
+
model: decl.model,
|
|
4234
|
+
budget: decl.budget,
|
|
4235
|
+
...decl.description !== void 0 ? { description: decl.description } : {},
|
|
4236
|
+
...system !== void 0 ? { system } : {},
|
|
4237
|
+
...decl.skills !== void 0 ? { skills: decl.skills } : {},
|
|
4238
|
+
...decl.mcp_servers !== void 0 ? { mcp_servers: decl.mcp_servers } : {},
|
|
4239
|
+
...tools !== void 0 ? { tools } : {},
|
|
4240
|
+
...decl.window !== void 0 ? { window: decl.window } : {},
|
|
4241
|
+
...team !== void 0 ? { multiagent: team } : {},
|
|
4242
|
+
...decl.handoffs !== void 0 ? { handoffs: decl.handoffs } : {},
|
|
4243
|
+
...decl.output_schema !== void 0 ? { output_schema: decl.output_schema } : {},
|
|
4244
|
+
...decl.structured_output_required !== void 0 ? { structured_output_required: decl.structured_output_required } : {},
|
|
4245
|
+
...metadata !== void 0 ? { metadata } : {}
|
|
4246
|
+
});
|
|
4247
|
+
if (identityId !== void 0) await client.identities.attach(created.id, identityId);
|
|
4248
|
+
return { name: decl.name, action: "created", id: created.id };
|
|
4249
|
+
}
|
|
4250
|
+
async function upsertAgent(client, decl, existing, ids, dryRun, scoped, of) {
|
|
4251
|
+
const unresolved = (decl.allowed_apps ?? []).filter((name) => !ids.apps.has(name));
|
|
4252
|
+
const identityId = decl.identity === void 0 ? void 0 : ids.identities.get(decl.identity);
|
|
4253
|
+
const missing = unresolved.length > 0 ? `allowed_apps needs app "${unresolved[0]}"` : decl.identity !== void 0 && identityId === void 0 ? `identity needs "${decl.identity}"` : null;
|
|
4254
|
+
if (missing !== null && !dryRun) {
|
|
4255
|
+
return { name: decl.name, action: "refused", reason: `${missing}, which was not provisioned in this run` };
|
|
4256
|
+
}
|
|
4257
|
+
const appIds = decl.allowed_apps !== void 0 ? decl.allowed_apps.flatMap((name) => ids.apps.get(name) ?? []) : scoped;
|
|
4258
|
+
const current = existing.find((agent) => agent.name === decl.name) ?? null;
|
|
4259
|
+
const owner = typeof current?.metadata?.["project"] === "string" ? current.metadata["project"] : null;
|
|
4260
|
+
if (current && of.template !== void 0 && owner !== null && owner !== of.project && !of.adopt) {
|
|
4261
|
+
return { name: decl.name, action: "refused", id: current.id, reason: ownershipRefusal(decl.name, of.project, owner, "agent") };
|
|
4262
|
+
}
|
|
4263
|
+
const tools = desiredTools(decl, current, appIds);
|
|
4264
|
+
const team = teamWithoutRoster(decl.multiagent);
|
|
4265
|
+
const system = desiredSystem(decl, of);
|
|
4266
|
+
const metadata = desiredMetadata(decl, of, current);
|
|
4267
|
+
if (!current) {
|
|
4268
|
+
return dryRun ? { name: decl.name, action: "created" } : createAgent(client, decl, tools, team, identityId, system, metadata);
|
|
4269
|
+
}
|
|
4270
|
+
const patch = drift(decl, current, tools, team, system, metadata);
|
|
4271
|
+
const held = identityId === void 0 ? [] : (await client.identities.held(current.id)).data;
|
|
4272
|
+
const grant = identityId === void 0 || held.some((one) => one.id === identityId) ? null : identityId;
|
|
4273
|
+
const drifted = Object.keys(patch).length > 0 || missing !== null || grant !== null;
|
|
4274
|
+
if (!drifted) return { name: decl.name, action: "unchanged", id: current.id };
|
|
4275
|
+
if (!dryRun) {
|
|
4276
|
+
if (Object.keys(patch).length > 0) await client.agents.update(current.id, patch);
|
|
4277
|
+
if (grant !== null) await client.identities.attach(current.id, grant);
|
|
4278
|
+
}
|
|
4279
|
+
return { name: decl.name, action: "updated", id: current.id };
|
|
4280
|
+
}
|
|
4281
|
+
function drift(decl, current, tools, team, system, metadata) {
|
|
4282
|
+
const patch = {};
|
|
4283
|
+
if (changed(decl.model, current.model)) patch.model = decl.model;
|
|
4284
|
+
if (changed(decl.budget, current.budget)) patch.budget = decl.budget;
|
|
4285
|
+
if (changed(decl.description, current.description)) patch.description = decl.description;
|
|
4286
|
+
if (changed(system, current.system)) patch.system = system;
|
|
4287
|
+
if (changed(decl.skills, current.skills)) patch.skills = decl.skills;
|
|
4288
|
+
if (changed(decl.mcp_servers, current.mcp_servers)) patch.mcp_servers = decl.mcp_servers;
|
|
4289
|
+
if (changed(tools, current.tools)) patch.tools = tools;
|
|
4290
|
+
if (changed(decl.window, current.window)) patch.window = decl.window;
|
|
4291
|
+
if (team !== void 0 && changed(normaliseMultiagent(team), normaliseMultiagent(current.multiagent))) patch.multiagent = team;
|
|
4292
|
+
if (changed(decl.handoffs, handoffsOf(current))) patch.handoffs = decl.handoffs;
|
|
4293
|
+
if (changed(decl.output_schema, current.output_schema)) patch.output_schema = decl.output_schema;
|
|
4294
|
+
if (changed(decl.structured_output_required, current.structured_output_required)) patch.structured_output_required = decl.structured_output_required;
|
|
4295
|
+
if (changed(metadata, current.metadata)) patch.metadata = metadata;
|
|
4296
|
+
return patch;
|
|
4297
|
+
}
|
|
4298
|
+
async function openIntake(client, agent, decl, dryRun) {
|
|
4299
|
+
if (dryRun || agent.id === void 0) return { name: agent.name, action: "created" };
|
|
4300
|
+
const started = await client.sessions.create({
|
|
4301
|
+
agent_id: agent.id,
|
|
4302
|
+
message: decl.message,
|
|
4303
|
+
...decl.budget_micro_usd !== void 0 ? { budget_micro_usd: decl.budget_micro_usd } : {}
|
|
4304
|
+
});
|
|
4305
|
+
return { name: agent.name, action: "created", id: started.id };
|
|
4306
|
+
}
|
|
4307
|
+
function brief(input) {
|
|
4308
|
+
const first = input.trim().split(/(?<=[.!?])\s|\n/)[0]?.trim() ?? "";
|
|
4309
|
+
const text = first.replace(/[.\s]+$/, "");
|
|
4310
|
+
return text.length > 72 ? `${text.slice(0, 71).trimEnd()}\u2026` : text;
|
|
4311
|
+
}
|
|
4312
|
+
async function upsertSchedule(client, agent, decl, current, identityIds, dryRun) {
|
|
4313
|
+
const name = `${agent.name} @ ${decl.cron}`;
|
|
4314
|
+
if (agent.action === "refused") throw new Error(`agent "${agent.name}" was not provisioned in this run`);
|
|
4315
|
+
const identity = decl.identity === void 0 ? void 0 : identityIds.get(decl.identity);
|
|
4316
|
+
const unresolved = decl.identity !== void 0 && identity === void 0;
|
|
4317
|
+
if (unresolved && !dryRun) throw new Error(`identity needs "${decl.identity}", which was not provisioned in this run`);
|
|
4318
|
+
if (!current) {
|
|
4319
|
+
if (dryRun || agent.id === void 0) return { name, action: "created" };
|
|
4320
|
+
const created = await client.deployments.create({
|
|
4321
|
+
agent_id: agent.id,
|
|
4322
|
+
cron: decl.cron,
|
|
4323
|
+
input_template: decl.input,
|
|
4324
|
+
budget_micro_usd: decl.budget_micro_usd,
|
|
4325
|
+
...decl.timezone !== void 0 ? { timezone: decl.timezone } : {},
|
|
4326
|
+
...identity !== void 0 ? { identity } : {},
|
|
4327
|
+
...decl.enabled !== void 0 ? { enabled: decl.enabled } : {}
|
|
4328
|
+
});
|
|
4329
|
+
return { name, action: "created", id: created.id };
|
|
4330
|
+
}
|
|
4331
|
+
const patch = {};
|
|
4332
|
+
if (changed(decl.timezone, current.timezone)) patch.timezone = decl.timezone;
|
|
4333
|
+
if (changed(decl.input, current.input_template)) patch.input_template = decl.input;
|
|
4334
|
+
if (changed(decl.budget_micro_usd, current.budget_micro_usd)) patch.budget_micro_usd = decl.budget_micro_usd;
|
|
4335
|
+
if (changed(identity, current.identity)) patch.identity = identity;
|
|
4336
|
+
if (changed(decl.enabled, current.enabled)) patch.enabled = decl.enabled;
|
|
4337
|
+
if (Object.keys(patch).length === 0 && !unresolved) return { name, action: "unchanged", id: current.id };
|
|
4338
|
+
if (!dryRun) await client.deployments.update(current.id, patch);
|
|
4339
|
+
return { name, action: "updated", id: current.id };
|
|
4340
|
+
}
|
|
4341
|
+
async function reconcileSchedules(client, agent, declared, live, identityIds, dryRun, into) {
|
|
4342
|
+
const rows = live.filter((row) => row.agent_id === agent.id);
|
|
4343
|
+
into.push(
|
|
4344
|
+
...await eachInFlight(declared, async (decl) => ({
|
|
4345
|
+
...await line(
|
|
4346
|
+
`${agent.name} @ ${decl.cron}`,
|
|
4347
|
+
() => upsertSchedule(client, agent, decl, rows.find((row) => row.cron === decl.cron), identityIds, dryRun)
|
|
4348
|
+
),
|
|
4349
|
+
// `<agent> @ <cron>` says WHEN a timer runs and nothing about what it does, so the dashboard's
|
|
4350
|
+
// opening message could only ever draw a timetable from these lines. The brief's first
|
|
4351
|
+
// sentence is what turns that timetable into a roadmap (§29.6).
|
|
4352
|
+
summary: brief(decl.input)
|
|
4353
|
+
}))
|
|
4354
|
+
);
|
|
4355
|
+
for (const row of rows.filter((row2) => !declared.some((decl) => decl.cron === row2.cron))) {
|
|
4356
|
+
const name = `${agent.name} @ ${row.cron}`;
|
|
4357
|
+
await attempt(into, name, () => tombstone(name, row, (id) => client.deployments.delete(id), dryRun));
|
|
4358
|
+
}
|
|
4359
|
+
}
|
|
4360
|
+
|
|
3764
4361
|
// src/reconcile-cards.ts
|
|
3765
4362
|
var LIVE = /* @__PURE__ */ new Set(["pending_payment", "issuing", "active"]);
|
|
3766
4363
|
var nameOf = (identity, decl) => `${identity} / card ${decl.label}`;
|
|
@@ -4217,7 +4814,7 @@ async function up(config, client, opts = {}) {
|
|
|
4217
4814
|
const deployments = taken.agents.some((decl) => decl.schedules !== void 0) ? await listAll(client.config, "/v1/deployments", DeploymentSchema, report2.skipped) : [];
|
|
4218
4815
|
const scoped = config.apps.length > 0 ? [...ids.apps.values()] : void 0;
|
|
4219
4816
|
const crew = await eachInFlight(taken.agents, async (decl) => {
|
|
4220
|
-
const agent = await line(decl.name, () => upsertAgent(client, decl, existing, ids, dryRun, scoped, { project: opts.project ?? config.name, ...applied(config) }));
|
|
4817
|
+
const agent = await line(decl.name, () => upsertAgent(client, decl, existing, ids, dryRun, scoped, { project: opts.project ?? config.name, ...applied(config), adopt: opts.adopt ?? false }));
|
|
4221
4818
|
const schedules = [];
|
|
4222
4819
|
if (decl.schedules !== void 0) {
|
|
4223
4820
|
await reconcileSchedules(client, agent, decl.schedules, deployments, ids.identities, dryRun, schedules);
|