@app-vitals/agent-admin 0.12.0 → 0.13.1
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/e2e/test-server.ts +5 -5
- package/openapi.json +12 -19
- package/openapi.platform.json +11 -18
- package/package.json +2 -2
- package/prisma/client/internal/class.ts +4 -4
- package/prisma/client/internal/prismaNamespace.ts +0 -1
- package/prisma/client/internal/prismaNamespaceBrowser.ts +0 -1
- package/prisma/client/models/Agent.ts +62 -137
- package/prisma/migrations/20261030000000_drop_agent_type_name/migration.sql +8 -0
- package/prisma/schema/schema.prisma +3 -4
- package/src/account-lifecycle.integration.test.ts +1 -1
- package/src/account-trial-warning-sweeper.integration.test.ts +1 -1
- package/src/admin-local-agent.smoke.test.ts +12 -12
- package/src/admin-ui-pages.ts +2 -2
- package/src/admin-ui-pages.unit.test.ts +2 -2
- package/src/admin-ui.fixtures.ts +6 -6
- package/src/admin-ui.smoke.test.ts +39 -39
- package/src/admin-ui.ts +8 -8
- package/src/agent-cron-jobs.integration.test.ts +8 -7
- package/src/agent-cron-jobs.ts +4 -5
- package/src/agent-cron-jobs.unit.test.ts +23 -23
- package/src/agent-patch-author-allowlist.integration.test.ts +4 -4
- package/src/agent-specialty-backfill.integration.test.ts +126 -0
- package/src/agents-api.integration.test.ts +20 -20
- package/src/agents-api.smoke.test.ts +76 -77
- package/src/agents-api.ts +9 -14
- package/src/agents.integration.test.ts +40 -53
- package/src/agents.ts +33 -46
- package/src/agents.unit.test.ts +28 -35
- package/src/api.smoke.test.ts +24 -2
- package/src/api.ts +15 -16
- package/src/openapi-schemas.ts +14 -7
- package/src/slack-provisioning-service.integration.test.ts +2 -2
- package/src/slack-provisioning.integration.test.ts +2 -2
- package/src/specialty-manifest-loader.ts +32 -32
- package/src/specialty-manifest-loader.unit.test.ts +8 -8
- package/src/startup-policy-reconcile.unit.test.ts +1 -1
- package/src/trial-expiry-sweeper.integration.test.ts +1 -1
- package/src/trial-expiry-warning-sweeper.integration.test.ts +1 -1
- package/src/agent-specialty.ts +0 -22
- package/src/agent-specialty.unit.test.ts +0 -43
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
-- AGR-6.3: REMOVE step of the typeName -> specialty rename.
|
|
2
|
+
-- Backfill any row AGR-6.1/6.2 missed (specialty still NULL) from typeName,
|
|
3
|
+
-- make specialty required (default 'coding', matching the old typeName
|
|
4
|
+
-- default), then drop the legacy typeName column.
|
|
5
|
+
UPDATE "Agent" SET "specialty" = "typeName" WHERE "specialty" IS NULL;
|
|
6
|
+
ALTER TABLE "Agent" ALTER COLUMN "specialty" SET DEFAULT 'coding';
|
|
7
|
+
ALTER TABLE "Agent" ALTER COLUMN "specialty" SET NOT NULL;
|
|
8
|
+
ALTER TABLE "Agent" DROP COLUMN "typeName";
|
|
@@ -42,10 +42,9 @@ model Agent {
|
|
|
42
42
|
reviewAuthorAllowlist String[] @default([])
|
|
43
43
|
patchAuthorAllowlist String[] @default([])
|
|
44
44
|
restrictSlackToMembers Boolean @default(false)
|
|
45
|
-
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
specialty String?
|
|
45
|
+
// The agent's Specialty name (manifest key). AGR-6.3 made it required and
|
|
46
|
+
// dropped the legacy typeName column.
|
|
47
|
+
specialty String @default("coding")
|
|
49
48
|
// SSP-1.2: owning account. Nullable/additive — existing agents keep NULL.
|
|
50
49
|
accountId String?
|
|
51
50
|
account Account? @relation(fields: [accountId], references: [id], onDelete: Restrict)
|
|
@@ -86,7 +86,7 @@ describeOrSkip("account lifecycle (integration)", () => {
|
|
|
86
86
|
trialExpiresAt: Date | null = null,
|
|
87
87
|
): Promise<string> {
|
|
88
88
|
const a = await prisma.agent.create({
|
|
89
|
-
data: { name: "agent",
|
|
89
|
+
data: { name: "agent", specialty: "coding", accountId, trialExpiresAt },
|
|
90
90
|
});
|
|
91
91
|
return a.id;
|
|
92
92
|
}
|
|
@@ -100,7 +100,7 @@ describeOrSkip("AccountTrialWarningSweeper (integration)", () => {
|
|
|
100
100
|
name = "bot",
|
|
101
101
|
): Promise<string> {
|
|
102
102
|
const a = await prisma.agent.create({
|
|
103
|
-
data: { name,
|
|
103
|
+
data: { name, specialty: "coding", accountId },
|
|
104
104
|
});
|
|
105
105
|
if (slack) {
|
|
106
106
|
slackEnv.set(a.id, {
|
|
@@ -247,7 +247,7 @@ function makeMockDeps(overrides?: Partial<AdminUIDeps>): AdminUIDeps {
|
|
|
247
247
|
reviewAuthorAllowlist: [],
|
|
248
248
|
patchAuthorAllowlist: [],
|
|
249
249
|
restrictSlackToMembers: false,
|
|
250
|
-
|
|
250
|
+
specialty: TYPE,
|
|
251
251
|
createdAt: new Date("2024-01-01"),
|
|
252
252
|
updatedAt: new Date("2024-01-01"),
|
|
253
253
|
missingRequiredEnv: [],
|
|
@@ -262,7 +262,7 @@ function makeMockDeps(overrides?: Partial<AdminUIDeps>): AdminUIDeps {
|
|
|
262
262
|
reviewAuthorAllowlist: [],
|
|
263
263
|
patchAuthorAllowlist: [],
|
|
264
264
|
restrictSlackToMembers: false,
|
|
265
|
-
|
|
265
|
+
specialty: TYPE,
|
|
266
266
|
createdAt: new Date("2024-01-01"),
|
|
267
267
|
updatedAt: new Date("2024-01-01"),
|
|
268
268
|
missingRequiredEnv: [],
|
|
@@ -276,7 +276,7 @@ function makeMockDeps(overrides?: Partial<AdminUIDeps>): AdminUIDeps {
|
|
|
276
276
|
reviewAuthorAllowlist: [],
|
|
277
277
|
patchAuthorAllowlist: [],
|
|
278
278
|
restrictSlackToMembers: false,
|
|
279
|
-
|
|
279
|
+
specialty: TYPE,
|
|
280
280
|
createdAt: new Date("2024-01-01"),
|
|
281
281
|
updatedAt: new Date("2024-01-01"),
|
|
282
282
|
missingRequiredEnv: [],
|
|
@@ -415,7 +415,7 @@ describe("admin UI — new local agent create flow", () => {
|
|
|
415
415
|
reviewAuthorAllowlist: [],
|
|
416
416
|
patchAuthorAllowlist: [],
|
|
417
417
|
restrictSlackToMembers: false,
|
|
418
|
-
|
|
418
|
+
specialty: TYPE,
|
|
419
419
|
createdAt: new Date("2024-01-01"),
|
|
420
420
|
updatedAt: new Date("2024-01-01"),
|
|
421
421
|
missingRequiredEnv: [],
|
|
@@ -476,7 +476,7 @@ describe("admin UI — new local agent create flow", () => {
|
|
|
476
476
|
reviewAuthorAllowlist: [],
|
|
477
477
|
patchAuthorAllowlist: [],
|
|
478
478
|
restrictSlackToMembers: false,
|
|
479
|
-
|
|
479
|
+
specialty: TYPE,
|
|
480
480
|
createdAt: new Date("2024-01-01"),
|
|
481
481
|
updatedAt: new Date("2024-01-01"),
|
|
482
482
|
missingRequiredEnv: [],
|
|
@@ -492,7 +492,7 @@ describe("admin UI — new local agent create flow", () => {
|
|
|
492
492
|
reviewAuthorAllowlist: [],
|
|
493
493
|
patchAuthorAllowlist: [],
|
|
494
494
|
restrictSlackToMembers: false,
|
|
495
|
-
|
|
495
|
+
specialty: TYPE,
|
|
496
496
|
createdAt: new Date("2024-01-01"),
|
|
497
497
|
updatedAt: new Date("2024-01-01"),
|
|
498
498
|
missingRequiredEnv: [],
|
|
@@ -661,7 +661,7 @@ describe("admin UI — new local agent create flow", () => {
|
|
|
661
661
|
reviewAuthorAllowlist: [],
|
|
662
662
|
patchAuthorAllowlist: [],
|
|
663
663
|
restrictSlackToMembers: false,
|
|
664
|
-
|
|
664
|
+
specialty: TYPE,
|
|
665
665
|
createdAt: new Date("2024-01-01"),
|
|
666
666
|
updatedAt: new Date("2024-01-01"),
|
|
667
667
|
missingRequiredEnv: [],
|
|
@@ -702,7 +702,7 @@ describe("admin UI — new local agent create flow", () => {
|
|
|
702
702
|
reviewAuthorAllowlist: [],
|
|
703
703
|
patchAuthorAllowlist: [],
|
|
704
704
|
restrictSlackToMembers: false,
|
|
705
|
-
|
|
705
|
+
specialty: TYPE,
|
|
706
706
|
createdAt: new Date("2024-01-01"),
|
|
707
707
|
updatedAt: new Date("2024-01-01"),
|
|
708
708
|
missingRequiredEnv: [],
|
|
@@ -744,7 +744,7 @@ describe("admin UI — new local agent create flow", () => {
|
|
|
744
744
|
reviewAuthorAllowlist: [],
|
|
745
745
|
patchAuthorAllowlist: [],
|
|
746
746
|
restrictSlackToMembers: false,
|
|
747
|
-
|
|
747
|
+
specialty: TYPE,
|
|
748
748
|
createdAt: new Date("2024-01-01"),
|
|
749
749
|
updatedAt: new Date("2024-01-01"),
|
|
750
750
|
missingRequiredEnv: [],
|
|
@@ -851,7 +851,7 @@ describe("admin UI — new local agent create flow", () => {
|
|
|
851
851
|
reviewAuthorAllowlist: [],
|
|
852
852
|
patchAuthorAllowlist: [],
|
|
853
853
|
restrictSlackToMembers: false,
|
|
854
|
-
|
|
854
|
+
specialty: TYPE,
|
|
855
855
|
createdAt: new Date("2024-01-01"),
|
|
856
856
|
updatedAt: new Date("2024-01-01"),
|
|
857
857
|
missingRequiredEnv: [],
|
|
@@ -1095,7 +1095,7 @@ describe("admin UI — new local agent create flow", () => {
|
|
|
1095
1095
|
reviewAuthorAllowlist: [],
|
|
1096
1096
|
patchAuthorAllowlist: [],
|
|
1097
1097
|
restrictSlackToMembers: false,
|
|
1098
|
-
|
|
1098
|
+
specialty: TYPE,
|
|
1099
1099
|
createdAt: new Date("2024-01-01"),
|
|
1100
1100
|
updatedAt: new Date("2024-01-01"),
|
|
1101
1101
|
missingRequiredEnv: [],
|
|
@@ -1537,7 +1537,7 @@ describe("admin UI — account users create / delete agents (SSP-4.2)", () => {
|
|
|
1537
1537
|
expect(created).toHaveLength(1);
|
|
1538
1538
|
expect(created[0]).toMatchObject({
|
|
1539
1539
|
accountId: "acct-a",
|
|
1540
|
-
|
|
1540
|
+
specialty: TYPE,
|
|
1541
1541
|
});
|
|
1542
1542
|
});
|
|
1543
1543
|
|
package/src/admin-ui-pages.ts
CHANGED
|
@@ -80,7 +80,7 @@ export interface AgentDetail {
|
|
|
80
80
|
*/
|
|
81
81
|
restrictSlackToMembers: boolean;
|
|
82
82
|
/** The agent's type name (e.g. "coding"), resolved at creation time. */
|
|
83
|
-
|
|
83
|
+
specialty: string;
|
|
84
84
|
/**
|
|
85
85
|
* Required env keys declared by the agent's type manifest with no
|
|
86
86
|
* corresponding AgentEnv row yet — key names only, never values. Always
|
|
@@ -1911,7 +1911,7 @@ export function renderAgentDetailPage(
|
|
|
1911
1911
|
<div>
|
|
1912
1912
|
<a href="/admin/agents" style="font-size:13px;color:#6b7280;text-decoration:none">← Agents</a>
|
|
1913
1913
|
<h1 class="page-title" style="margin-top:4px">${escapeHtml(agent.name)}</h1>
|
|
1914
|
-
<span style="font-size:13px;color:#6b7280">Type: <span class="mono">${escapeHtml(agent.
|
|
1914
|
+
<span style="font-size:13px;color:#6b7280">Type: <span class="mono">${escapeHtml(agent.specialty)}</span></span>
|
|
1915
1915
|
${agent.slackId ? `<span style="font-size:13px;color:#6b7280">Slack ID: <span class="mono">${escapeHtml(agent.slackId)}</span></span>` : ""}
|
|
1916
1916
|
</div>
|
|
1917
1917
|
${
|
|
@@ -47,7 +47,7 @@ const AGENT: AgentDetail = {
|
|
|
47
47
|
authorAllowlist: [],
|
|
48
48
|
patchAuthorAllowlist: [],
|
|
49
49
|
restrictSlackToMembers: false,
|
|
50
|
-
|
|
50
|
+
specialty: "coding",
|
|
51
51
|
missingRequiredEnv: [],
|
|
52
52
|
autoPostReviews: true,
|
|
53
53
|
allowSelfReview: false,
|
|
@@ -638,7 +638,7 @@ describe("renderAgentDetailPage — overview", () => {
|
|
|
638
638
|
test("XSS: specialty name is escaped", () => {
|
|
639
639
|
const xssAgent: AgentDetail = {
|
|
640
640
|
...AGENT,
|
|
641
|
-
|
|
641
|
+
specialty: '<script>alert("xss")</script>',
|
|
642
642
|
};
|
|
643
643
|
const html = renderAgentDetailPage(
|
|
644
644
|
xssAgent,
|
package/src/admin-ui.fixtures.ts
CHANGED
|
@@ -336,7 +336,7 @@ export function makeMockDeps(
|
|
|
336
336
|
name: "Test Agent",
|
|
337
337
|
slackId: "U123456",
|
|
338
338
|
selfHosted: false,
|
|
339
|
-
|
|
339
|
+
specialty: "coding",
|
|
340
340
|
createdAt: new Date("2024-01-01"),
|
|
341
341
|
updatedAt: new Date("2024-01-01"),
|
|
342
342
|
},
|
|
@@ -347,7 +347,7 @@ export function makeMockDeps(
|
|
|
347
347
|
name: "Test Agent",
|
|
348
348
|
slackId: "U123456",
|
|
349
349
|
selfHosted: false,
|
|
350
|
-
|
|
350
|
+
specialty: "coding",
|
|
351
351
|
createdAt: new Date("2024-01-01"),
|
|
352
352
|
updatedAt: new Date("2024-01-01"),
|
|
353
353
|
},
|
|
@@ -358,7 +358,7 @@ export function makeMockDeps(
|
|
|
358
358
|
name: "Test Agent",
|
|
359
359
|
slackId: "U123456",
|
|
360
360
|
selfHosted: false,
|
|
361
|
-
|
|
361
|
+
specialty: "coding",
|
|
362
362
|
createdAt: new Date("2024-01-01"),
|
|
363
363
|
updatedAt: new Date("2024-01-01"),
|
|
364
364
|
},
|
|
@@ -373,7 +373,7 @@ export function makeMockDeps(
|
|
|
373
373
|
reviewAuthorAllowlist: [],
|
|
374
374
|
patchAuthorAllowlist: [],
|
|
375
375
|
restrictSlackToMembers: false,
|
|
376
|
-
|
|
376
|
+
specialty: "coding",
|
|
377
377
|
createdAt: new Date("2024-01-01"),
|
|
378
378
|
updatedAt: new Date("2024-01-01"),
|
|
379
379
|
missingRequiredEnv: [],
|
|
@@ -384,7 +384,7 @@ export function makeMockDeps(
|
|
|
384
384
|
name: "Test Agent",
|
|
385
385
|
slackId: "U123456",
|
|
386
386
|
selfHosted: false,
|
|
387
|
-
|
|
387
|
+
specialty: "coding",
|
|
388
388
|
createdAt: new Date("2024-01-01"),
|
|
389
389
|
updatedAt: new Date("2024-01-01"),
|
|
390
390
|
repos: [],
|
|
@@ -398,7 +398,7 @@ export function makeMockDeps(
|
|
|
398
398
|
name: "Test Agent",
|
|
399
399
|
slackId: "U123456",
|
|
400
400
|
selfHosted: false,
|
|
401
|
-
|
|
401
|
+
specialty: "coding",
|
|
402
402
|
createdAt: new Date("2024-01-01"),
|
|
403
403
|
updatedAt: new Date("2024-01-01"),
|
|
404
404
|
repos: [],
|
|
@@ -1484,7 +1484,7 @@ describe("admin UI — authenticated pages", () => {
|
|
|
1484
1484
|
name: "Managed Agent",
|
|
1485
1485
|
slackId: "U0AALR8M69X",
|
|
1486
1486
|
selfHosted: false,
|
|
1487
|
-
|
|
1487
|
+
specialty: TYPE,
|
|
1488
1488
|
createdAt: new Date("2024-01-01"),
|
|
1489
1489
|
updatedAt: new Date("2024-01-01"),
|
|
1490
1490
|
repos: [],
|
|
@@ -1573,7 +1573,7 @@ describe("admin UI — authenticated pages", () => {
|
|
|
1573
1573
|
name: "Self-Hosted Agent",
|
|
1574
1574
|
slackId: null,
|
|
1575
1575
|
selfHosted: true,
|
|
1576
|
-
|
|
1576
|
+
specialty: TYPE,
|
|
1577
1577
|
createdAt: new Date("2024-01-01"),
|
|
1578
1578
|
updatedAt: new Date("2024-01-01"),
|
|
1579
1579
|
repos: [],
|
|
@@ -1603,7 +1603,7 @@ describe("admin UI — authenticated pages", () => {
|
|
|
1603
1603
|
name: "Self-Hosted Agent",
|
|
1604
1604
|
slackId: null,
|
|
1605
1605
|
selfHosted: true,
|
|
1606
|
-
|
|
1606
|
+
specialty: TYPE,
|
|
1607
1607
|
createdAt: new Date("2024-01-01"),
|
|
1608
1608
|
updatedAt: new Date("2024-01-01"),
|
|
1609
1609
|
repos: [],
|
|
@@ -1644,7 +1644,7 @@ describe("admin UI — authenticated pages", () => {
|
|
|
1644
1644
|
name: "Self-Hosted Agent",
|
|
1645
1645
|
slackId: null,
|
|
1646
1646
|
selfHosted: true,
|
|
1647
|
-
|
|
1647
|
+
specialty: TYPE,
|
|
1648
1648
|
createdAt: new Date("2024-01-01"),
|
|
1649
1649
|
updatedAt: new Date("2024-01-01"),
|
|
1650
1650
|
repos: [],
|
|
@@ -1703,7 +1703,7 @@ describe("admin UI — authenticated pages", () => {
|
|
|
1703
1703
|
name: "Self-Hosted Agent",
|
|
1704
1704
|
slackId: null,
|
|
1705
1705
|
selfHosted: true,
|
|
1706
|
-
|
|
1706
|
+
specialty: TYPE,
|
|
1707
1707
|
createdAt: new Date("2024-01-01"),
|
|
1708
1708
|
updatedAt: new Date("2024-01-01"),
|
|
1709
1709
|
repos: [],
|
|
@@ -2116,7 +2116,7 @@ describe("admin UI — owner and Anthropic identity section (PAI-2.5)", () => {
|
|
|
2116
2116
|
name: "Test Agent",
|
|
2117
2117
|
slackId: "U123456",
|
|
2118
2118
|
selfHosted: false,
|
|
2119
|
-
|
|
2119
|
+
specialty: TYPE,
|
|
2120
2120
|
createdAt: new Date("2024-01-01"),
|
|
2121
2121
|
updatedAt: new Date("2024-01-01"),
|
|
2122
2122
|
repos: [],
|
|
@@ -2249,7 +2249,7 @@ describe("admin UI — agent policy fields", () => {
|
|
|
2249
2249
|
name: "Test Agent",
|
|
2250
2250
|
slackId: "U123456",
|
|
2251
2251
|
selfHosted: false,
|
|
2252
|
-
|
|
2252
|
+
specialty: TYPE,
|
|
2253
2253
|
createdAt: new Date("2024-01-01"),
|
|
2254
2254
|
updatedAt: new Date("2024-01-01"),
|
|
2255
2255
|
repos: [],
|
|
@@ -2334,7 +2334,7 @@ describe("admin UI — agent policy fields", () => {
|
|
|
2334
2334
|
name: "Test Agent",
|
|
2335
2335
|
slackId: "U123456",
|
|
2336
2336
|
selfHosted: false,
|
|
2337
|
-
|
|
2337
|
+
specialty: TYPE,
|
|
2338
2338
|
createdAt: new Date("2024-01-01"),
|
|
2339
2339
|
updatedAt: new Date("2024-01-01"),
|
|
2340
2340
|
repos: [],
|
|
@@ -2379,7 +2379,7 @@ describe("admin UI — agent policy fields", () => {
|
|
|
2379
2379
|
name: "Test Agent",
|
|
2380
2380
|
slackId: "U123456",
|
|
2381
2381
|
selfHosted: false,
|
|
2382
|
-
|
|
2382
|
+
specialty: TYPE,
|
|
2383
2383
|
createdAt: new Date("2024-01-01"),
|
|
2384
2384
|
updatedAt: new Date("2024-01-01"),
|
|
2385
2385
|
repos: [],
|
|
@@ -2420,7 +2420,7 @@ describe("admin UI — agent policy fields", () => {
|
|
|
2420
2420
|
name: "Test Agent",
|
|
2421
2421
|
slackId: "U123456",
|
|
2422
2422
|
selfHosted: false,
|
|
2423
|
-
|
|
2423
|
+
specialty: TYPE,
|
|
2424
2424
|
createdAt: new Date("2024-01-01"),
|
|
2425
2425
|
updatedAt: new Date("2024-01-01"),
|
|
2426
2426
|
repos: [],
|
|
@@ -2473,7 +2473,7 @@ describe("admin UI — agent policy fields", () => {
|
|
|
2473
2473
|
name: "Test Agent",
|
|
2474
2474
|
slackId: "U123456",
|
|
2475
2475
|
selfHosted: false,
|
|
2476
|
-
|
|
2476
|
+
specialty: TYPE,
|
|
2477
2477
|
createdAt: new Date("2024-01-01"),
|
|
2478
2478
|
updatedAt: new Date("2024-01-01"),
|
|
2479
2479
|
repos: [],
|
|
@@ -2560,7 +2560,7 @@ describe("admin UI — agent policy fields", () => {
|
|
|
2560
2560
|
name: "Test Agent",
|
|
2561
2561
|
slackId: "U123456",
|
|
2562
2562
|
selfHosted: false,
|
|
2563
|
-
|
|
2563
|
+
specialty: TYPE,
|
|
2564
2564
|
createdAt: new Date("2024-01-01"),
|
|
2565
2565
|
updatedAt: new Date("2024-01-01"),
|
|
2566
2566
|
repos: [],
|
|
@@ -2605,7 +2605,7 @@ describe("admin UI — agent policy fields", () => {
|
|
|
2605
2605
|
name: "Test Agent",
|
|
2606
2606
|
slackId: "U123456",
|
|
2607
2607
|
selfHosted: false,
|
|
2608
|
-
|
|
2608
|
+
specialty: TYPE,
|
|
2609
2609
|
createdAt: new Date("2024-01-01"),
|
|
2610
2610
|
updatedAt: new Date("2024-01-01"),
|
|
2611
2611
|
repos: [],
|
|
@@ -2650,7 +2650,7 @@ describe("admin UI — agent policy fields", () => {
|
|
|
2650
2650
|
name: "Test Agent",
|
|
2651
2651
|
slackId: "U123456",
|
|
2652
2652
|
selfHosted: false,
|
|
2653
|
-
|
|
2653
|
+
specialty: TYPE,
|
|
2654
2654
|
createdAt: new Date("2024-01-01"),
|
|
2655
2655
|
updatedAt: new Date("2024-01-01"),
|
|
2656
2656
|
repos: [],
|
|
@@ -2962,7 +2962,7 @@ describe("admin UI — member access control", () => {
|
|
|
2962
2962
|
name: "My Agent",
|
|
2963
2963
|
slackId: "U1",
|
|
2964
2964
|
selfHosted: false,
|
|
2965
|
-
|
|
2965
|
+
specialty: TYPE,
|
|
2966
2966
|
createdAt: new Date("2024-01-01"),
|
|
2967
2967
|
updatedAt: new Date("2024-01-01"),
|
|
2968
2968
|
},
|
|
@@ -2971,7 +2971,7 @@ describe("admin UI — member access control", () => {
|
|
|
2971
2971
|
name: "Other Agent",
|
|
2972
2972
|
slackId: "U2",
|
|
2973
2973
|
selfHosted: false,
|
|
2974
|
-
|
|
2974
|
+
specialty: TYPE,
|
|
2975
2975
|
createdAt: new Date("2024-01-01"),
|
|
2976
2976
|
updatedAt: new Date("2024-01-01"),
|
|
2977
2977
|
},
|
|
@@ -2983,7 +2983,7 @@ describe("admin UI — member access control", () => {
|
|
|
2983
2983
|
name: "My Agent",
|
|
2984
2984
|
slackId: "U1",
|
|
2985
2985
|
selfHosted: false,
|
|
2986
|
-
|
|
2986
|
+
specialty: TYPE,
|
|
2987
2987
|
createdAt: new Date("2024-01-01"),
|
|
2988
2988
|
updatedAt: new Date("2024-01-01"),
|
|
2989
2989
|
},
|
|
@@ -2992,7 +2992,7 @@ describe("admin UI — member access control", () => {
|
|
|
2992
2992
|
name: "Other Agent",
|
|
2993
2993
|
slackId: "U2",
|
|
2994
2994
|
selfHosted: false,
|
|
2995
|
-
|
|
2995
|
+
specialty: TYPE,
|
|
2996
2996
|
createdAt: new Date("2024-01-01"),
|
|
2997
2997
|
updatedAt: new Date("2024-01-01"),
|
|
2998
2998
|
},
|
|
@@ -4146,7 +4146,7 @@ describe("admin UI — GET /admin/agents/:id/connect-slack/callback", () => {
|
|
|
4146
4146
|
name: "Test Agent",
|
|
4147
4147
|
slackId: null,
|
|
4148
4148
|
selfHosted: false,
|
|
4149
|
-
|
|
4149
|
+
specialty: TYPE,
|
|
4150
4150
|
createdAt: new Date("2024-01-01"),
|
|
4151
4151
|
updatedAt: new Date("2024-01-01"),
|
|
4152
4152
|
repos: [],
|
|
@@ -5290,7 +5290,7 @@ describe("admin UI — create agent with author allowlist", () => {
|
|
|
5290
5290
|
name: "Test Agent",
|
|
5291
5291
|
slackId: null,
|
|
5292
5292
|
selfHosted: true,
|
|
5293
|
-
|
|
5293
|
+
specialty: TYPE,
|
|
5294
5294
|
createdAt: new Date("2024-01-01"),
|
|
5295
5295
|
updatedAt: new Date("2024-01-01"),
|
|
5296
5296
|
repos: [],
|
|
@@ -5486,7 +5486,7 @@ describe("admin UI — create agent with patch author allowlist", () => {
|
|
|
5486
5486
|
name: "Test Agent",
|
|
5487
5487
|
slackId: null,
|
|
5488
5488
|
selfHosted: true,
|
|
5489
|
-
|
|
5489
|
+
specialty: TYPE,
|
|
5490
5490
|
createdAt: new Date("2024-01-01"),
|
|
5491
5491
|
updatedAt: new Date("2024-01-01"),
|
|
5492
5492
|
repos: [],
|
|
@@ -5865,7 +5865,7 @@ describe("admin UI — repos mutation routes", () => {
|
|
|
5865
5865
|
name: "Test Agent",
|
|
5866
5866
|
slackId: "U123456",
|
|
5867
5867
|
selfHosted: false,
|
|
5868
|
-
|
|
5868
|
+
specialty: TYPE,
|
|
5869
5869
|
createdAt: new Date("2024-01-01"),
|
|
5870
5870
|
updatedAt: new Date("2024-01-01"),
|
|
5871
5871
|
repos: ["my-org/my-repo"],
|
|
@@ -5881,7 +5881,7 @@ describe("admin UI — repos mutation routes", () => {
|
|
|
5881
5881
|
name: "Test Agent",
|
|
5882
5882
|
slackId: "U123456",
|
|
5883
5883
|
selfHosted: false,
|
|
5884
|
-
|
|
5884
|
+
specialty: TYPE,
|
|
5885
5885
|
createdAt: new Date("2024-01-01"),
|
|
5886
5886
|
updatedAt: new Date("2024-01-01"),
|
|
5887
5887
|
repos: capturedRepos ?? [],
|
|
@@ -6026,7 +6026,7 @@ describe("admin UI — author allowlist mutation routes", () => {
|
|
|
6026
6026
|
name: "Test Agent",
|
|
6027
6027
|
slackId: "U123456",
|
|
6028
6028
|
selfHosted: false,
|
|
6029
|
-
|
|
6029
|
+
specialty: TYPE,
|
|
6030
6030
|
createdAt: new Date("2024-01-01"),
|
|
6031
6031
|
updatedAt: new Date("2024-01-01"),
|
|
6032
6032
|
repos: [],
|
|
@@ -6045,7 +6045,7 @@ describe("admin UI — author allowlist mutation routes", () => {
|
|
|
6045
6045
|
name: "Test Agent",
|
|
6046
6046
|
slackId: "U123456",
|
|
6047
6047
|
selfHosted: false,
|
|
6048
|
-
|
|
6048
|
+
specialty: TYPE,
|
|
6049
6049
|
createdAt: new Date("2024-01-01"),
|
|
6050
6050
|
updatedAt: new Date("2024-01-01"),
|
|
6051
6051
|
repos: [],
|
|
@@ -6087,7 +6087,7 @@ describe("admin UI — author allowlist mutation routes", () => {
|
|
|
6087
6087
|
name: "Test Agent",
|
|
6088
6088
|
slackId: "U123456",
|
|
6089
6089
|
selfHosted: false,
|
|
6090
|
-
|
|
6090
|
+
specialty: TYPE,
|
|
6091
6091
|
createdAt: new Date("2024-01-01"),
|
|
6092
6092
|
updatedAt: new Date("2024-01-01"),
|
|
6093
6093
|
repos: [],
|
|
@@ -6103,7 +6103,7 @@ describe("admin UI — author allowlist mutation routes", () => {
|
|
|
6103
6103
|
name: "Test Agent",
|
|
6104
6104
|
slackId: "U123456",
|
|
6105
6105
|
selfHosted: false,
|
|
6106
|
-
|
|
6106
|
+
specialty: TYPE,
|
|
6107
6107
|
createdAt: new Date("2024-01-01"),
|
|
6108
6108
|
updatedAt: new Date("2024-01-01"),
|
|
6109
6109
|
repos: [],
|
|
@@ -6284,7 +6284,7 @@ describe("admin UI — patch author allowlist mutation routes", () => {
|
|
|
6284
6284
|
name: "Test Agent",
|
|
6285
6285
|
slackId: "U123456",
|
|
6286
6286
|
selfHosted: false,
|
|
6287
|
-
|
|
6287
|
+
specialty: TYPE,
|
|
6288
6288
|
createdAt: new Date("2024-01-01"),
|
|
6289
6289
|
updatedAt: new Date("2024-01-01"),
|
|
6290
6290
|
repos: [],
|
|
@@ -6303,7 +6303,7 @@ describe("admin UI — patch author allowlist mutation routes", () => {
|
|
|
6303
6303
|
name: "Test Agent",
|
|
6304
6304
|
slackId: "U123456",
|
|
6305
6305
|
selfHosted: false,
|
|
6306
|
-
|
|
6306
|
+
specialty: TYPE,
|
|
6307
6307
|
createdAt: new Date("2024-01-01"),
|
|
6308
6308
|
updatedAt: new Date("2024-01-01"),
|
|
6309
6309
|
repos: [],
|
|
@@ -6345,7 +6345,7 @@ describe("admin UI — patch author allowlist mutation routes", () => {
|
|
|
6345
6345
|
name: "Test Agent",
|
|
6346
6346
|
slackId: "U123456",
|
|
6347
6347
|
selfHosted: false,
|
|
6348
|
-
|
|
6348
|
+
specialty: TYPE,
|
|
6349
6349
|
createdAt: new Date("2024-01-01"),
|
|
6350
6350
|
updatedAt: new Date("2024-01-01"),
|
|
6351
6351
|
repos: [],
|
|
@@ -6361,7 +6361,7 @@ describe("admin UI — patch author allowlist mutation routes", () => {
|
|
|
6361
6361
|
name: "Test Agent",
|
|
6362
6362
|
slackId: "U123456",
|
|
6363
6363
|
selfHosted: false,
|
|
6364
|
-
|
|
6364
|
+
specialty: TYPE,
|
|
6365
6365
|
createdAt: new Date("2024-01-01"),
|
|
6366
6366
|
updatedAt: new Date("2024-01-01"),
|
|
6367
6367
|
repos: [],
|
|
@@ -6417,7 +6417,7 @@ describe("admin UI — patch author allowlist mutation routes", () => {
|
|
|
6417
6417
|
name: "Test Agent",
|
|
6418
6418
|
slackId: "U123456",
|
|
6419
6419
|
selfHosted: false,
|
|
6420
|
-
|
|
6420
|
+
specialty: TYPE,
|
|
6421
6421
|
createdAt: new Date("2024-01-01"),
|
|
6422
6422
|
updatedAt: new Date("2024-01-01"),
|
|
6423
6423
|
repos: [],
|
|
@@ -6433,7 +6433,7 @@ describe("admin UI — patch author allowlist mutation routes", () => {
|
|
|
6433
6433
|
name: "Test Agent",
|
|
6434
6434
|
slackId: "U123456",
|
|
6435
6435
|
selfHosted: false,
|
|
6436
|
-
|
|
6436
|
+
specialty: TYPE,
|
|
6437
6437
|
createdAt: new Date("2024-01-01"),
|
|
6438
6438
|
updatedAt: new Date("2024-01-01"),
|
|
6439
6439
|
repos: [],
|
|
@@ -6527,7 +6527,7 @@ describe("admin UI — Slack access settings route (restrictSlackToMembers)", ()
|
|
|
6527
6527
|
name: "Test Agent",
|
|
6528
6528
|
slackId: "U123456",
|
|
6529
6529
|
selfHosted: false,
|
|
6530
|
-
|
|
6530
|
+
specialty: TYPE,
|
|
6531
6531
|
createdAt: new Date("2024-01-01"),
|
|
6532
6532
|
updatedAt: new Date("2024-01-01"),
|
|
6533
6533
|
repos: [],
|
|
@@ -6569,7 +6569,7 @@ describe("admin UI — Slack access settings route (restrictSlackToMembers)", ()
|
|
|
6569
6569
|
name: "Test Agent",
|
|
6570
6570
|
slackId: "U123456",
|
|
6571
6571
|
selfHosted: false,
|
|
6572
|
-
|
|
6572
|
+
specialty: TYPE,
|
|
6573
6573
|
createdAt: new Date("2024-01-01"),
|
|
6574
6574
|
updatedAt: new Date("2024-01-01"),
|
|
6575
6575
|
repos: [],
|
|
@@ -6866,7 +6866,7 @@ describe("admin UI — Okta-authenticated access control", () => {
|
|
|
6866
6866
|
name: "My Okta Agent",
|
|
6867
6867
|
slackId: "U1",
|
|
6868
6868
|
selfHosted: false,
|
|
6869
|
-
|
|
6869
|
+
specialty: TYPE,
|
|
6870
6870
|
createdAt: new Date("2024-01-01"),
|
|
6871
6871
|
updatedAt: new Date("2024-01-01"),
|
|
6872
6872
|
},
|
|
@@ -6875,7 +6875,7 @@ describe("admin UI — Okta-authenticated access control", () => {
|
|
|
6875
6875
|
name: "Other Okta Agent",
|
|
6876
6876
|
slackId: "U2",
|
|
6877
6877
|
selfHosted: false,
|
|
6878
|
-
|
|
6878
|
+
specialty: TYPE,
|
|
6879
6879
|
createdAt: new Date("2024-01-01"),
|
|
6880
6880
|
updatedAt: new Date("2024-01-01"),
|
|
6881
6881
|
},
|
|
@@ -6887,7 +6887,7 @@ describe("admin UI — Okta-authenticated access control", () => {
|
|
|
6887
6887
|
name: "My Okta Agent",
|
|
6888
6888
|
slackId: "U1",
|
|
6889
6889
|
selfHosted: false,
|
|
6890
|
-
|
|
6890
|
+
specialty: TYPE,
|
|
6891
6891
|
createdAt: new Date("2024-01-01"),
|
|
6892
6892
|
updatedAt: new Date("2024-01-01"),
|
|
6893
6893
|
},
|
|
@@ -6896,7 +6896,7 @@ describe("admin UI — Okta-authenticated access control", () => {
|
|
|
6896
6896
|
name: "Other Okta Agent",
|
|
6897
6897
|
slackId: "U2",
|
|
6898
6898
|
selfHosted: false,
|
|
6899
|
-
|
|
6899
|
+
specialty: TYPE,
|
|
6900
6900
|
createdAt: new Date("2024-01-01"),
|
|
6901
6901
|
updatedAt: new Date("2024-01-01"),
|
|
6902
6902
|
},
|
package/src/admin-ui.ts
CHANGED
|
@@ -346,7 +346,7 @@ export interface AdminUIDeps {
|
|
|
346
346
|
/** WIF-2.1: Anthropic federation is enabled; defaults to false. */
|
|
347
347
|
anthropicFederationEnabled?: boolean;
|
|
348
348
|
/**
|
|
349
|
-
* Resolves an agent's
|
|
349
|
+
* Resolves an agent's specialty to its parsed Specialty manifest and lists
|
|
350
350
|
* the registry's discoverable types (for the new-specialty picker).
|
|
351
351
|
* Defaults to a disk-backed SpecialtyRegistry, matching the DI pattern
|
|
352
352
|
* already used by agents-api.ts's AdminDeps.
|
|
@@ -1449,7 +1449,7 @@ export function createAdminUIApp(deps: AdminUIDeps): Hono<AdminUIEnv> {
|
|
|
1449
1449
|
return new Response("Forbidden", { status: 403 });
|
|
1450
1450
|
}
|
|
1451
1451
|
let name: string | undefined;
|
|
1452
|
-
let
|
|
1452
|
+
let specialty: string | undefined;
|
|
1453
1453
|
let reposRaw: string | undefined;
|
|
1454
1454
|
let authorAllowlistRaw: string | undefined;
|
|
1455
1455
|
let patchAuthorAllowlistRaw: string | undefined;
|
|
@@ -1470,7 +1470,7 @@ export function createAdminUIApp(deps: AdminUIDeps): Hono<AdminUIEnv> {
|
|
|
1470
1470
|
try {
|
|
1471
1471
|
const formData = await c.req.formData();
|
|
1472
1472
|
name = formData.get("name")?.toString()?.trim();
|
|
1473
|
-
|
|
1473
|
+
specialty = formData.get("type")?.toString()?.trim();
|
|
1474
1474
|
reposRaw = formData.get("repos")?.toString()?.trim();
|
|
1475
1475
|
authorAllowlistRaw = formData.get("authorAllowlist")?.toString()?.trim();
|
|
1476
1476
|
patchAuthorAllowlistRaw = formData
|
|
@@ -1509,7 +1509,7 @@ export function createAdminUIApp(deps: AdminUIDeps): Hono<AdminUIEnv> {
|
|
|
1509
1509
|
const connectSlack = connectSlackRaw === "true";
|
|
1510
1510
|
// SSP-4.2: account users always create "coding" agents in their own
|
|
1511
1511
|
// account — any submitted type/accountId is ignored.
|
|
1512
|
-
if (accountId !== null)
|
|
1512
|
+
if (accountId !== null) specialty = getSelfServeSpecialty();
|
|
1513
1513
|
// Absent/unrecognized runtime means self-hosted — the historical behavior
|
|
1514
1514
|
// of this form. createAgent() below re-derives this same value itself
|
|
1515
1515
|
// (it owns the runtime/provisioning validation); it's recomputed here
|
|
@@ -1518,7 +1518,7 @@ export function createAdminUIApp(deps: AdminUIDeps): Hono<AdminUIEnv> {
|
|
|
1518
1518
|
// whether this agent is in-cluster.
|
|
1519
1519
|
const inCluster = runtime === "in-cluster";
|
|
1520
1520
|
|
|
1521
|
-
// APA-1.1: the entire create-agent sequence (validate name/
|
|
1521
|
+
// APA-1.1: the entire create-agent sequence (validate name/specialty,
|
|
1522
1522
|
// create the Agent row, seed AgentTool/AgentPlugin from the type
|
|
1523
1523
|
// manifest, attach repos/allowlists/members, patch Claude credentials,
|
|
1524
1524
|
// provision Kubernetes when requested, best-effort reconcile system
|
|
@@ -1561,7 +1561,7 @@ export function createAdminUIApp(deps: AdminUIDeps): Hono<AdminUIEnv> {
|
|
|
1561
1561
|
},
|
|
1562
1562
|
{
|
|
1563
1563
|
name,
|
|
1564
|
-
|
|
1564
|
+
specialty,
|
|
1565
1565
|
runtime,
|
|
1566
1566
|
reposRaw,
|
|
1567
1567
|
authorAllowlistRaw,
|
|
@@ -1736,7 +1736,7 @@ export function createAdminUIApp(deps: AdminUIDeps): Hono<AdminUIEnv> {
|
|
|
1736
1736
|
authorAllowlist: agent.reviewAuthorAllowlist,
|
|
1737
1737
|
patchAuthorAllowlist: agent.patchAuthorAllowlist,
|
|
1738
1738
|
restrictSlackToMembers: agent.restrictSlackToMembers,
|
|
1739
|
-
|
|
1739
|
+
specialty: agent.specialty,
|
|
1740
1740
|
missingRequiredEnv: agent.missingRequiredEnv,
|
|
1741
1741
|
autoPostReviews: agent.autoPostReviews ?? true,
|
|
1742
1742
|
allowSelfReview: agent.allowSelfReview ?? false,
|
|
@@ -2425,7 +2425,7 @@ export function createAdminUIApp(deps: AdminUIDeps): Hono<AdminUIEnv> {
|
|
|
2425
2425
|
authorAllowlist: agent.reviewAuthorAllowlist,
|
|
2426
2426
|
patchAuthorAllowlist: agent.patchAuthorAllowlist,
|
|
2427
2427
|
restrictSlackToMembers: agent.restrictSlackToMembers,
|
|
2428
|
-
|
|
2428
|
+
specialty: agent.specialty,
|
|
2429
2429
|
missingRequiredEnv: agent.missingRequiredEnv,
|
|
2430
2430
|
autoPostReviews: agent.autoPostReviews ?? true,
|
|
2431
2431
|
allowSelfReview: agent.allowSelfReview ?? false,
|