@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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* admin/src/specialty-manifest-loader.unit.test.ts
|
|
3
3
|
* Unit tests for SpecialtyRegistry — the disk-backed resolver from an agent's
|
|
4
|
-
*
|
|
4
|
+
* specialty to its parsed manifest, with the unknown-type "coding" fallback.
|
|
5
5
|
*
|
|
6
6
|
* Pure logic against an injected reader/warner — no filesystem, no DB. See
|
|
7
7
|
* docs/testing.md for the unit-layer contract.
|
|
@@ -44,7 +44,7 @@ voice: true
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
describe("SpecialtyRegistry", () => {
|
|
47
|
-
it("resolves a known
|
|
47
|
+
it("resolves a known specialty to its parsed manifest", () => {
|
|
48
48
|
const registry = new SpecialtyRegistry({
|
|
49
49
|
defaultTypeName: DEFAULT_SPECIALTY_NAME,
|
|
50
50
|
read: (t) => manifestYaml(t),
|
|
@@ -54,7 +54,7 @@ describe("SpecialtyRegistry", () => {
|
|
|
54
54
|
expect(manifest.crons[0]?.name).toBe("coding-cron");
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
it("falls back to the coding manifest with a warning for an unknown
|
|
57
|
+
it("falls back to the coding manifest with a warning for an unknown specialty", () => {
|
|
58
58
|
const warnings: string[] = [];
|
|
59
59
|
const registry = new SpecialtyRegistry({
|
|
60
60
|
defaultTypeName: DEFAULT_SPECIALTY_NAME,
|
|
@@ -97,10 +97,10 @@ describe("SpecialtyRegistry", () => {
|
|
|
97
97
|
defaultTypeName: "absent",
|
|
98
98
|
});
|
|
99
99
|
|
|
100
|
-
for (const
|
|
100
|
+
for (const specialty of ["absent", "some-other-type"]) {
|
|
101
101
|
let message = "";
|
|
102
102
|
try {
|
|
103
|
-
registry.getManifest(
|
|
103
|
+
registry.getManifest(specialty);
|
|
104
104
|
} catch (err) {
|
|
105
105
|
message = (err as Error).message;
|
|
106
106
|
}
|
|
@@ -131,12 +131,12 @@ describe("SpecialtyRegistry", () => {
|
|
|
131
131
|
// ─── tryGetManifest — non-fallback lookup ────────────────────────────────
|
|
132
132
|
//
|
|
133
133
|
// Unlike getManifest(), tryGetManifest() must NOT fall back to "coding" for
|
|
134
|
-
// an unknown
|
|
134
|
+
// an unknown specialty — it returns undefined instead. This is what lets
|
|
135
135
|
// POST /agents distinguish "resolved to the exact requested type" from
|
|
136
136
|
// "silently degraded", which the cron-reconcile boot path (getManifest())
|
|
137
137
|
// deliberately does not need to distinguish.
|
|
138
138
|
|
|
139
|
-
it("tryGetManifest resolves a known
|
|
139
|
+
it("tryGetManifest resolves a known specialty to its parsed manifest", () => {
|
|
140
140
|
const registry = new SpecialtyRegistry({
|
|
141
141
|
defaultTypeName: DEFAULT_SPECIALTY_NAME,
|
|
142
142
|
read: (t) => manifestYaml(t),
|
|
@@ -145,7 +145,7 @@ describe("SpecialtyRegistry", () => {
|
|
|
145
145
|
expect(manifest?.metadata.name).toBe("coding");
|
|
146
146
|
});
|
|
147
147
|
|
|
148
|
-
it("tryGetManifest returns undefined for an unknown
|
|
148
|
+
it("tryGetManifest returns undefined for an unknown specialty — no fallback, no warning", () => {
|
|
149
149
|
const warnings: string[] = [];
|
|
150
150
|
const registry = new SpecialtyRegistry({
|
|
151
151
|
defaultTypeName: DEFAULT_SPECIALTY_NAME,
|
package/src/agent-specialty.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AGR-6.1: typeName -> specialty rename, ADD step. `Agent.specialty` is a
|
|
3
|
-
* nullable column written alongside `typeName`; reads prefer it and fall back
|
|
4
|
-
* to `typeName` for rows that predate the column. Nothing is retired yet.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
export interface SpecialtyBearingRow {
|
|
8
|
-
typeName: string;
|
|
9
|
-
specialty?: string | null;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/** The agent's specialty: the new column when set, else the legacy `typeName`. */
|
|
13
|
-
export function resolveSpecialty(row: SpecialtyBearingRow): string {
|
|
14
|
-
return row.specialty ?? row.typeName;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/** Returns the row with `specialty` resolved to a non-null string. */
|
|
18
|
-
export function withResolvedSpecialty<T extends SpecialtyBearingRow>(
|
|
19
|
-
row: T,
|
|
20
|
-
): Omit<T, "specialty"> & { specialty: string } {
|
|
21
|
-
return { ...row, specialty: resolveSpecialty(row) };
|
|
22
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit tests for the AGR-6.1 specialty mapper (typeName -> specialty ADD step).
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { describe, expect, it } from "bun:test";
|
|
6
|
-
import { resolveSpecialty, withResolvedSpecialty } from "./agent-specialty.ts";
|
|
7
|
-
|
|
8
|
-
describe("resolveSpecialty", () => {
|
|
9
|
-
it("prefers specialty when set", () => {
|
|
10
|
-
expect(
|
|
11
|
-
resolveSpecialty({ typeName: "coding", specialty: "research" }),
|
|
12
|
-
).toBe("research");
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("falls back to typeName when specialty is null", () => {
|
|
16
|
-
expect(resolveSpecialty({ typeName: "coding", specialty: null })).toBe(
|
|
17
|
-
"coding",
|
|
18
|
-
);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it("falls back to typeName when specialty is absent", () => {
|
|
22
|
-
expect(resolveSpecialty({ typeName: "coding" })).toBe("coding");
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("does not treat an empty-string specialty as unset", () => {
|
|
26
|
-
expect(resolveSpecialty({ typeName: "coding", specialty: "" })).toBe("");
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
describe("withResolvedSpecialty", () => {
|
|
31
|
-
it("returns a copy with specialty resolved and typeName preserved", () => {
|
|
32
|
-
const row = { id: "a1", typeName: "coding", specialty: null };
|
|
33
|
-
const out = withResolvedSpecialty(row);
|
|
34
|
-
expect(out).toEqual({ id: "a1", typeName: "coding", specialty: "coding" });
|
|
35
|
-
expect(row.specialty).toBeNull();
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it("keeps an explicit specialty", () => {
|
|
39
|
-
expect(
|
|
40
|
-
withResolvedSpecialty({ typeName: "coding", specialty: "research" }),
|
|
41
|
-
).toEqual({ typeName: "coding", specialty: "research" });
|
|
42
|
-
});
|
|
43
|
-
});
|