@kindgi/api 0.1.4-rc.0 → 0.1.4-rc.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/dist/agent-binding.d.ts +8 -0
- package/dist/agent-binding.d.ts.map +1 -1
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +7 -1
- package/dist/app.js.map +1 -1
- package/dist/deploy-versions.d.ts +2 -0
- package/dist/deploy-versions.d.ts.map +1 -1
- package/dist/deploy-versions.js +1 -1
- package/dist/deploy-versions.js.map +1 -1
- package/dist/derive-agent-version.d.ts +9 -1
- package/dist/derive-agent-version.d.ts.map +1 -1
- package/dist/derive-agent-version.js +11 -1
- package/dist/derive-agent-version.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +1 -0
- package/dist/errors.js.map +1 -1
- package/dist/eval-run-binding.d.ts +7 -0
- package/dist/eval-run-binding.d.ts.map +1 -1
- package/dist/eval-run-binding.js.map +1 -1
- package/dist/eval-run-dispatcher.d.ts +3 -0
- package/dist/eval-run-dispatcher.d.ts.map +1 -1
- package/dist/eval-run-dispatcher.js.map +1 -1
- package/dist/flow-binding.d.ts +8 -0
- package/dist/flow-binding.d.ts.map +1 -1
- package/dist/guardrail-binding.d.ts +8 -0
- package/dist/guardrail-binding.d.ts.map +1 -1
- package/dist/handler-binding.d.ts +3 -0
- package/dist/handler-binding.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/judged-dispatcher.d.ts +4 -0
- package/dist/judged-dispatcher.d.ts.map +1 -1
- package/dist/judged-dispatcher.js +14 -3
- package/dist/judged-dispatcher.js.map +1 -1
- package/dist/openapi/operations.d.ts.map +1 -1
- package/dist/openapi/operations.js +21 -6
- package/dist/openapi/operations.js.map +1 -1
- package/dist/openapi/schemas.d.ts +6 -0
- package/dist/openapi/schemas.d.ts.map +1 -1
- package/dist/openapi/schemas.js +341 -2
- package/dist/openapi/schemas.js.map +1 -1
- package/dist/registry-read-only.d.ts +32 -0
- package/dist/registry-read-only.d.ts.map +1 -0
- package/dist/registry-read-only.js +22 -0
- package/dist/registry-read-only.js.map +1 -0
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +7 -1
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/blocks.d.ts.map +1 -1
- package/dist/routes/blocks.js +37 -12
- package/dist/routes/blocks.js.map +1 -1
- package/dist/routes/deployments.d.ts.map +1 -1
- package/dist/routes/deployments.js +16 -0
- package/dist/routes/deployments.js.map +1 -1
- package/dist/routes/eval-comparison.d.ts +3 -2
- package/dist/routes/eval-comparison.d.ts.map +1 -1
- package/dist/routes/eval-comparison.js +39 -3
- package/dist/routes/eval-comparison.js.map +1 -1
- package/dist/routes/eval-runs.d.ts +7 -1
- package/dist/routes/eval-runs.d.ts.map +1 -1
- package/dist/routes/eval-runs.js +34 -3
- package/dist/routes/eval-runs.js.map +1 -1
- package/dist/routes/eval-versions.d.ts +25 -0
- package/dist/routes/eval-versions.d.ts.map +1 -0
- package/dist/routes/eval-versions.js +66 -0
- package/dist/routes/eval-versions.js.map +1 -0
- package/dist/routes/flows.d.ts.map +1 -1
- package/dist/routes/flows.js +4 -0
- package/dist/routes/flows.js.map +1 -1
- package/dist/routes/guardrails.d.ts.map +1 -1
- package/dist/routes/guardrails.js +4 -0
- package/dist/routes/guardrails.js.map +1 -1
- package/dist/routes/hierarchy-errors.d.ts +10 -0
- package/dist/routes/hierarchy-errors.d.ts.map +1 -1
- package/dist/routes/hierarchy-errors.js +8 -0
- package/dist/routes/hierarchy-errors.js.map +1 -1
- package/dist/routes/projects.d.ts.map +1 -1
- package/dist/routes/projects.js +13 -7
- package/dist/routes/projects.js.map +1 -1
- package/dist/routes/runs.js +1 -0
- package/dist/routes/runs.js.map +1 -1
- package/dist/routes/teams.d.ts.map +1 -1
- package/dist/routes/teams.js +12 -6
- package/dist/routes/teams.js.map +1 -1
- package/dist/routes/tools.d.ts.map +1 -1
- package/dist/routes/tools.js +4 -0
- package/dist/routes/tools.js.map +1 -1
- package/dist/tool-binding.d.ts +8 -0
- package/dist/tool-binding.d.ts.map +1 -1
- package/openapi.json +729 -17
- package/package.json +21 -21
- package/src/agent-binding.ts +9 -0
- package/src/app.ts +10 -1
- package/src/deploy-versions.ts +1 -1
- package/src/derive-agent-version.ts +12 -1
- package/src/errors.ts +1 -0
- package/src/eval-run-binding.ts +7 -0
- package/src/eval-run-dispatcher.ts +3 -0
- package/src/flow-binding.ts +9 -0
- package/src/guardrail-binding.ts +9 -0
- package/src/handler-binding.ts +3 -0
- package/src/index.ts +1 -0
- package/src/judged-dispatcher.ts +27 -4
- package/src/openapi/operations.ts +56 -6
- package/src/openapi/schemas.ts +361 -2
- package/src/registry-read-only.ts +43 -0
- package/src/routes/agents.ts +10 -1
- package/src/routes/blocks.ts +39 -14
- package/src/routes/deployments.ts +25 -0
- package/src/routes/eval-comparison.ts +37 -3
- package/src/routes/eval-runs.ts +46 -3
- package/src/routes/eval-versions.ts +110 -0
- package/src/routes/flows.ts +7 -0
- package/src/routes/guardrails.ts +7 -0
- package/src/routes/hierarchy-errors.ts +9 -0
- package/src/routes/projects.ts +18 -7
- package/src/routes/runs.ts +1 -0
- package/src/routes/teams.ts +14 -6
- package/src/routes/tools.ts +7 -0
- package/src/tool-binding.ts +9 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kindgi/api",
|
|
3
|
-
"version": "0.1.4-rc.
|
|
3
|
+
"version": "0.1.4-rc.1",
|
|
4
4
|
"description": "REST + SSE HTTP surface for Kindgi™. createApp assembles a Hono app serving the /v1/* REST API (bearer or session-token auth; OpenAPI 3.1 document at /v1/openapi.json) and an optional S3-compatible /s3/* surface (SigV4), over caller-plugged bindings for the runtime (runs, agents, flows, HITL, supervisor) and for storage. Route conventions: docs/API-ROUTE-CONVENTIONS.md.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -32,30 +32,30 @@
|
|
|
32
32
|
"openapi.json"
|
|
33
33
|
],
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@kindgi/agents": "0.1.4-rc.
|
|
36
|
-
"@kindgi/audit-events": "0.1.4-rc.
|
|
37
|
-
"@kindgi/compliance": "0.1.4-rc.
|
|
38
|
-
"@kindgi/authz": "0.1.4-rc.
|
|
39
|
-
"@kindgi/blob-binding": "0.1.4-rc.
|
|
40
|
-
"@kindgi/capabilities": "0.1.4-rc.
|
|
41
|
-
"@kindgi/crypto": "0.1.4-rc.
|
|
42
|
-
"@kindgi/flow": "0.1.4-rc.
|
|
43
|
-
"@kindgi/guardrails": "0.1.4-rc.
|
|
44
|
-
"@kindgi/memory": "0.1.4-rc.
|
|
45
|
-
"@kindgi/platform": "0.1.4-rc.
|
|
46
|
-
"@kindgi/provenance": "0.1.4-rc.
|
|
47
|
-
"@kindgi/runtime": "0.1.4-rc.
|
|
48
|
-
"@kindgi/policy-contract": "0.1.4-rc.
|
|
49
|
-
"@kindgi/schema": "0.1.4-rc.
|
|
50
|
-
"@kindgi/tools": "0.1.4-rc.
|
|
51
|
-
"@kindgi/types": "0.1.4-rc.
|
|
35
|
+
"@kindgi/agents": "0.1.4-rc.1",
|
|
36
|
+
"@kindgi/audit-events": "0.1.4-rc.1",
|
|
37
|
+
"@kindgi/compliance": "0.1.4-rc.1",
|
|
38
|
+
"@kindgi/authz": "0.1.4-rc.1",
|
|
39
|
+
"@kindgi/blob-binding": "0.1.4-rc.1",
|
|
40
|
+
"@kindgi/capabilities": "0.1.4-rc.1",
|
|
41
|
+
"@kindgi/crypto": "0.1.4-rc.1",
|
|
42
|
+
"@kindgi/flow": "0.1.4-rc.1",
|
|
43
|
+
"@kindgi/guardrails": "0.1.4-rc.1",
|
|
44
|
+
"@kindgi/memory": "0.1.4-rc.1",
|
|
45
|
+
"@kindgi/platform": "0.1.4-rc.1",
|
|
46
|
+
"@kindgi/provenance": "0.1.4-rc.1",
|
|
47
|
+
"@kindgi/runtime": "0.1.4-rc.1",
|
|
48
|
+
"@kindgi/policy-contract": "0.1.4-rc.1",
|
|
49
|
+
"@kindgi/schema": "0.1.4-rc.1",
|
|
50
|
+
"@kindgi/tools": "0.1.4-rc.1",
|
|
51
|
+
"@kindgi/types": "0.1.4-rc.1",
|
|
52
52
|
"@scalar/hono-api-reference": "^0.12.2",
|
|
53
53
|
"hono": "^4.6.14"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@kindgi/audit-events-inmemory": "0.1.4-rc.
|
|
57
|
-
"@kindgi/specs": "0.1.4-rc.
|
|
58
|
-
"@kindgi/testing": "0.1.4-rc.
|
|
56
|
+
"@kindgi/audit-events-inmemory": "0.1.4-rc.1",
|
|
57
|
+
"@kindgi/specs": "0.1.4-rc.1",
|
|
58
|
+
"@kindgi/testing": "0.1.4-rc.1",
|
|
59
59
|
"@types/aws4": "^1.11.6",
|
|
60
60
|
"@types/node": "^22.10.5",
|
|
61
61
|
"aws4": "^1.13.2",
|
package/src/agent-binding.ts
CHANGED
|
@@ -6,6 +6,8 @@ import type { TupleEnqueueHook } from '@kindgi/authz';
|
|
|
6
6
|
import type { Scope } from '@kindgi/platform';
|
|
7
7
|
import type { Cursor, ProjectId, Semver, TenantId } from '@kindgi/types';
|
|
8
8
|
|
|
9
|
+
import type { RegistryReadOnly } from './registry-read-only.js';
|
|
10
|
+
|
|
9
11
|
/**
|
|
10
12
|
* Caller-plugged surface for the agent catalog. Same shape as
|
|
11
13
|
* `TokenAdmin` / `ReviewerBinding` / `RunHandlerBinding`: the API
|
|
@@ -22,6 +24,13 @@ import type { Cursor, ProjectId, Semver, TenantId } from '@kindgi/types';
|
|
|
22
24
|
* cursor round-trips as a string; it never inspects the payload.
|
|
23
25
|
*/
|
|
24
26
|
export interface AgentRegistryBinding {
|
|
27
|
+
/**
|
|
28
|
+
* Set when this registry takes no writes (under `kindgi dev`, the
|
|
29
|
+
* pack's files are the source of its agents): every write is refused
|
|
30
|
+
* with `409 registry-read-only` and this reason, before the binding is
|
|
31
|
+
* called. See `RegistryReadOnly`.
|
|
32
|
+
*/
|
|
33
|
+
readonly readOnly?: RegistryReadOnly;
|
|
25
34
|
/**
|
|
26
35
|
* Cursor-paginated list of agents (latest version per id, sorted by
|
|
27
36
|
* agent id ascending). Optional `nameFilter` is a prefix match on the
|
package/src/app.ts
CHANGED
|
@@ -1289,7 +1289,16 @@ export function createApp(input: CreateAppInput): Hono<AppEnv> {
|
|
|
1289
1289
|
// `evalSuiteRegistry` binding: the dispatcher itself surfaces
|
|
1290
1290
|
// `suite-not-found` when the caller-plugged binding can't resolve
|
|
1291
1291
|
// the suite id, so the API layer stays consumer-neutral.
|
|
1292
|
-
const evalRuns = evalRunsRouters(
|
|
1292
|
+
const evalRuns = evalRunsRouters(
|
|
1293
|
+
input.evalRunBinding,
|
|
1294
|
+
input.flowRegistry !== undefined
|
|
1295
|
+
? {
|
|
1296
|
+
flows: input.flowRegistry,
|
|
1297
|
+
...(input.agentRegistry !== undefined && { agents: input.agentRegistry }),
|
|
1298
|
+
...(input.toolRegistry !== undefined && { tools: input.toolRegistry }),
|
|
1299
|
+
}
|
|
1300
|
+
: undefined,
|
|
1301
|
+
);
|
|
1293
1302
|
v1.route('/eval-suites', evalRuns.start);
|
|
1294
1303
|
v1.route('/eval-runs', evalRuns.readback);
|
|
1295
1304
|
}
|
package/src/deploy-versions.ts
CHANGED
|
@@ -151,7 +151,7 @@ async function registerNextFree<T extends PinnedDefinition>(
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
/** A definition: everything but its version and what the runtime sets. */
|
|
154
|
-
function definitionKey(definition: PinnedDefinition): string {
|
|
154
|
+
export function definitionKey(definition: PinnedDefinition): string {
|
|
155
155
|
const { version: _v, pins: _p, pinsDigest: _d, derivedFrom: _f, ...rest } = definition;
|
|
156
156
|
return canonicalize(rest);
|
|
157
157
|
}
|
|
@@ -16,6 +16,7 @@ import type { ProjectId, Semver, TenantId } from '@kindgi/types';
|
|
|
16
16
|
import type { AgentRegistryBinding, AgentVersionRecord } from './agent-binding.js';
|
|
17
17
|
import { activeAgentVersions } from './agent-pins.js';
|
|
18
18
|
import type { BlockRegistryBinding } from './block-binding.js';
|
|
19
|
+
import { definitionKey } from './deploy-versions.js';
|
|
19
20
|
|
|
20
21
|
/** Which data-block pins to swap, by kind then block id → exact version. */
|
|
21
22
|
export interface PinSwaps {
|
|
@@ -48,6 +49,8 @@ export interface SwapIssue {
|
|
|
48
49
|
|
|
49
50
|
export type DeriveAgentVersionOutcome =
|
|
50
51
|
| { readonly kind: 'ok'; readonly agent: Agent }
|
|
52
|
+
/** An active version already has this definition and these pins: that one, unchanged. */
|
|
53
|
+
| { readonly kind: 'reused'; readonly agent: Agent }
|
|
51
54
|
| { readonly kind: 'not-found' }
|
|
52
55
|
| { readonly kind: 'unpinned' }
|
|
53
56
|
| { readonly kind: 'invalid'; readonly issues: readonly SwapIssue[] }
|
|
@@ -63,7 +66,10 @@ const MAX_TRIES = 100;
|
|
|
63
66
|
* reaching an agent without a code change. The new version is the old
|
|
64
67
|
* one's bag with those pins swapped (`derivedFrom: { version, reason:
|
|
65
68
|
* 'edited', label, by }`), numbered the next free patch after the
|
|
66
|
-
* agent's highest version (versions never change).
|
|
69
|
+
* agent's highest version (versions never change). If an active version
|
|
70
|
+
* already holds that definition and those pins (the same swap derived
|
|
71
|
+
* before, or a deploy that registered it), that version is returned
|
|
72
|
+
* unchanged (`reused`) rather than a duplicate.
|
|
67
73
|
*
|
|
68
74
|
* Only data-block pins swap: a swap must name a block the version
|
|
69
75
|
* already references (adding one is a code change), at a published,
|
|
@@ -114,6 +120,11 @@ async function publishNextFree(
|
|
|
114
120
|
): Promise<DeriveAgentVersionOutcome> {
|
|
115
121
|
const { agents, tenantId, agentId } = input;
|
|
116
122
|
const active = await activeAgentVersions(agents, tenantId, agentId);
|
|
123
|
+
// The same swap again (or a deploy that registered it) finds the
|
|
124
|
+
// version that already holds it: versions are never duplicated.
|
|
125
|
+
const key = definitionKey(derived);
|
|
126
|
+
const same = active.find((a) => a.pinsDigest === derived.pinsDigest && definitionKey(a) === key);
|
|
127
|
+
if (same !== undefined) return { kind: 'reused', agent: same };
|
|
117
128
|
const highest =
|
|
118
129
|
latestVersion(active.map((a) => a.version as unknown as string)) ??
|
|
119
130
|
(derived.version as unknown as string);
|
package/src/errors.ts
CHANGED
|
@@ -67,6 +67,7 @@ export const ERROR_CODE_TO_STATUS: Readonly<Record<string, number>> = {
|
|
|
67
67
|
'duplicate-edge-id': 409,
|
|
68
68
|
'agent-version-mismatch': 409,
|
|
69
69
|
'agent-already-registered': 409,
|
|
70
|
+
'registry-read-only': 409,
|
|
70
71
|
'agent-gone': 410,
|
|
71
72
|
'flow-gone': 410,
|
|
72
73
|
'policy-gone': 410,
|
package/src/eval-run-binding.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Copyright (C) 2026 Kindgi Inc.
|
|
3
3
|
|
|
4
4
|
import type { AgentId } from '@kindgi/agents';
|
|
5
|
+
import type { FlowVersionOverrides } from '@kindgi/flow';
|
|
5
6
|
import type { Scope } from '@kindgi/platform';
|
|
6
7
|
import type { Cursor, FlowId, ProjectId, RunId, Semver, TenantId, Timestamp } from '@kindgi/types';
|
|
7
8
|
|
|
@@ -145,6 +146,12 @@ export interface EvalComparison {
|
|
|
145
146
|
readonly repetitions: number;
|
|
146
147
|
/** How many ranked items `weightedPrecisionAtK` looks at (1–100). */
|
|
147
148
|
readonly k: number;
|
|
149
|
+
/**
|
|
150
|
+
* For a flow candidate: agents and tools its replays run at other exact
|
|
151
|
+
* versions than the flow version's pins ("this flow, with `acme.scorer`
|
|
152
|
+
* at 0.4.0"), without publishing a new flow version.
|
|
153
|
+
*/
|
|
154
|
+
readonly versions?: FlowVersionOverrides;
|
|
148
155
|
}
|
|
149
156
|
|
|
150
157
|
export interface EvalRunStartInput {
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
5
5
|
|
|
6
6
|
import type { ReplayTurnReport } from '@kindgi/agents';
|
|
7
|
+
import type { FlowVersionOverrides } from '@kindgi/flow';
|
|
7
8
|
import type { RunReplayRef } from '@kindgi/runtime';
|
|
8
9
|
import type { ProjectId, RunId, TenantId, Timestamp } from '@kindgi/types';
|
|
9
10
|
|
|
@@ -63,6 +64,8 @@ export interface EvalRunSubjectInvokeInput {
|
|
|
63
64
|
readonly replay?: RunReplayRef;
|
|
64
65
|
/** The conversation before the past turn, oldest first: a replayed turn starts from it. */
|
|
65
66
|
readonly history?: readonly unknown[];
|
|
67
|
+
/** A flow target's agents and tools at other exact versions (`EvalComparison.versions`). */
|
|
68
|
+
readonly versions?: FlowVersionOverrides;
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
export interface EvalRunSubjectInvokeOutcome {
|
package/src/flow-binding.ts
CHANGED
|
@@ -6,6 +6,8 @@ import type { Flow } from '@kindgi/flow';
|
|
|
6
6
|
import type { Scope } from '@kindgi/platform';
|
|
7
7
|
import type { Cursor, FlowId, ProjectId, TenantId } from '@kindgi/types';
|
|
8
8
|
|
|
9
|
+
import type { RegistryReadOnly } from './registry-read-only.js';
|
|
10
|
+
|
|
9
11
|
/**
|
|
10
12
|
* Caller-plugged surface for the flow catalog. Mirrors
|
|
11
13
|
* `AgentRegistryBinding` 1:1 — the API package does NOT own registry
|
|
@@ -26,6 +28,13 @@ import type { Cursor, FlowId, ProjectId, TenantId } from '@kindgi/types';
|
|
|
26
28
|
* cursor round-trips as a string; it never inspects the payload.
|
|
27
29
|
*/
|
|
28
30
|
export interface FlowRegistryBinding {
|
|
31
|
+
/**
|
|
32
|
+
* Set when this registry takes no writes (under `kindgi dev`, the
|
|
33
|
+
* pack's files are the source of its flows): every write is refused
|
|
34
|
+
* with `409 registry-read-only` and this reason, before the binding is
|
|
35
|
+
* called. See `RegistryReadOnly`.
|
|
36
|
+
*/
|
|
37
|
+
readonly readOnly?: RegistryReadOnly;
|
|
29
38
|
/**
|
|
30
39
|
* Cursor-paginated list of flows (latest version per id, sorted by
|
|
31
40
|
* flow id ascending). Optional `nameFilter` is a prefix match on the
|
package/src/guardrail-binding.ts
CHANGED
|
@@ -6,6 +6,8 @@ import type { Guardrail } from '@kindgi/guardrails';
|
|
|
6
6
|
import type { Scope } from '@kindgi/platform';
|
|
7
7
|
import type { Cursor, GuardrailId, ProjectId, TenantId } from '@kindgi/types';
|
|
8
8
|
|
|
9
|
+
import type { RegistryReadOnly } from './registry-read-only.js';
|
|
10
|
+
|
|
9
11
|
/**
|
|
10
12
|
* Caller-plugged surface for the guardrail catalog. Same shape as
|
|
11
13
|
* `AgentRegistryBinding` / `ToolRegistryBinding`: the API package does
|
|
@@ -27,6 +29,13 @@ import type { Cursor, GuardrailId, ProjectId, TenantId } from '@kindgi/types';
|
|
|
27
29
|
* inspects the payload.
|
|
28
30
|
*/
|
|
29
31
|
export interface GuardrailRegistryBinding {
|
|
32
|
+
/**
|
|
33
|
+
* Set when this registry takes no writes (under `kindgi dev`, the
|
|
34
|
+
* pack's files are the source of its guardrails): every write is refused
|
|
35
|
+
* with `409 registry-read-only` and this reason, before the binding is
|
|
36
|
+
* called. See `RegistryReadOnly`.
|
|
37
|
+
*/
|
|
38
|
+
readonly readOnly?: RegistryReadOnly;
|
|
30
39
|
/**
|
|
31
40
|
* Cursor-paginated list of guardrails sorted by id ascending.
|
|
32
41
|
* Optional `nameFilter` is a prefix match on the guardrail id —
|
package/src/handler-binding.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Copyright (C) 2026 Kindgi Inc.
|
|
3
3
|
|
|
4
4
|
import type { AgentId } from '@kindgi/agents';
|
|
5
|
+
import type { FlowVersionOverrides } from '@kindgi/flow';
|
|
5
6
|
import type { FlowId, ProjectId, RunId, Semver, TenantId } from '@kindgi/types';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -107,6 +108,8 @@ export interface InvokeFlowBindingInput {
|
|
|
107
108
|
* can't run in the background may treat `false` like `true`.
|
|
108
109
|
*/
|
|
109
110
|
readonly wait?: boolean;
|
|
111
|
+
/** Agents and tools to run at other exact versions than the flow version's pins (`RunFlowInput.versions`). */
|
|
112
|
+
readonly versions?: FlowVersionOverrides;
|
|
110
113
|
}
|
|
111
114
|
|
|
112
115
|
export type RunHandlerOutcome =
|
package/src/index.ts
CHANGED
package/src/judged-dispatcher.ts
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import type { ReplayTurnReport } from '@kindgi/agents';
|
|
19
|
+
import type { FlowVersionOverrides } from '@kindgi/flow';
|
|
19
20
|
import type { RunId } from '@kindgi/types';
|
|
20
21
|
|
|
21
22
|
import type { EvalCaseStoreBinding, JudgedEvalCase } from './eval-case-binding.js';
|
|
@@ -81,7 +82,13 @@ export type RecordedVersion =
|
|
|
81
82
|
/** What ran on the cases: an agent version, or a flow version. */
|
|
82
83
|
export type ComparisonCandidate =
|
|
83
84
|
| { readonly kind: 'agent'; readonly agentId: string; readonly version: string }
|
|
84
|
-
| {
|
|
85
|
+
| {
|
|
86
|
+
readonly kind: 'flow';
|
|
87
|
+
readonly flowId: string;
|
|
88
|
+
readonly version: string;
|
|
89
|
+
/** Agents and tools its replays ran at other versions than the flow version's pins. */
|
|
90
|
+
readonly versions?: FlowVersionOverrides;
|
|
91
|
+
};
|
|
85
92
|
|
|
86
93
|
/** What a comparison eval run concluded: what a promotion gate reads. */
|
|
87
94
|
export interface JudgedComparisonSummary {
|
|
@@ -150,6 +157,9 @@ export interface JudgedDispatcherOptions {
|
|
|
150
157
|
/** Cases read per page. */
|
|
151
158
|
const CASE_PAGE = 100;
|
|
152
159
|
|
|
160
|
+
export const VERSIONS_NEED_A_FLOW =
|
|
161
|
+
'`versions` runs a flow with some of its agents or tools at other versions: it needs `flowRef`.';
|
|
162
|
+
|
|
153
163
|
function validateComparison(
|
|
154
164
|
suite: { readonly spec: Readonly<Record<string, unknown>> },
|
|
155
165
|
target: AgentRef | FlowRef,
|
|
@@ -168,6 +178,9 @@ function validateComparison(
|
|
|
168
178
|
return { kind: 'err', message: 'The test set has no cases.' };
|
|
169
179
|
}
|
|
170
180
|
const c = comparison ?? DEFAULT_COMPARISON;
|
|
181
|
+
if (c.versions !== undefined && 'agentId' in target) {
|
|
182
|
+
return { kind: 'err', message: VERSIONS_NEED_A_FLOW };
|
|
183
|
+
}
|
|
171
184
|
if (c.baseline !== 'recorded') {
|
|
172
185
|
return { kind: 'err', message: "Only `baseline: 'recorded'` runs today." };
|
|
173
186
|
}
|
|
@@ -337,6 +350,8 @@ async function invokeCase(
|
|
|
337
350
|
evalRunId: ctx.runId as unknown as string,
|
|
338
351
|
},
|
|
339
352
|
...(judgedCase.subject.kind === 'agent' && { history: judgedCase.context?.history ?? [] }),
|
|
353
|
+
...(!('agentId' in ctx.target) &&
|
|
354
|
+
ctx.comparison?.versions !== undefined && { versions: ctx.comparison.versions }),
|
|
340
355
|
});
|
|
341
356
|
} catch (cause) {
|
|
342
357
|
return { error: cause instanceof Error ? cause.message : String(cause) };
|
|
@@ -467,7 +482,7 @@ function summarize(
|
|
|
467
482
|
: 'failed',
|
|
468
483
|
completedAt: new Date().toISOString(),
|
|
469
484
|
suite: { id: ctx.suite.id, version: ctx.suite.version },
|
|
470
|
-
candidate: candidateOf(ctx.target),
|
|
485
|
+
candidate: candidateOf(ctx.target, ctx.comparison?.versions),
|
|
471
486
|
baseline: {
|
|
472
487
|
kind: 'recorded',
|
|
473
488
|
versions: [...versions.values()].map(
|
|
@@ -500,8 +515,16 @@ function summarize(
|
|
|
500
515
|
};
|
|
501
516
|
}
|
|
502
517
|
|
|
503
|
-
function candidateOf(
|
|
518
|
+
function candidateOf(
|
|
519
|
+
target: AgentRef | FlowRef,
|
|
520
|
+
versions: FlowVersionOverrides | undefined,
|
|
521
|
+
): ComparisonCandidate {
|
|
504
522
|
return 'agentId' in target
|
|
505
523
|
? { kind: 'agent', agentId: target.agentId as unknown as string, version: target.version ?? '' }
|
|
506
|
-
: {
|
|
524
|
+
: {
|
|
525
|
+
kind: 'flow',
|
|
526
|
+
flowId: target.flowId as unknown as string,
|
|
527
|
+
version: target.version ?? '',
|
|
528
|
+
...(versions !== undefined && { versions }),
|
|
529
|
+
};
|
|
507
530
|
}
|
|
@@ -1686,8 +1686,16 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
1686
1686
|
parameters: [AgentIdPathParam, IdempotencyKeyParam],
|
|
1687
1687
|
requestBody: { required: true, schema: ref('DeriveAgentVersionBody') },
|
|
1688
1688
|
responses: {
|
|
1689
|
+
'200': {
|
|
1690
|
+
description:
|
|
1691
|
+
'An active version already holds this definition and these pins (the same swap derived before, or a deploy that registered it): that version, unchanged.',
|
|
1692
|
+
schema: ref('Agent'),
|
|
1693
|
+
},
|
|
1689
1694
|
'201': { description: 'The derived agent version.', schema: ref('Agent') },
|
|
1690
1695
|
...CommonMutationErrors,
|
|
1696
|
+
'409': ErrorResponse(
|
|
1697
|
+
"Idempotency-Key was reused with a different body, or resource-state conflict. Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead.",
|
|
1698
|
+
),
|
|
1691
1699
|
'400': ErrorResponse(
|
|
1692
1700
|
"`validation-failed`: `from` has no pins, a swap names a block it doesn't reference, or a version that isn't published, active or the right kind (see `details.issues`).",
|
|
1693
1701
|
),
|
|
@@ -1725,7 +1733,9 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
1725
1733
|
'201': { description: 'Agent published.', schema: ref('PublishAgentResult') },
|
|
1726
1734
|
...CommonMutationErrors,
|
|
1727
1735
|
'400': ErrorResponse('Validation failed (see `details.issues`).'),
|
|
1728
|
-
'409': ErrorResponse(
|
|
1736
|
+
'409': ErrorResponse(
|
|
1737
|
+
"Agent already registered at that (id, version). Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead.",
|
|
1738
|
+
),
|
|
1729
1739
|
},
|
|
1730
1740
|
},
|
|
1731
1741
|
{
|
|
@@ -1740,6 +1750,9 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
1740
1750
|
responses: {
|
|
1741
1751
|
'200': { description: 'Unregistered.', schema: ref('UnregisterAgentResult') },
|
|
1742
1752
|
...CommonMutationErrors,
|
|
1753
|
+
'409': ErrorResponse(
|
|
1754
|
+
"Idempotency-Key was reused with a different body, or resource-state conflict. Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead.",
|
|
1755
|
+
),
|
|
1743
1756
|
'404': ErrorResponse('No agent at that (id, version) under this tenant.'),
|
|
1744
1757
|
},
|
|
1745
1758
|
},
|
|
@@ -1757,6 +1770,9 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
1757
1770
|
responses: {
|
|
1758
1771
|
'200': { description: 'Reinstated.', schema: ref('ReinstateAgentVersionResult') },
|
|
1759
1772
|
...CommonMutationErrors,
|
|
1773
|
+
'409': ErrorResponse(
|
|
1774
|
+
"Idempotency-Key was reused with a different body, or resource-state conflict. Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead.",
|
|
1775
|
+
),
|
|
1760
1776
|
'404': ErrorResponse('No agent at that (id, version) under this tenant.'),
|
|
1761
1777
|
},
|
|
1762
1778
|
},
|
|
@@ -1848,7 +1864,9 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
1848
1864
|
'201': { description: 'Flow published.', schema: ref('PublishFlowResult') },
|
|
1849
1865
|
...CommonMutationErrors,
|
|
1850
1866
|
'400': ErrorResponse('Validation failed (see `details.issues`).'),
|
|
1851
|
-
'409': ErrorResponse(
|
|
1867
|
+
'409': ErrorResponse(
|
|
1868
|
+
"Flow already registered at that (id, version). Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead.",
|
|
1869
|
+
),
|
|
1852
1870
|
},
|
|
1853
1871
|
},
|
|
1854
1872
|
{
|
|
@@ -1863,6 +1881,9 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
1863
1881
|
responses: {
|
|
1864
1882
|
'200': { description: 'Unregistered.', schema: ref('UnregisterFlowResult') },
|
|
1865
1883
|
...CommonMutationErrors,
|
|
1884
|
+
'409': ErrorResponse(
|
|
1885
|
+
"Idempotency-Key was reused with a different body, or resource-state conflict. Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead.",
|
|
1886
|
+
),
|
|
1866
1887
|
'404': ErrorResponse('No flow at that (id, version) under this tenant.'),
|
|
1867
1888
|
},
|
|
1868
1889
|
},
|
|
@@ -1880,6 +1901,9 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
1880
1901
|
responses: {
|
|
1881
1902
|
'200': { description: 'Reinstated.', schema: ref('ReinstateFlowVersionResult') },
|
|
1882
1903
|
...CommonMutationErrors,
|
|
1904
|
+
'409': ErrorResponse(
|
|
1905
|
+
"Idempotency-Key was reused with a different body, or resource-state conflict. Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead.",
|
|
1906
|
+
),
|
|
1883
1907
|
'404': ErrorResponse('No flow at that (id, version) under this tenant.'),
|
|
1884
1908
|
},
|
|
1885
1909
|
},
|
|
@@ -1975,7 +1999,9 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
1975
1999
|
'201': { description: 'Tool registered.', schema: ref('RegisterToolResult') },
|
|
1976
2000
|
...CommonMutationErrors,
|
|
1977
2001
|
'400': ErrorResponse('Validation failed (see `details.issues`).'),
|
|
1978
|
-
'409': ErrorResponse(
|
|
2002
|
+
'409': ErrorResponse(
|
|
2003
|
+
"Tool already registered at that id. Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead.",
|
|
2004
|
+
),
|
|
1979
2005
|
},
|
|
1980
2006
|
},
|
|
1981
2007
|
{
|
|
@@ -1990,6 +2016,9 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
1990
2016
|
responses: {
|
|
1991
2017
|
'200': { description: 'Unregistered.', schema: ref('UnregisterToolResult') },
|
|
1992
2018
|
...CommonMutationErrors,
|
|
2019
|
+
'409': ErrorResponse(
|
|
2020
|
+
"Idempotency-Key was reused with a different body, or resource-state conflict. Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead.",
|
|
2021
|
+
),
|
|
1993
2022
|
'404': ErrorResponse('No tool at that (id, version) under this tenant.'),
|
|
1994
2023
|
},
|
|
1995
2024
|
},
|
|
@@ -2007,6 +2036,9 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
2007
2036
|
responses: {
|
|
2008
2037
|
'200': { description: 'Reinstated.', schema: ref('ReinstateToolVersionResult') },
|
|
2009
2038
|
...CommonMutationErrors,
|
|
2039
|
+
'409': ErrorResponse(
|
|
2040
|
+
"Idempotency-Key was reused with a different body, or resource-state conflict. Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead.",
|
|
2041
|
+
),
|
|
2010
2042
|
'404': ErrorResponse('No tool at that (id, version) under this tenant.'),
|
|
2011
2043
|
},
|
|
2012
2044
|
},
|
|
@@ -2067,7 +2099,9 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
2067
2099
|
'201': { description: 'Guardrail registered.', schema: ref('RegisterGuardrailResult') },
|
|
2068
2100
|
...CommonMutationErrors,
|
|
2069
2101
|
'400': ErrorResponse('Validation failed (see `details.issues`).'),
|
|
2070
|
-
'409': ErrorResponse(
|
|
2102
|
+
'409': ErrorResponse(
|
|
2103
|
+
"Guardrail already registered at that id. Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead.",
|
|
2104
|
+
),
|
|
2071
2105
|
},
|
|
2072
2106
|
},
|
|
2073
2107
|
{
|
|
@@ -2082,6 +2116,9 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
2082
2116
|
responses: {
|
|
2083
2117
|
'200': { description: 'Unregistered.', schema: ref('UnregisterGuardrailResult') },
|
|
2084
2118
|
...CommonMutationErrors,
|
|
2119
|
+
'409': ErrorResponse(
|
|
2120
|
+
"Idempotency-Key was reused with a different body, or resource-state conflict. Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead.",
|
|
2121
|
+
),
|
|
2085
2122
|
'404': ErrorResponse('No guardrail with that id under this tenant.'),
|
|
2086
2123
|
},
|
|
2087
2124
|
},
|
|
@@ -4131,6 +4168,9 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
4131
4168
|
schema: ref('DeploymentRecord'),
|
|
4132
4169
|
},
|
|
4133
4170
|
...CommonMutationErrors,
|
|
4171
|
+
'409': ErrorResponse(
|
|
4172
|
+
"Idempotency-Key was reused with a different body, or resource-state conflict. Or `registry-read-only`: this registry takes no writes (under `kindgi dev`, the pack's files are the source); the message says what to do instead.",
|
|
4173
|
+
),
|
|
4134
4174
|
'400': ErrorResponse(
|
|
4135
4175
|
'Signature invalid, image unverifiable, or deployment-validation-failed with per-primitive `details[]`.',
|
|
4136
4176
|
),
|
|
@@ -4632,6 +4672,9 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
4632
4672
|
responses: {
|
|
4633
4673
|
'201': { description: 'Team created.', schema: ref('CreateResourceResult') },
|
|
4634
4674
|
...CommonMutationErrors,
|
|
4675
|
+
'404': ErrorResponse(
|
|
4676
|
+
'org-not-found: `orgId` names no org of the tenant (it never existed, or it was deleted).',
|
|
4677
|
+
),
|
|
4635
4678
|
},
|
|
4636
4679
|
},
|
|
4637
4680
|
{
|
|
@@ -4679,7 +4722,9 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
4679
4722
|
responses: {
|
|
4680
4723
|
'204': { description: 'Updated. No body.' },
|
|
4681
4724
|
...CommonMutationErrors,
|
|
4682
|
-
'404': ErrorResponse(
|
|
4725
|
+
'404': ErrorResponse(
|
|
4726
|
+
'team-not-found: no team with that id under this tenant; or org-not-found: `orgId` names no org of the tenant (it never existed, or it was deleted).',
|
|
4727
|
+
),
|
|
4683
4728
|
},
|
|
4684
4729
|
},
|
|
4685
4730
|
{
|
|
@@ -4893,6 +4938,9 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
4893
4938
|
responses: {
|
|
4894
4939
|
'201': { description: 'Project created.', schema: ref('CreateResourceResult') },
|
|
4895
4940
|
...CommonMutationErrors,
|
|
4941
|
+
'404': ErrorResponse(
|
|
4942
|
+
'org-not-found: `orgId` names no org of the tenant (it never existed, or it was deleted).',
|
|
4943
|
+
),
|
|
4896
4944
|
},
|
|
4897
4945
|
},
|
|
4898
4946
|
{
|
|
@@ -4942,7 +4990,9 @@ export const OPERATIONS: readonly OperationSpec[] = [
|
|
|
4942
4990
|
responses: {
|
|
4943
4991
|
'204': { description: 'Updated. No body.' },
|
|
4944
4992
|
...CommonMutationErrors,
|
|
4945
|
-
'404': ErrorResponse(
|
|
4993
|
+
'404': ErrorResponse(
|
|
4994
|
+
'project-not-found: no project with that id under this tenant; or org-not-found: `orgId` names no org of the tenant (it never existed, or it was deleted).',
|
|
4995
|
+
),
|
|
4946
4996
|
},
|
|
4947
4997
|
},
|
|
4948
4998
|
{
|