@agent-team-foundation/first-tree-hub 0.6.1 → 0.6.3

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.
@@ -0,0 +1,832 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-twds-ZHy.mjs";
2
+ import { z } from "zod";
3
+ //#region ../shared/dist/index.mjs
4
+ const adapterPlatformSchema = z.enum([
5
+ "feishu",
6
+ "slack",
7
+ "kael"
8
+ ]);
9
+ const adapterStatusSchema = z.enum(["active", "inactive"]);
10
+ const createAdapterConfigSchema = z.object({
11
+ platform: adapterPlatformSchema,
12
+ agentId: z.string().min(1),
13
+ credentials: z.record(z.string(), z.unknown()),
14
+ status: adapterStatusSchema.default("active")
15
+ });
16
+ const updateAdapterConfigSchema = z.object({
17
+ agentId: z.string().min(1).optional(),
18
+ credentials: z.record(z.string(), z.unknown()).optional(),
19
+ status: adapterStatusSchema.optional()
20
+ });
21
+ z.object({
22
+ id: z.number(),
23
+ platform: z.string(),
24
+ agentId: z.string(),
25
+ hasCredentials: z.boolean(),
26
+ status: z.string(),
27
+ createdAt: z.string(),
28
+ updatedAt: z.string()
29
+ });
30
+ const adapterBindMethodSchema = z.enum([
31
+ "code",
32
+ "reverse_token",
33
+ "oauth",
34
+ "manual"
35
+ ]);
36
+ const selfServiceFeishuBotSchema = z.object({
37
+ appId: z.string().min(1),
38
+ appSecret: z.string().min(1)
39
+ });
40
+ const createAdapterMappingSchema = z.object({
41
+ platform: adapterPlatformSchema,
42
+ externalUserId: z.string().min(1),
43
+ agentId: z.string().min(1),
44
+ boundVia: adapterBindMethodSchema.default("manual"),
45
+ displayName: z.string().max(200).optional()
46
+ });
47
+ z.object({
48
+ id: z.number(),
49
+ platform: z.string(),
50
+ externalUserId: z.string(),
51
+ agentId: z.string(),
52
+ boundVia: z.string().nullable(),
53
+ displayName: z.string().nullable(),
54
+ createdAt: z.string()
55
+ });
56
+ const delegateFeishuUserSchema = z.object({
57
+ feishuUserId: z.string().min(1),
58
+ displayName: z.string().max(200).optional()
59
+ });
60
+ z.object({
61
+ configId: z.number(),
62
+ platform: z.string(),
63
+ agentId: z.string(),
64
+ appId: z.string(),
65
+ connected: z.boolean(),
66
+ lastActiveAt: z.string().nullable()
67
+ });
68
+ const presenceStatusSchema = z.enum(["online", "offline"]);
69
+ const runtimeStateSchema = z.enum([
70
+ "idle",
71
+ "working",
72
+ "blocked",
73
+ "error"
74
+ ]);
75
+ const sessionStateSchema = z.enum([
76
+ "active",
77
+ "suspended",
78
+ "evicted"
79
+ ]);
80
+ const sessionStateMessageSchema = z.object({
81
+ chatId: z.string().min(1),
82
+ state: sessionStateSchema
83
+ });
84
+ /** Client-reported runtime state override (client → server, per-agent). */
85
+ const runtimeStateMessageSchema = z.object({ runtimeState: runtimeStateSchema });
86
+ const agentBindRequestSchema = z.object({
87
+ agentId: z.string().min(1),
88
+ runtimeType: z.string().max(50),
89
+ runtimeVersion: z.string().max(50).optional()
90
+ });
91
+ const AGENT_BIND_REJECT_REASONS = {
92
+ WRONG_CLIENT: "wrong_client",
93
+ NOT_OWNED: "not_owned",
94
+ AGENT_SUSPENDED: "agent_suspended",
95
+ WRONG_ORG: "wrong_org",
96
+ UNKNOWN_AGENT: "unknown_agent"
97
+ };
98
+ z.enum([
99
+ "wrong_client",
100
+ "not_owned",
101
+ "agent_suspended",
102
+ "wrong_org",
103
+ "unknown_agent"
104
+ ]);
105
+ /** Header used on agent-scoped HTTP calls to select which managed agent the JWT acts as. */
106
+ const AGENT_SELECTOR_HEADER = "x-agent-id";
107
+ z.object({
108
+ agentId: z.string(),
109
+ status: presenceStatusSchema,
110
+ connectedAt: z.string().nullable(),
111
+ lastSeenAt: z.string(),
112
+ clientId: z.string().nullable().optional(),
113
+ runtimeType: z.string().nullable().optional(),
114
+ runtimeVersion: z.string().nullable().optional(),
115
+ runtimeState: runtimeStateSchema.nullable().optional(),
116
+ activeSessions: z.number().int().nullable().optional(),
117
+ totalSessions: z.number().int().nullable().optional(),
118
+ runtimeUpdatedAt: z.string().nullable().optional()
119
+ });
120
+ z.object({
121
+ total: z.number().int(),
122
+ running: z.number().int(),
123
+ byState: z.object({
124
+ idle: z.number().int(),
125
+ working: z.number().int(),
126
+ blocked: z.number().int(),
127
+ error: z.number().int()
128
+ }),
129
+ clients: z.number().int()
130
+ });
131
+ const AGENT_TYPES = {
132
+ HUMAN: "human",
133
+ PERSONAL_ASSISTANT: "personal_assistant",
134
+ AUTONOMOUS_AGENT: "autonomous_agent"
135
+ };
136
+ const agentTypeSchema = z.enum([
137
+ "human",
138
+ "personal_assistant",
139
+ "autonomous_agent"
140
+ ]);
141
+ const AGENT_VISIBILITY = {
142
+ PRIVATE: "private",
143
+ ORGANIZATION: "organization"
144
+ };
145
+ const agentVisibilitySchema = z.enum(["private", "organization"]);
146
+ const AGENT_STATUSES = {
147
+ ACTIVE: "active",
148
+ SUSPENDED: "suspended",
149
+ DELETED: "deleted"
150
+ };
151
+ const AGENT_SOURCES = {
152
+ ADMIN_API: "admin-api",
153
+ PORTAL: "portal"
154
+ };
155
+ const agentSourceSchema = z.enum(["admin-api", "portal"]);
156
+ z.enum(["active", "suspended"]);
157
+ const createAgentSchema = z.object({
158
+ name: z.string().min(1).max(100).regex(/^[a-z0-9_-]+$/, "Only lowercase alphanumeric, hyphens, and underscores").optional(),
159
+ type: agentTypeSchema,
160
+ displayName: z.string().max(200).optional(),
161
+ delegateMention: z.string().max(100).optional(),
162
+ organizationId: z.string().max(100).optional(),
163
+ source: agentSourceSchema.optional(),
164
+ visibility: agentVisibilitySchema.optional(),
165
+ metadata: z.record(z.string(), z.unknown()).optional(),
166
+ managerId: z.string().optional(),
167
+ clientId: z.string().min(1).max(100).optional()
168
+ });
169
+ const updateAgentSchema = z.object({
170
+ type: agentTypeSchema.optional(),
171
+ displayName: z.string().max(200).nullable().optional(),
172
+ delegateMention: z.string().max(100).nullable().optional(),
173
+ visibility: agentVisibilitySchema.optional(),
174
+ metadata: z.record(z.string(), z.unknown()).optional(),
175
+ managerId: z.string().nullable().optional(),
176
+ clientId: z.string().min(1).max(100).nullable().optional()
177
+ });
178
+ z.object({
179
+ uuid: z.string(),
180
+ name: z.string().nullable(),
181
+ organizationId: z.string(),
182
+ type: agentTypeSchema,
183
+ displayName: z.string().nullable(),
184
+ delegateMention: z.string().nullable(),
185
+ inboxId: z.string(),
186
+ status: z.string(),
187
+ source: z.string().nullable().optional(),
188
+ cloudUserId: z.string().nullable().optional(),
189
+ visibility: agentVisibilitySchema,
190
+ metadata: z.record(z.string(), z.unknown()),
191
+ managerId: z.string().nullable(),
192
+ clientId: z.string().nullable(),
193
+ presenceStatus: presenceStatusSchema.optional(),
194
+ createdAt: z.string(),
195
+ updatedAt: z.string()
196
+ });
197
+ z.object({
198
+ repo: z.string().nullable(),
199
+ branch: z.string().nullable()
200
+ });
201
+ /**
202
+ * Agent runtime configuration — M1 (Claude Code only).
203
+ *
204
+ * Defines the 5 user-tunable field groups that the Hub centrally manages
205
+ * and pushes down to the client runtime: prompt append, model, MCP servers,
206
+ * env vars, and Git repos.
207
+ *
208
+ * NOTE: do not co-locate with `packages/shared/src/config/` — that namespace
209
+ * is reserved for the local YAML config (`agent.yaml` / server / client) and
210
+ * is unrelated to the Hub-managed runtime config defined here.
211
+ */
212
+ const PROMPT_APPEND_MAX_LENGTH = 32e3;
213
+ const MCP_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]{0,63}$/i;
214
+ const ENV_KEY_PATTERN = /^[A-Z][A-Z0-9_]*$/;
215
+ const promptConfigSchema = z.object({ append: z.string().max(PROMPT_APPEND_MAX_LENGTH).default("") });
216
+ const mcpStdioServerSchema = z.object({
217
+ name: z.string().regex(MCP_NAME_PATTERN, "MCP name must match /^[a-z0-9][a-z0-9_-]{0,63}$/i"),
218
+ transport: z.literal("stdio"),
219
+ command: z.string().min(1),
220
+ args: z.array(z.string()).optional()
221
+ });
222
+ const mcpHttpServerSchema = z.object({
223
+ name: z.string().regex(MCP_NAME_PATTERN, "MCP name must match /^[a-z0-9][a-z0-9_-]{0,63}$/i"),
224
+ transport: z.literal("http"),
225
+ url: z.string().url(),
226
+ headers: z.record(z.string(), z.string()).optional()
227
+ });
228
+ const mcpSseServerSchema = z.object({
229
+ name: z.string().regex(MCP_NAME_PATTERN, "MCP name must match /^[a-z0-9][a-z0-9_-]{0,63}$/i"),
230
+ transport: z.literal("sse"),
231
+ url: z.string().url(),
232
+ headers: z.record(z.string(), z.string()).optional()
233
+ });
234
+ const mcpServerSchema = z.discriminatedUnion("transport", [
235
+ mcpStdioServerSchema,
236
+ mcpHttpServerSchema,
237
+ mcpSseServerSchema
238
+ ]);
239
+ const envEntrySchema = z.object({
240
+ key: z.string().regex(ENV_KEY_PATTERN, "Env key must match /^[A-Z][A-Z0-9_]*$/"),
241
+ value: z.string(),
242
+ sensitive: z.boolean().default(false)
243
+ });
244
+ const gitRepoSchema = z.object({
245
+ url: z.string().min(1),
246
+ ref: z.string().min(1).optional(),
247
+ localPath: z.string().min(1).optional()
248
+ });
249
+ /**
250
+ * Base shape (no refinements) — used for `.partial()` derivations such as the
251
+ * PATCH payload schema. Zod 4 forbids `.partial()` on a refined object, so we
252
+ * keep refinements on a separate full schema below.
253
+ */
254
+ const agentRuntimeConfigPayloadShape = z.object({
255
+ prompt: promptConfigSchema.default({ append: "" }),
256
+ model: z.string().default(""),
257
+ mcpServers: z.array(mcpServerSchema).default([]),
258
+ env: z.array(envEntrySchema).default([]),
259
+ gitRepos: z.array(gitRepoSchema).default([])
260
+ });
261
+ const payloadDuplicatesRefinement = (payload, ctx) => {
262
+ const seenMcp = /* @__PURE__ */ new Set();
263
+ payload.mcpServers.forEach((server, idx) => {
264
+ const lower = server.name.toLowerCase();
265
+ if (seenMcp.has(lower)) ctx.addIssue({
266
+ code: z.ZodIssueCode.custom,
267
+ path: [
268
+ "mcpServers",
269
+ idx,
270
+ "name"
271
+ ],
272
+ message: `Duplicate MCP server name "${server.name}"`
273
+ });
274
+ seenMcp.add(lower);
275
+ });
276
+ const seenEnv = /* @__PURE__ */ new Set();
277
+ payload.env.forEach((entry, idx) => {
278
+ if (seenEnv.has(entry.key)) ctx.addIssue({
279
+ code: z.ZodIssueCode.custom,
280
+ path: [
281
+ "env",
282
+ idx,
283
+ "key"
284
+ ],
285
+ message: `Duplicate env key "${entry.key}"`
286
+ });
287
+ seenEnv.add(entry.key);
288
+ });
289
+ const seenPaths = /* @__PURE__ */ new Set();
290
+ payload.gitRepos.forEach((repo, idx) => {
291
+ const path = repo.localPath ?? deriveRepoLocalPath(repo.url);
292
+ if (!path) return;
293
+ if (seenPaths.has(path)) ctx.addIssue({
294
+ code: z.ZodIssueCode.custom,
295
+ path: [
296
+ "gitRepos",
297
+ idx,
298
+ "localPath"
299
+ ],
300
+ message: `Duplicate git repo local path "${path}"`
301
+ });
302
+ seenPaths.add(path);
303
+ });
304
+ };
305
+ const agentRuntimeConfigPayloadSchema = agentRuntimeConfigPayloadShape.superRefine(payloadDuplicatesRefinement);
306
+ /** Default payload used when creating a fresh agent. */
307
+ const DEFAULT_AGENT_RUNTIME_CONFIG_PAYLOAD = {
308
+ prompt: { append: "" },
309
+ model: "",
310
+ mcpServers: [],
311
+ env: [],
312
+ gitRepos: []
313
+ };
314
+ const agentRuntimeConfigSchema = z.object({
315
+ agentId: z.string(),
316
+ version: z.number().int().positive(),
317
+ payload: agentRuntimeConfigPayloadSchema,
318
+ updatedAt: z.string(),
319
+ updatedBy: z.string()
320
+ });
321
+ /**
322
+ * Patch payload for PATCH /api/v1/admin/agents/:uuid/config.
323
+ *
324
+ * - `expectedVersion` enforces optimistic locking; mismatch → 409.
325
+ * - All payload fields are optional; omitted fields are left untouched.
326
+ */
327
+ const updateAgentRuntimeConfigSchema = z.object({
328
+ expectedVersion: z.number().int().positive(),
329
+ payload: agentRuntimeConfigPayloadShape.partial()
330
+ });
331
+ const dryRunAgentRuntimeConfigSchema = z.object({ payload: agentRuntimeConfigPayloadShape.partial() });
332
+ z.object({
333
+ current: agentRuntimeConfigSchema,
334
+ next: agentRuntimeConfigPayloadSchema,
335
+ diff: z.array(z.object({
336
+ path: z.string(),
337
+ op: z.enum([
338
+ "add",
339
+ "remove",
340
+ "replace"
341
+ ]),
342
+ before: z.unknown().optional(),
343
+ after: z.unknown().optional()
344
+ }))
345
+ });
346
+ /** Mask of a previously-stored sensitive value when echoing back to admin. */
347
+ function isRedactedEnvValue(value) {
348
+ return value === "***";
349
+ }
350
+ /**
351
+ * Derive a default local path from a repo URL.
352
+ * Used both for validation (duplicate detection) and at runtime when the user
353
+ * leaves `localPath` empty.
354
+ */
355
+ function deriveRepoLocalPath(url) {
356
+ const trimmed = url.trim();
357
+ if (!trimmed) return "";
358
+ return ((trimmed.split(/[?#]/)[0] ?? "").split(/[/:]/).filter(Boolean).pop() ?? "").replace(/\.git$/i, "");
359
+ }
360
+ const loginSchema = z.object({
361
+ username: z.string().min(1),
362
+ password: z.string().min(1)
363
+ });
364
+ z.object({
365
+ accessToken: z.string(),
366
+ refreshToken: z.string()
367
+ });
368
+ const refreshTokenSchema = z.object({ refreshToken: z.string().min(1) });
369
+ const connectTokenExchangeSchema = z.object({ token: z.string().min(1) });
370
+ z.object({
371
+ token: z.string(),
372
+ expiresIn: z.number(),
373
+ command: z.string()
374
+ });
375
+ const chatTypeSchema = z.enum([
376
+ "direct",
377
+ "group",
378
+ "thread"
379
+ ]);
380
+ const createChatSchema = z.object({
381
+ type: chatTypeSchema,
382
+ topic: z.string().max(500).optional(),
383
+ participantIds: z.array(z.string()).min(1),
384
+ metadata: z.record(z.string(), z.unknown()).optional()
385
+ });
386
+ const chatParticipantSchema = z.object({
387
+ agentId: z.string(),
388
+ role: z.string(),
389
+ mode: z.string(),
390
+ joinedAt: z.string()
391
+ });
392
+ z.object({
393
+ id: z.string(),
394
+ organizationId: z.string(),
395
+ type: z.string(),
396
+ topic: z.string().nullable(),
397
+ lifecyclePolicy: z.string().nullable().optional(),
398
+ metadata: z.record(z.string(), z.unknown()),
399
+ createdAt: z.string(),
400
+ updatedAt: z.string()
401
+ }).extend({ participants: z.array(chatParticipantSchema) });
402
+ const addParticipantSchema = z.object({
403
+ agentId: z.string().min(1),
404
+ mode: z.enum(["full", "mention_only"]).default("full")
405
+ });
406
+ z.object({ agentId: z.string().min(1) });
407
+ const clientStatusSchema = z.enum(["connected", "disconnected"]);
408
+ z.object({
409
+ id: z.string(),
410
+ userId: z.string().nullable(),
411
+ status: clientStatusSchema,
412
+ sdkVersion: z.string().max(50).nullable(),
413
+ hostname: z.string().max(100).nullable(),
414
+ os: z.string().max(50).nullable(),
415
+ agentCount: z.number().int().min(0),
416
+ connectedAt: z.string().nullable(),
417
+ lastSeenAt: z.string(),
418
+ metadata: z.record(z.string(), z.unknown()).nullable()
419
+ });
420
+ const clientRegisterSchema = z.object({
421
+ clientId: z.string().min(1).max(100),
422
+ hostname: z.string().max(100).optional(),
423
+ os: z.string().max(50).optional(),
424
+ sdkVersion: z.string().max(50).optional()
425
+ });
426
+ const paginationQuerySchema = z.object({
427
+ limit: z.coerce.number().int().min(1).max(100).default(20),
428
+ cursor: z.string().optional()
429
+ });
430
+ const messageSourceSchema = z.enum([
431
+ "hub_ui",
432
+ "cli",
433
+ "feishu",
434
+ "github",
435
+ "api"
436
+ ]);
437
+ const messageFormatSchema = z.enum([
438
+ "text",
439
+ "markdown",
440
+ "card",
441
+ "reference",
442
+ "file",
443
+ "task"
444
+ ]);
445
+ const sendMessageSchema = z.object({
446
+ format: messageFormatSchema.default("text"),
447
+ content: z.unknown(),
448
+ metadata: z.record(z.string(), z.unknown()).optional(),
449
+ inReplyTo: z.string().optional(),
450
+ replyToInbox: z.string().optional(),
451
+ replyToChat: z.string().optional(),
452
+ source: messageSourceSchema.optional()
453
+ });
454
+ const sendToAgentSchema = z.object({
455
+ format: messageFormatSchema.default("text"),
456
+ content: z.unknown(),
457
+ metadata: z.record(z.string(), z.unknown()).optional(),
458
+ replyToInbox: z.string().optional(),
459
+ replyToChat: z.string().optional(),
460
+ source: messageSourceSchema.optional()
461
+ });
462
+ /**
463
+ * Wire format for messages routed FROM the Hub TO a client runtime.
464
+ *
465
+ * Adds `configVersion` so the client can compare against its locally cached
466
+ * agent runtime config and refresh before delivering the message to the SDK.
467
+ *
468
+ * Step 3: this is the single shape used by `buildClientMessagePayload` —
469
+ * never serialise a raw `messageSchema` row to a client; always go through
470
+ * the dispatcher.
471
+ */
472
+ const clientMessageSchema = z.object({
473
+ id: z.string(),
474
+ chatId: z.string(),
475
+ senderId: z.string(),
476
+ format: z.string(),
477
+ content: z.unknown(),
478
+ metadata: z.record(z.string(), z.unknown()),
479
+ replyToInbox: z.string().nullable(),
480
+ replyToChat: z.string().nullable(),
481
+ inReplyTo: z.string().nullable(),
482
+ source: messageSourceSchema.nullable(),
483
+ createdAt: z.string()
484
+ }).extend({ configVersion: z.number().int().positive() });
485
+ z.enum([
486
+ "pending",
487
+ "delivered",
488
+ "acked",
489
+ "failed"
490
+ ]);
491
+ z.object({
492
+ id: z.number(),
493
+ inboxId: z.string(),
494
+ messageId: z.string(),
495
+ chatId: z.string().nullable(),
496
+ status: z.string(),
497
+ retryCount: z.number(),
498
+ createdAt: z.string(),
499
+ deliveredAt: z.string().nullable(),
500
+ ackedAt: z.string().nullable()
501
+ }).extend({ message: clientMessageSchema });
502
+ const inboxPollQuerySchema = z.object({ limit: z.coerce.number().int().min(1).max(50).default(10) });
503
+ const memberRoleSchema = z.enum(["admin", "member"]);
504
+ const memberSchema = z.object({
505
+ id: z.string(),
506
+ userId: z.string(),
507
+ organizationId: z.string(),
508
+ agentId: z.string(),
509
+ role: memberRoleSchema,
510
+ createdAt: z.string()
511
+ });
512
+ /** Admin creates a member — password is auto-generated, returned once. */
513
+ const createMemberSchema = z.object({
514
+ username: z.string().min(1).max(100),
515
+ displayName: z.string().min(1).max(200),
516
+ role: memberRoleSchema.default("member")
517
+ });
518
+ const updateMemberSchema = z.object({ role: memberRoleSchema.optional() });
519
+ memberSchema.extend({
520
+ username: z.string(),
521
+ displayName: z.string(),
522
+ password: z.string()
523
+ });
524
+ const notificationTypeSchema = z.enum([
525
+ "agent_error",
526
+ "session_error",
527
+ "agent_needs_decision",
528
+ "agent_blocked",
529
+ "agent_stale",
530
+ "agent_disconnected",
531
+ "agent_connected",
532
+ "session_completed"
533
+ ]);
534
+ const notificationSeveritySchema = z.enum([
535
+ "high",
536
+ "medium",
537
+ "low"
538
+ ]);
539
+ z.object({
540
+ id: z.string(),
541
+ organizationId: z.string(),
542
+ type: notificationTypeSchema,
543
+ severity: notificationSeveritySchema,
544
+ agentId: z.string().nullable(),
545
+ chatId: z.string().nullable(),
546
+ message: z.string(),
547
+ read: z.boolean(),
548
+ createdAt: z.string()
549
+ });
550
+ const notificationQuerySchema = z.object({
551
+ limit: z.coerce.number().int().min(1).max(100).default(20),
552
+ cursor: z.string().optional(),
553
+ severity: notificationSeveritySchema.optional(),
554
+ read: z.enum(["true", "false"]).transform((v) => v === "true").optional(),
555
+ agentId: z.string().optional()
556
+ });
557
+ const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
558
+ const createOrganizationSchema = z.object({
559
+ name: z.string().min(2).max(50).regex(/^[a-z0-9][a-z0-9-]*$/, "Must start with a letter or digit and contain only lowercase alphanumeric and hyphens").refine((v) => !UUID_PATTERN.test(v), "Name must not be a UUID format"),
560
+ displayName: z.string().min(1).max(200),
561
+ maxAgents: z.number().int().min(0).default(0),
562
+ maxMessagesPerMinute: z.number().int().min(0).default(0),
563
+ features: z.record(z.string(), z.unknown()).default({})
564
+ });
565
+ const updateOrganizationSchema = z.object({
566
+ name: z.string().min(2).max(50).regex(/^[a-z0-9][a-z0-9-]*$/, "Must start with a letter or digit and contain only lowercase alphanumeric and hyphens").refine((v) => !UUID_PATTERN.test(v), "Name must not be a UUID format").optional(),
567
+ displayName: z.string().min(1).max(200).optional(),
568
+ maxAgents: z.number().int().min(0).optional(),
569
+ maxMessagesPerMinute: z.number().int().min(0).optional(),
570
+ features: z.record(z.string(), z.unknown()).optional()
571
+ });
572
+ z.object({
573
+ id: z.string(),
574
+ name: z.string(),
575
+ displayName: z.string(),
576
+ maxAgents: z.number(),
577
+ maxMessagesPerMinute: z.number(),
578
+ features: z.record(z.string(), z.unknown()),
579
+ createdAt: z.string(),
580
+ updatedAt: z.string()
581
+ });
582
+ z.object({
583
+ id: z.string(),
584
+ agentId: z.string(),
585
+ chatId: z.string(),
586
+ content: z.string(),
587
+ updatedAt: z.string()
588
+ });
589
+ /** WS message: client reports session output text to server. */
590
+ const sessionOutputMessageSchema = z.object({
591
+ agentId: z.string(),
592
+ chatId: z.string(),
593
+ content: z.string().max(5e4)
594
+ });
595
+ const orgStatsSchema = z.object({
596
+ organizationId: z.string(),
597
+ agentCount: z.number(),
598
+ chatCount: z.number(),
599
+ messageCount: z.number()
600
+ });
601
+ z.object({
602
+ totalAgents: z.number(),
603
+ totalChats: z.number(),
604
+ totalMessages: z.number(),
605
+ byOrganization: z.array(orgStatsSchema)
606
+ });
607
+ z.object({
608
+ key: z.string(),
609
+ value: z.unknown(),
610
+ updatedAt: z.string()
611
+ });
612
+ const updateSystemConfigSchema = z.record(z.string(), z.unknown());
613
+ const SYSTEM_CONFIG_KEYS = {
614
+ INBOX_TIMEOUT_SECONDS: "inbox_timeout_seconds",
615
+ MAX_RETRY_COUNT: "max_retry_count",
616
+ POLLING_INTERVAL_SECONDS: "polling_interval_seconds",
617
+ PRESENCE_CLEANUP_SECONDS: "presence_cleanup_seconds"
618
+ };
619
+ const SYSTEM_CONFIG_DEFAULTS = {
620
+ [SYSTEM_CONFIG_KEYS.INBOX_TIMEOUT_SECONDS]: 300,
621
+ [SYSTEM_CONFIG_KEYS.MAX_RETRY_COUNT]: 3,
622
+ [SYSTEM_CONFIG_KEYS.POLLING_INTERVAL_SECONDS]: 5,
623
+ [SYSTEM_CONFIG_KEYS.PRESENCE_CLEANUP_SECONDS]: 60
624
+ };
625
+ /** Fixed 5-state machine. No custom statuses. */
626
+ const TASK_STATUSES = {
627
+ PENDING: "pending",
628
+ ASSIGNED: "assigned",
629
+ WORKING: "working",
630
+ COMPLETED: "completed",
631
+ FAILED: "failed",
632
+ CANCELLED: "cancelled"
633
+ };
634
+ const taskStatusSchema = z.enum([
635
+ "pending",
636
+ "assigned",
637
+ "working",
638
+ "completed",
639
+ "failed",
640
+ "cancelled"
641
+ ]);
642
+ /** Terminal statuses — once reached, no further transitions allowed. */
643
+ const TASK_TERMINAL_STATUSES = [
644
+ "completed",
645
+ "failed",
646
+ "cancelled"
647
+ ];
648
+ /** Creator type discriminator. */
649
+ const TASK_CREATOR_TYPES = {
650
+ AGENT: "agent",
651
+ ADMIN: "admin"
652
+ };
653
+ const taskCreatorTypeSchema = z.enum(["agent", "admin"]);
654
+ const taskMessageEventSchema = z.enum([
655
+ "assigned",
656
+ "status_changed",
657
+ "cancelled"
658
+ ]);
659
+ z.object({
660
+ taskId: z.string(),
661
+ event: taskMessageEventSchema,
662
+ title: z.string(),
663
+ body: z.string().default(""),
664
+ status: taskStatusSchema,
665
+ fromStatus: taskStatusSchema.optional(),
666
+ originRef: z.string().nullable().optional()
667
+ });
668
+ /** Create task input. Used by both agent API and admin API. */
669
+ const createTaskSchema = z.object({
670
+ title: z.string().min(1).max(500),
671
+ body: z.string().optional(),
672
+ assigneeAgentId: z.string().optional(),
673
+ originRef: z.string().max(500).optional(),
674
+ metadata: z.record(z.string(), z.unknown()).optional()
675
+ });
676
+ /** Admin-only create: allows passing an explicit organizationId. */
677
+ const adminCreateTaskSchema = createTaskSchema.extend({ organizationId: z.string().optional() });
678
+ /**
679
+ * Agent-facing status update. Agents may only self-report working/completed/failed.
680
+ * Cancellation goes through the dedicated cancel endpoint.
681
+ */
682
+ const updateTaskStatusSchema = z.object({
683
+ status: z.enum([
684
+ "working",
685
+ "completed",
686
+ "failed"
687
+ ]),
688
+ result: z.string().optional()
689
+ });
690
+ /** Admin-facing update — may re-assign or re-target status (within legal transitions). */
691
+ const adminUpdateTaskSchema = z.object({
692
+ assigneeAgentId: z.string().nullable().optional(),
693
+ status: taskStatusSchema.optional(),
694
+ result: z.string().optional()
695
+ });
696
+ const linkTaskChatSchema = z.object({ chatId: z.string().min(1) });
697
+ const taskSchema = z.object({
698
+ id: z.string(),
699
+ organizationId: z.string(),
700
+ title: z.string(),
701
+ body: z.string(),
702
+ status: taskStatusSchema,
703
+ assigneeAgentId: z.string().nullable(),
704
+ createdByType: taskCreatorTypeSchema,
705
+ createdById: z.string(),
706
+ originRef: z.string().nullable(),
707
+ result: z.string().nullable(),
708
+ metadata: z.record(z.string(), z.unknown()),
709
+ createdAt: z.string(),
710
+ updatedAt: z.string(),
711
+ cancelledAt: z.string().nullable(),
712
+ cancelledByType: taskCreatorTypeSchema.nullable(),
713
+ cancelledById: z.string().nullable()
714
+ });
715
+ const taskChatLinkSchema = z.object({
716
+ taskId: z.string(),
717
+ chatId: z.string(),
718
+ linkedByAgentId: z.string().nullable(),
719
+ linkedAt: z.string()
720
+ });
721
+ taskSchema.extend({ chats: z.array(taskChatLinkSchema) });
722
+ const taskListQuerySchema = z.object({
723
+ status: taskStatusSchema.optional(),
724
+ assigneeAgentId: z.string().optional(),
725
+ originRef: z.string().optional(),
726
+ limit: z.coerce.number().int().min(1).max(100).default(20),
727
+ cursor: z.string().optional()
728
+ });
729
+ /**
730
+ * Task health signals derived from associated chats' session state + recent messages.
731
+ * See hub-task-design Section 9.
732
+ */
733
+ const TASK_HEALTH_SIGNALS = {
734
+ NORMAL: "normal",
735
+ IDLE_ISLAND: "idle_island",
736
+ AWAITING_REPLY: "awaiting_reply",
737
+ NO_CHAT: "no_chat",
738
+ NOT_APPLICABLE: "not_applicable"
739
+ };
740
+ const taskHealthSignalSchema = z.enum([
741
+ "normal",
742
+ "idle_island",
743
+ "awaiting_reply",
744
+ "no_chat",
745
+ "not_applicable"
746
+ ]);
747
+ z.object({
748
+ taskId: z.string(),
749
+ signal: taskHealthSignalSchema,
750
+ reason: z.string()
751
+ });
752
+ const userStatusSchema = z.enum(["active", "suspended"]);
753
+ z.object({
754
+ id: z.string(),
755
+ username: z.string(),
756
+ displayName: z.string(),
757
+ avatarUrl: z.string().nullable(),
758
+ status: userStatusSchema,
759
+ createdAt: z.string(),
760
+ updatedAt: z.string()
761
+ });
762
+ z.object({
763
+ username: z.string().min(1).max(100),
764
+ displayName: z.string().min(1).max(200),
765
+ password: z.string().min(8).max(200)
766
+ });
767
+ z.object({
768
+ displayName: z.string().min(1).max(200).optional(),
769
+ password: z.string().min(8).max(200).optional()
770
+ });
771
+ /**
772
+ * First-frame auth envelope sent by the SDK on the client WS connection.
773
+ * The server rejects the connection with close code 4401 if this frame does
774
+ * not arrive within {@link WS_AUTH_FRAME_TIMEOUT_MS} or fails verification.
775
+ */
776
+ const wsAuthFrameSchema = z.object({
777
+ type: z.literal("auth"),
778
+ token: z.string().min(1)
779
+ });
780
+ /** How long the server waits for the first `auth` frame before closing the WS. */
781
+ const WS_AUTH_FRAME_TIMEOUT_MS = 5e3;
782
+ //#endregion
783
+ //#region src/core/feishu.ts
784
+ var feishu_exports = /* @__PURE__ */ __exportAll({
785
+ bindFeishuBot: () => bindFeishuBot,
786
+ bindFeishuUser: () => bindFeishuUser
787
+ });
788
+ /**
789
+ * Feishu-related core operations: bind-bot, bind-user.
790
+ *
791
+ * All agent-scoped calls carry both the member access JWT (Authorization)
792
+ * and the acting agent UUID (X-Agent-Id); the server's agent-selector
793
+ * middleware enforces Rule R-RUN.
794
+ */
795
+ async function bindFeishuBot(serverUrl, accessToken, agentId, appId, appSecret) {
796
+ const res = await fetch(`${serverUrl}/api/v1/agent/me/feishu-bot`, {
797
+ method: "PUT",
798
+ headers: {
799
+ Authorization: `Bearer ${accessToken}`,
800
+ [AGENT_SELECTOR_HEADER]: agentId,
801
+ "Content-Type": "application/json"
802
+ },
803
+ body: JSON.stringify({
804
+ appId,
805
+ appSecret
806
+ })
807
+ });
808
+ if (!res.ok) {
809
+ const body = await res.json().catch(() => ({}));
810
+ throw new Error(body.error ?? `Bind Feishu bot failed: HTTP ${res.status}`);
811
+ }
812
+ }
813
+ async function bindFeishuUser(serverUrl, accessToken, agentId, humanAgentId, feishuUserId, displayName) {
814
+ const res = await fetch(`${serverUrl}/api/v1/agent/delegated/${encodeURIComponent(humanAgentId)}/feishu-user`, {
815
+ method: "POST",
816
+ headers: {
817
+ Authorization: `Bearer ${accessToken}`,
818
+ [AGENT_SELECTOR_HEADER]: agentId,
819
+ "Content-Type": "application/json"
820
+ },
821
+ body: JSON.stringify({
822
+ feishuUserId,
823
+ displayName
824
+ })
825
+ });
826
+ if (!res.ok) {
827
+ const body = await res.json().catch(() => ({}));
828
+ throw new Error(body.error ?? `Bind Feishu user failed: HTTP ${res.status}`);
829
+ }
830
+ }
831
+ //#endregion
832
+ export { updateOrganizationSchema as $, createOrganizationSchema as A, paginationQuerySchema as B, clientRegisterSchema as C, createAgentSchema as D, createAdapterMappingSchema as E, isRedactedEnvValue as F, sendToAgentSchema as G, runtimeStateMessageSchema as H, linkTaskChatSchema as I, taskListQuerySchema as J, sessionOutputMessageSchema as K, loginSchema as L, delegateFeishuUserSchema as M, dryRunAgentRuntimeConfigSchema as N, createChatSchema as O, inboxPollQuerySchema as P, updateMemberSchema as Q, messageSourceSchema as R, agentTypeSchema as S, createAdapterConfigSchema as T, selfServiceFeishuBotSchema as U, refreshTokenSchema as V, sendMessageSchema as W, updateAgentRuntimeConfigSchema as X, updateAdapterConfigSchema as Y, updateAgentSchema as Z, addParticipantSchema as _, AGENT_SELECTOR_HEADER as a, agentBindRequestSchema as b, AGENT_TYPES as c, SYSTEM_CONFIG_DEFAULTS as d, updateSystemConfigSchema as et, TASK_CREATOR_TYPES as f, WS_AUTH_FRAME_TIMEOUT_MS as g, TASK_TERMINAL_STATUSES as h, AGENT_BIND_REJECT_REASONS as i, createTaskSchema as j, createMemberSchema as k, AGENT_VISIBILITY as l, TASK_STATUSES as m, bindFeishuUser as n, wsAuthFrameSchema as nt, AGENT_SOURCES as o, TASK_HEALTH_SIGNALS as p, sessionStateMessageSchema as q, feishu_exports as r, AGENT_STATUSES as s, bindFeishuBot as t, updateTaskStatusSchema as tt, DEFAULT_AGENT_RUNTIME_CONFIG_PAYLOAD as u, adminCreateTaskSchema as v, connectTokenExchangeSchema as w, agentRuntimeConfigPayloadSchema as x, adminUpdateTaskSchema as y, notificationQuerySchema as z };