@cat-factory/server 0.214.1 → 0.216.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/ContainerAgentExecutor.d.ts +5 -1
- package/dist/agents/ContainerAgentExecutor.d.ts.map +1 -1
- package/dist/agents/ContainerAgentExecutor.js +6 -13
- package/dist/agents/ContainerAgentExecutor.js.map +1 -1
- package/dist/agents/toolTrajectory.d.ts +40 -0
- package/dist/agents/toolTrajectory.d.ts.map +1 -0
- package/dist/agents/toolTrajectory.js +67 -0
- package/dist/agents/toolTrajectory.js.map +1 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +7 -0
- package/dist/app.js.map +1 -1
- package/dist/http/cors.d.ts +7 -0
- package/dist/http/cors.d.ts.map +1 -1
- package/dist/http/cors.js +8 -0
- package/dist/http/cors.js.map +1 -1
- package/dist/http/loopback.d.ts +23 -0
- package/dist/http/loopback.d.ts.map +1 -0
- package/dist/http/loopback.js +53 -0
- package/dist/http/loopback.js.map +1 -0
- package/dist/modules/publicApi/PublicDebugController.d.ts.map +1 -1
- package/dist/modules/publicApi/PublicDebugController.js +43 -1
- package/dist/modules/publicApi/PublicDebugController.js.map +1 -1
- package/dist/modules/publicApi/PublicDecisionController.d.ts.map +1 -1
- package/dist/modules/publicApi/PublicDecisionController.js +41 -322
- package/dist/modules/publicApi/PublicDecisionController.js.map +1 -1
- package/dist/modules/publicApi/PublicMcpController.d.ts +5 -0
- package/dist/modules/publicApi/PublicMcpController.d.ts.map +1 -0
- package/dist/modules/publicApi/PublicMcpController.js +74 -0
- package/dist/modules/publicApi/PublicMcpController.js.map +1 -0
- package/dist/modules/publicApi/decisions/approvalRoutes.d.ts +4 -0
- package/dist/modules/publicApi/decisions/approvalRoutes.d.ts.map +1 -0
- package/dist/modules/publicApi/decisions/approvalRoutes.js +96 -0
- package/dist/modules/publicApi/decisions/approvalRoutes.js.map +1 -0
- package/dist/modules/publicApi/decisions/dialogueRoutes.d.ts +5 -0
- package/dist/modules/publicApi/decisions/dialogueRoutes.d.ts.map +1 -0
- package/dist/modules/publicApi/decisions/dialogueRoutes.js +161 -0
- package/dist/modules/publicApi/decisions/dialogueRoutes.js.map +1 -0
- package/dist/modules/publicApi/decisions/gateRoutes.d.ts +5 -0
- package/dist/modules/publicApi/decisions/gateRoutes.d.ts.map +1 -0
- package/dist/modules/publicApi/decisions/gateRoutes.js +120 -0
- package/dist/modules/publicApi/decisions/gateRoutes.js.map +1 -0
- package/dist/modules/publicApi/decisions/projection.d.ts +62 -0
- package/dist/modules/publicApi/decisions/projection.d.ts.map +1 -0
- package/dist/modules/publicApi/decisions/projection.js +489 -0
- package/dist/modules/publicApi/decisions/projection.js.map +1 -0
- package/dist/modules/publicApi/decisions/requirementsRoutes.d.ts +11 -0
- package/dist/modules/publicApi/decisions/requirementsRoutes.d.ts.map +1 -0
- package/dist/modules/publicApi/decisions/requirementsRoutes.js +91 -0
- package/dist/modules/publicApi/decisions/requirementsRoutes.js.map +1 -0
- package/dist/modules/publicApi/decisions/scope.d.ts +107 -0
- package/dist/modules/publicApi/decisions/scope.d.ts.map +1 -0
- package/dist/modules/publicApi/decisions/scope.js +142 -0
- package/dist/modules/publicApi/decisions/scope.js.map +1 -0
- package/dist/modules/publicApi/publicApiAdmission.d.ts +9 -5
- package/dist/modules/publicApi/publicApiAdmission.d.ts.map +1 -1
- package/dist/modules/publicApi/publicApiAdmission.js +13 -5
- package/dist/modules/publicApi/publicApiAdmission.js.map +1 -1
- package/dist/modules/publicApi/publicApiAuth.d.ts +22 -0
- package/dist/modules/publicApi/publicApiAuth.d.ts.map +1 -1
- package/dist/modules/publicApi/publicApiAuth.js +39 -2
- package/dist/modules/publicApi/publicApiAuth.js.map +1 -1
- package/dist/modules/telemetry/TelemetryIngestController.d.ts.map +1 -1
- package/dist/modules/telemetry/TelemetryIngestController.js +13 -3
- package/dist/modules/telemetry/TelemetryIngestController.js.map +1 -1
- package/dist/persistence/rpc-allowlist.d.ts +1 -1
- package/dist/persistence/rpc-allowlist.d.ts.map +1 -1
- package/dist/persistence/rpc-allowlist.js +1 -0
- package/dist/persistence/rpc-allowlist.js.map +1 -1
- package/dist/telemetry/machineTelemetry.d.ts +8 -1
- package/dist/telemetry/machineTelemetry.d.ts.map +1 -1
- package/dist/telemetry/machineTelemetry.js +6 -0
- package/dist/telemetry/machineTelemetry.js.map +1 -1
- package/dist/telemetry/machineTelemetryRead.d.ts +36 -1
- package/dist/telemetry/machineTelemetryRead.d.ts.map +1 -1
- package/dist/telemetry/machineTelemetryRead.js +29 -0
- package/dist/telemetry/machineTelemetryRead.js.map +1 -1
- package/package.json +9 -8
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { BrainstormSession, BrainstormStage, ClarityReview, ExecutionInstance, RequirementReview } from '@cat-factory/contracts';
|
|
2
|
+
import type { Context } from 'hono';
|
|
3
|
+
import type { BrainstormModule, ClarityModule, RequirementsModule } from '@cat-factory/orchestration';
|
|
4
|
+
import type { AppEnv } from '../../../http/env.js';
|
|
5
|
+
/** A run resolved for the caller's key, with the block it is anchored on. */
|
|
6
|
+
export interface ScopedRun {
|
|
7
|
+
execution: ExecutionInstance;
|
|
8
|
+
/** The run's anchor block id — a board task, or a headless job anchor. */
|
|
9
|
+
blockId: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Load a run by id for an authenticated key, scoped to the key's workspace. Accepts BOTH shapes the
|
|
13
|
+
* public surface can create: a headless job anchor (`getInternalTask`) and an ordinary board
|
|
14
|
+
* task (`getServiceTask`) — their union is exactly the set of runs this key may already read
|
|
15
|
+
* through `GET /api/v1/jobs/:id` and `GET /api/v1/tasks/:taskId/run`, so nothing new is exposed.
|
|
16
|
+
* Anything else in the workspace (or in another workspace) is a 404.
|
|
17
|
+
*
|
|
18
|
+
* WHY A RESOLVED RUN IS SAFE TO ANSWER THROUGH A BLOCK-SCOPED SERVICE METHOD. The three iterative
|
|
19
|
+
* reviews and both human-verdict gates delegate to methods keyed by BLOCK, not by run (the SPA
|
|
20
|
+
* drives them from the task's window), so the `runId` in the path names a run nothing downstream
|
|
21
|
+
* reads. That would be a misaddressing hazard (answer with a stale id, act on whatever run the
|
|
22
|
+
* block now holds), except the engine makes the two the same question: `insertLive` claims a
|
|
23
|
+
* block's live run under a partial unique index and DELETES that block's terminal rows in the same
|
|
24
|
+
* transaction, and a cancel / `stop-reset` deletes the run row outright. So a run that is no
|
|
25
|
+
* longer its block's live run is not resolvable AT ALL, and this 404 is already the refusal. That
|
|
26
|
+
* is an invariant of the execution repositories rather than of this file, so it is pinned by a
|
|
27
|
+
* conformance assertion (`refuses a block-scoped answer once the task has moved on`) instead of
|
|
28
|
+
* re-checked per request here. A runtime re-check would be an unreachable branch, and an
|
|
29
|
+
* unreachable branch in four published SDK error vocabularies.
|
|
30
|
+
*/
|
|
31
|
+
export declare function loadScopedRun<E extends AppEnv>(c: Context<E>, workspaceId: string, runId: string): Promise<ScopedRun | null>;
|
|
32
|
+
/** The error a gate rejected with, kept as DATA so each handler emits its own typed `c.json`. */
|
|
33
|
+
export type GateFailure = {
|
|
34
|
+
fail: {
|
|
35
|
+
status: 401 | 403 | 404 | 503;
|
|
36
|
+
code: string;
|
|
37
|
+
message: string;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Emit a gate's rejection as the surface's standard error body.
|
|
42
|
+
*
|
|
43
|
+
* The `c.json` call stays INSIDE each handler's closure (rather than this returning a built
|
|
44
|
+
* `Response`) so `buildHonoRoute` keeps type-checking every handler against its contract's declared
|
|
45
|
+
* response union — a bare `Response` would erase that. This just removes the identical copies
|
|
46
|
+
* of the body/status shuffle, which is where an inconsistent error envelope would eventually creep
|
|
47
|
+
* in between two routes of the same surface.
|
|
48
|
+
*/
|
|
49
|
+
export declare function failureBody(fail: GateFailure['fail']): {
|
|
50
|
+
error: {
|
|
51
|
+
code: string;
|
|
52
|
+
message: string;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Resolve the run + require the answering scope, then hand the handler a settled context — or the
|
|
57
|
+
* failure to emit. Every mutating route shares exactly this preamble, and duplicating it per route
|
|
58
|
+
* is how two surfaces drift apart.
|
|
59
|
+
*
|
|
60
|
+
* The failure is returned as DATA rather than a built `Response` (mirroring `authorize`) because
|
|
61
|
+
* `buildHonoRoute` types each handler against its contract's declared response union: a bare
|
|
62
|
+
* `Response` would erase that and stop the compiler checking the success payload.
|
|
63
|
+
*/
|
|
64
|
+
export declare function gateDecisionAction<E extends AppEnv>(c: Context<E>, runId: string): Promise<{
|
|
65
|
+
workspaceId: string;
|
|
66
|
+
scoped: ScopedRun;
|
|
67
|
+
} | GateFailure>;
|
|
68
|
+
/** The settled context an iterative-review route acts on, for one review kind. */
|
|
69
|
+
export interface ReviewAction<TReview> {
|
|
70
|
+
workspaceId: string;
|
|
71
|
+
scoped: ScopedRun;
|
|
72
|
+
review: TReview;
|
|
73
|
+
}
|
|
74
|
+
/** The settled context a requirements route acts on. */
|
|
75
|
+
export interface RequirementsAction extends ReviewAction<RequirementReview> {
|
|
76
|
+
requirements: RequirementsModule;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Gate a requirements action: the shared {@link gateDecisionAction} preamble, plus the opt-in
|
|
80
|
+
* requirements module and the run's LIVE review. Every requirements route needs exactly this
|
|
81
|
+
* quartet (key + scope, run, module, review), and hand-rolling it per route is how two surfaces
|
|
82
|
+
* end up disagreeing about which review a run's answer applies to.
|
|
83
|
+
*/
|
|
84
|
+
export declare function gateRequirementsAction<E extends AppEnv>(c: Context<E>, runId: string): Promise<RequirementsAction | GateFailure>;
|
|
85
|
+
/** The settled context a clarity route acts on. */
|
|
86
|
+
export interface ClarityAction extends ReviewAction<ClarityReview> {
|
|
87
|
+
clarity: ClarityModule;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Gate a clarity action — the requirements gate's twin, over the clarity module. Kept as a
|
|
91
|
+
* separate function rather than parameterised over the module because the two 503/404 messages
|
|
92
|
+
* have to NAME their own subject: a bug-triage caller told "requirements review is not configured"
|
|
93
|
+
* has been handed the wrong thing to go and wire.
|
|
94
|
+
*/
|
|
95
|
+
export declare function gateClarityAction<E extends AppEnv>(c: Context<E>, runId: string): Promise<ClarityAction | GateFailure>;
|
|
96
|
+
/** The settled context a brainstorm route acts on, for ONE stage. */
|
|
97
|
+
export interface BrainstormAction extends ReviewAction<BrainstormSession> {
|
|
98
|
+
brainstorm: BrainstormModule;
|
|
99
|
+
stage: BrainstormStage;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Gate a brainstorm action. Keyed by `(block, stage)` rather than block alone, because a block may
|
|
103
|
+
* hold one live `requirements` session and one live `architecture` session at once — resolving
|
|
104
|
+
* "the run's brainstorm" without the stage would answer whichever the store returned first.
|
|
105
|
+
*/
|
|
106
|
+
export declare function gateBrainstormAction<E extends AppEnv>(c: Context<E>, runId: string, stage: BrainstormStage): Promise<BrainstormAction | GateFailure>;
|
|
107
|
+
//# sourceMappingURL=scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../../../src/modules/publicApi/decisions/scope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { authorize } from '../publicApiAuth.js';
|
|
2
|
+
/**
|
|
3
|
+
* Load a run by id for an authenticated key, scoped to the key's workspace. Accepts BOTH shapes the
|
|
4
|
+
* public surface can create: a headless job anchor (`getInternalTask`) and an ordinary board
|
|
5
|
+
* task (`getServiceTask`) — their union is exactly the set of runs this key may already read
|
|
6
|
+
* through `GET /api/v1/jobs/:id` and `GET /api/v1/tasks/:taskId/run`, so nothing new is exposed.
|
|
7
|
+
* Anything else in the workspace (or in another workspace) is a 404.
|
|
8
|
+
*
|
|
9
|
+
* WHY A RESOLVED RUN IS SAFE TO ANSWER THROUGH A BLOCK-SCOPED SERVICE METHOD. The three iterative
|
|
10
|
+
* reviews and both human-verdict gates delegate to methods keyed by BLOCK, not by run (the SPA
|
|
11
|
+
* drives them from the task's window), so the `runId` in the path names a run nothing downstream
|
|
12
|
+
* reads. That would be a misaddressing hazard (answer with a stale id, act on whatever run the
|
|
13
|
+
* block now holds), except the engine makes the two the same question: `insertLive` claims a
|
|
14
|
+
* block's live run under a partial unique index and DELETES that block's terminal rows in the same
|
|
15
|
+
* transaction, and a cancel / `stop-reset` deletes the run row outright. So a run that is no
|
|
16
|
+
* longer its block's live run is not resolvable AT ALL, and this 404 is already the refusal. That
|
|
17
|
+
* is an invariant of the execution repositories rather than of this file, so it is pinned by a
|
|
18
|
+
* conformance assertion (`refuses a block-scoped answer once the task has moved on`) instead of
|
|
19
|
+
* re-checked per request here. A runtime re-check would be an unreachable branch, and an
|
|
20
|
+
* unreachable branch in four published SDK error vocabularies.
|
|
21
|
+
*/
|
|
22
|
+
export async function loadScopedRun(c, workspaceId, runId) {
|
|
23
|
+
const container = c.get('container');
|
|
24
|
+
const execution = await container.executionRepository.get(workspaceId, runId);
|
|
25
|
+
if (!execution)
|
|
26
|
+
return null;
|
|
27
|
+
const task = await container.boardService.getServiceTask(workspaceId, execution.blockId);
|
|
28
|
+
if (task)
|
|
29
|
+
return { execution, blockId: execution.blockId };
|
|
30
|
+
const anchor = await container.boardService.getInternalTask(workspaceId, execution.blockId);
|
|
31
|
+
return anchor ? { execution, blockId: execution.blockId } : null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Emit a gate's rejection as the surface's standard error body.
|
|
35
|
+
*
|
|
36
|
+
* The `c.json` call stays INSIDE each handler's closure (rather than this returning a built
|
|
37
|
+
* `Response`) so `buildHonoRoute` keeps type-checking every handler against its contract's declared
|
|
38
|
+
* response union — a bare `Response` would erase that. This just removes the identical copies
|
|
39
|
+
* of the body/status shuffle, which is where an inconsistent error envelope would eventually creep
|
|
40
|
+
* in between two routes of the same surface.
|
|
41
|
+
*/
|
|
42
|
+
export function failureBody(fail) {
|
|
43
|
+
return { error: { code: fail.code, message: fail.message } };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Resolve the run + require the answering scope, then hand the handler a settled context — or the
|
|
47
|
+
* failure to emit. Every mutating route shares exactly this preamble, and duplicating it per route
|
|
48
|
+
* is how two surfaces drift apart.
|
|
49
|
+
*
|
|
50
|
+
* The failure is returned as DATA rather than a built `Response` (mirroring `authorize`) because
|
|
51
|
+
* `buildHonoRoute` types each handler against its contract's declared response union: a bare
|
|
52
|
+
* `Response` would erase that and stop the compiler checking the success payload.
|
|
53
|
+
*/
|
|
54
|
+
export async function gateDecisionAction(c, runId) {
|
|
55
|
+
// `decide` — the same rung that admits a parking pipeline in the first place. Answering injects
|
|
56
|
+
// caller-supplied prose into the requirements every downstream agent then implements, so it sits
|
|
57
|
+
// above ordinary `write` task authoring.
|
|
58
|
+
const gate = await authorize(c, 'decide');
|
|
59
|
+
if ('fail' in gate)
|
|
60
|
+
return gate;
|
|
61
|
+
const { workspaceId } = gate.auth;
|
|
62
|
+
const scoped = await loadScopedRun(c, workspaceId, runId);
|
|
63
|
+
if (!scoped) {
|
|
64
|
+
return { fail: { status: 404, code: 'not_found', message: 'Run not found' } };
|
|
65
|
+
}
|
|
66
|
+
return { workspaceId, scoped };
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Gate a requirements action: the shared {@link gateDecisionAction} preamble, plus the opt-in
|
|
70
|
+
* requirements module and the run's LIVE review. Every requirements route needs exactly this
|
|
71
|
+
* quartet (key + scope, run, module, review), and hand-rolling it per route is how two surfaces
|
|
72
|
+
* end up disagreeing about which review a run's answer applies to.
|
|
73
|
+
*/
|
|
74
|
+
export async function gateRequirementsAction(c, runId) {
|
|
75
|
+
const gated = await gateDecisionAction(c, runId);
|
|
76
|
+
if ('fail' in gated)
|
|
77
|
+
return gated;
|
|
78
|
+
const requirements = c.get('container').requirements;
|
|
79
|
+
if (!requirements) {
|
|
80
|
+
return moduleUnavailable('Requirements review is not configured');
|
|
81
|
+
}
|
|
82
|
+
const { workspaceId, scoped } = gated;
|
|
83
|
+
const review = await requirements.service.getForBlock(workspaceId, scoped.blockId);
|
|
84
|
+
if (!review) {
|
|
85
|
+
return noReview('This run has no requirements review');
|
|
86
|
+
}
|
|
87
|
+
return { workspaceId, scoped, requirements, review };
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Gate a clarity action — the requirements gate's twin, over the clarity module. Kept as a
|
|
91
|
+
* separate function rather than parameterised over the module because the two 503/404 messages
|
|
92
|
+
* have to NAME their own subject: a bug-triage caller told "requirements review is not configured"
|
|
93
|
+
* has been handed the wrong thing to go and wire.
|
|
94
|
+
*/
|
|
95
|
+
export async function gateClarityAction(c, runId) {
|
|
96
|
+
const gated = await gateDecisionAction(c, runId);
|
|
97
|
+
if ('fail' in gated)
|
|
98
|
+
return gated;
|
|
99
|
+
const clarity = c.get('container').clarity;
|
|
100
|
+
if (!clarity) {
|
|
101
|
+
return moduleUnavailable('Clarity review is not configured');
|
|
102
|
+
}
|
|
103
|
+
const { workspaceId, scoped } = gated;
|
|
104
|
+
const review = await clarity.service.getForBlock(workspaceId, scoped.blockId);
|
|
105
|
+
if (!review) {
|
|
106
|
+
return noReview('This run has no clarity review');
|
|
107
|
+
}
|
|
108
|
+
return { workspaceId, scoped, clarity, review };
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Gate a brainstorm action. Keyed by `(block, stage)` rather than block alone, because a block may
|
|
112
|
+
* hold one live `requirements` session and one live `architecture` session at once — resolving
|
|
113
|
+
* "the run's brainstorm" without the stage would answer whichever the store returned first.
|
|
114
|
+
*/
|
|
115
|
+
export async function gateBrainstormAction(c, runId, stage) {
|
|
116
|
+
const gated = await gateDecisionAction(c, runId);
|
|
117
|
+
if ('fail' in gated)
|
|
118
|
+
return gated;
|
|
119
|
+
const brainstorm = c.get('container').brainstorm;
|
|
120
|
+
if (!brainstorm) {
|
|
121
|
+
return moduleUnavailable('Brainstorm is not configured');
|
|
122
|
+
}
|
|
123
|
+
const { workspaceId, scoped } = gated;
|
|
124
|
+
const review = await brainstorm.services[stage].getForBlock(workspaceId, scoped.blockId);
|
|
125
|
+
if (!review) {
|
|
126
|
+
return noReview(`This run has no ${stage} brainstorm`);
|
|
127
|
+
}
|
|
128
|
+
return { workspaceId, scoped, brainstorm, stage, review };
|
|
129
|
+
}
|
|
130
|
+
/** A deployment that never wired the module behind a park cannot answer it: 503, naming what. */
|
|
131
|
+
function moduleUnavailable(message) {
|
|
132
|
+
return { fail: { status: 503, code: 'unavailable', message } };
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* The run exists and the key may answer it, but the entity the route addresses does not exist.
|
|
136
|
+
* A 404 rather than a 409: there is nothing on this run to act on, which is a different fact from
|
|
137
|
+
* "the park moved on" (the service methods raise that themselves).
|
|
138
|
+
*/
|
|
139
|
+
function noReview(message) {
|
|
140
|
+
return { fail: { status: 404, code: 'no_review', message } };
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../../../../src/modules/publicApi/decisions/scope.ts"],"names":[],"mappings":"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"}
|
|
@@ -63,16 +63,20 @@ export declare const PUBLIC_TASK_STOP_PATH = "POST /api/v1/tasks/:taskId/stop";
|
|
|
63
63
|
/**
|
|
64
64
|
* The park surfaces `/api/v1/runs/:runId/decisions` can actually ANSWER today.
|
|
65
65
|
*
|
|
66
|
-
* Deliberately a SEPARATE set from {@link PARKING_INLINE_KINDS}, because the asymmetry between
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* `buildDecisionList` does not read; an approval gate is not projected at all). Closing that gap is
|
|
70
|
-
* tracked in `docs/initiatives/public-api-additions.md`.
|
|
66
|
+
* Deliberately a SEPARATE set from {@link PARKING_INLINE_KINDS}, because the asymmetry between the
|
|
67
|
+
* two is the thing worth stating: admission decides what a `decide` key may set in motion, and
|
|
68
|
+
* this decides what the refusal is allowed to PROMISE it can then answer.
|
|
71
69
|
*
|
|
72
70
|
* Keeping the answerable set EXPLICIT rather than implied is what stops the refusal below drifting
|
|
73
71
|
* from what the surface really serves: landing a slice moves a member here and the message it
|
|
74
72
|
* builds updates itself, where a hand-written sentence would keep promising an answer path that
|
|
75
73
|
* does not exist — which is exactly the defect this replaced.
|
|
74
|
+
*
|
|
75
|
+
* The gap is now down to ONE member of {@link parkSurfacesOf}: `human-review`, and it is not a
|
|
76
|
+
* slice waiting to be built. Its answer is a person approving the pull request on the VCS host,
|
|
77
|
+
* not an API call this surface could offer, so a run parked there is honestly reported as
|
|
78
|
+
* `parked: true` with nothing to answer and the refusal says as much. See
|
|
79
|
+
* `docs/initiatives/public-api-additions.md`.
|
|
76
80
|
*/
|
|
77
81
|
export declare const PUBLICLY_ANSWERABLE_PARK_SURFACES: Set<string>;
|
|
78
82
|
/** The pipeline shape admission reasons about — the step chain plus its parallel flag arrays. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publicApiAdmission.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/publicApiAdmission.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,KAAK,iBAAiB,EAMvB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAE9D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,oBAAoB,aAK/B,CAAA;AAEF;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,kBAAkB,CAAA;AAEzD;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,eAAe,CAAA;AAEnD;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,qBAAqB,EAAE,CAAA;AAEhC;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,iCAAiC,CAAA;AACpE,eAAO,MAAM,qBAAqB,oCAAoC,CAAA;AAEtE
|
|
1
|
+
{"version":3,"file":"publicApiAdmission.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/publicApiAdmission.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,KAAK,iBAAiB,EAMvB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAE9D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,oBAAoB,aAK/B,CAAA;AAEF;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,kBAAkB,CAAA;AAEzD;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,eAAe,CAAA;AAEnD;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,qBAAqB,EAAE,CAAA;AAEhC;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,iCAAiC,CAAA;AACpE,eAAO,MAAM,qBAAqB,oCAAoC,CAAA;AAEtE;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,iCAAiC,aAO5C,CAAA;AAEF,iGAAiG;AACjG,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,6FAA6F;IAC7F,OAAO,CAAC,EAAE,OAAO,EAAE,CAAA;IACnB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,OAAO,EAAE,CAAA;CAClB;AASD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,uBAAuB,EACjC,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAIT;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,uBAAuB,GAAG,OAAO,CAEzE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,uBAAuB,GAAG,MAAM,EAAE,CAO1E;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAgBjG;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,uBAAuB,EACjC,OAAO,EAAE;IAAE,eAAe,EAAE,OAAO,CAAA;CAAE,GACpC,MAAM,EAAE,CAKV;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,uBAAuB,EACjC,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAET"}
|
|
@@ -80,20 +80,28 @@ export const PUBLIC_TASK_STOP_PATH = 'POST /api/v1/tasks/:taskId/stop';
|
|
|
80
80
|
/**
|
|
81
81
|
* The park surfaces `/api/v1/runs/:runId/decisions` can actually ANSWER today.
|
|
82
82
|
*
|
|
83
|
-
* Deliberately a SEPARATE set from {@link PARKING_INLINE_KINDS}, because the asymmetry between
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* `buildDecisionList` does not read; an approval gate is not projected at all). Closing that gap is
|
|
87
|
-
* tracked in `docs/initiatives/public-api-additions.md`.
|
|
83
|
+
* Deliberately a SEPARATE set from {@link PARKING_INLINE_KINDS}, because the asymmetry between the
|
|
84
|
+
* two is the thing worth stating: admission decides what a `decide` key may set in motion, and
|
|
85
|
+
* this decides what the refusal is allowed to PROMISE it can then answer.
|
|
88
86
|
*
|
|
89
87
|
* Keeping the answerable set EXPLICIT rather than implied is what stops the refusal below drifting
|
|
90
88
|
* from what the surface really serves: landing a slice moves a member here and the message it
|
|
91
89
|
* builds updates itself, where a hand-written sentence would keep promising an answer path that
|
|
92
90
|
* does not exist — which is exactly the defect this replaced.
|
|
91
|
+
*
|
|
92
|
+
* The gap is now down to ONE member of {@link parkSurfacesOf}: `human-review`, and it is not a
|
|
93
|
+
* slice waiting to be built. Its answer is a person approving the pull request on the VCS host,
|
|
94
|
+
* not an API call this surface could offer, so a run parked there is honestly reported as
|
|
95
|
+
* `parked: true` with nothing to answer and the refusal says as much. See
|
|
96
|
+
* `docs/initiatives/public-api-additions.md`.
|
|
93
97
|
*/
|
|
94
98
|
export const PUBLICLY_ANSWERABLE_PARK_SURFACES = new Set([
|
|
95
99
|
REQUIREMENTS_REVIEW_AGENT_KIND,
|
|
100
|
+
CLARITY_REVIEW_AGENT_KIND,
|
|
101
|
+
REQUIREMENTS_BRAINSTORM_AGENT_KIND,
|
|
102
|
+
ARCHITECTURE_BRAINSTORM_AGENT_KIND,
|
|
96
103
|
INPUT_GATE_PARK_SURFACE,
|
|
104
|
+
APPROVAL_GATE_PARK_SURFACE,
|
|
97
105
|
]);
|
|
98
106
|
/** The enabled steps of a pipeline, paired with their ORIGINAL index (gates are index-aligned). */
|
|
99
107
|
function enabledSteps(pipeline) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publicApiAdmission.js","sourceRoot":"","sources":["../../../src/modules/publicApi/publicApiAdmission.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,0FAA0F;AAC1F,mCAAmC;AACnC,EAAE;AACF,iGAAiG;AACjG,mGAAmG;AACnG,mGAAmG;AACnG,mGAAmG;AACnG,sFAAsF;AACtF,mCAAmC;AACnC,EAAE;AACF,4DAA4D;AAE5D,OAAO,EAEL,kCAAkC,EAClC,yBAAyB,EACzB,iBAAiB,EACjB,kCAAkC,EAClC,8BAA8B,GAC/B,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAE9D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAS;IAClD,8BAA8B;IAC9B,yBAAyB;IACzB,kCAAkC;IAClC,kCAAkC;CACnC,CAAC,CAAA;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,eAAe,CAAA;AAEzD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,YAAY,CAAA;AAEnD;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,qBAAqB,EAAE,CAAA;AAEhC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,8BAA8B,CAAA;AACpE,MAAM,CAAC,MAAM,qBAAqB,GAAG,iCAAiC,CAAA;AAEtE
|
|
1
|
+
{"version":3,"file":"publicApiAdmission.js","sourceRoot":"","sources":["../../../src/modules/publicApi/publicApiAdmission.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,14 @@ export type KeyResult = {
|
|
|
16
16
|
message: string;
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
|
+
/**
|
|
20
|
+
* The raw key the caller presented, stripped of its `Bearer` prefix.
|
|
21
|
+
*
|
|
22
|
+
* Shared rather than re-derived, because the hosted MCP endpoint FORWARDS the key onto the calls its
|
|
23
|
+
* tools make: a second copy of this parse could admit a key here and hand a differently-trimmed one
|
|
24
|
+
* to the SDK, which authenticates as nobody.
|
|
25
|
+
*/
|
|
26
|
+
export declare function bearerToken<E extends AppEnv>(c: Context<E>): string | undefined;
|
|
19
27
|
/**
|
|
20
28
|
* Render an auth `fail` as its response. Lives here rather than in each controller because the
|
|
21
29
|
* refusal shape is part of the surface's contract, not a per-route choice: every `/api/v1` handler
|
|
@@ -44,4 +52,18 @@ export declare function resolveKey<E extends AppEnv>(c: Context<E>): Promise<Key
|
|
|
44
52
|
* this". Every `/api/v1` handler gates through this, naming the least scope it needs.
|
|
45
53
|
*/
|
|
46
54
|
export declare function authorize<E extends AppEnv>(c: Context<E>, need: PublicApiScope): Promise<KeyResult>;
|
|
55
|
+
/**
|
|
56
|
+
* {@link authorize} for a route with no contract-declared response schema: the refusal is THROWN as
|
|
57
|
+
* a `DomainError` so `handleError` renders it, correlation id and all.
|
|
58
|
+
*
|
|
59
|
+
* The `fail`-as-data shape above exists because the contract handlers must stay typed against their
|
|
60
|
+
* declared responses; a hand-mounted route (the MCP endpoint) has no such obligation and gets the
|
|
61
|
+
* repo's default instead of a fourth hand-built envelope. Same ladder either way: the scope rule
|
|
62
|
+
* lives in exactly one place, and this is a translation of its verdict rather than a second copy.
|
|
63
|
+
*
|
|
64
|
+
* `details.reason` carries the machine-readable cause, since `code` is only the status class: an
|
|
65
|
+
* `insufficient_scope` needs a wider key, a `invalid_api_key` a valid one, and an unconfigured
|
|
66
|
+
* public API needs the deployment's operator.
|
|
67
|
+
*/
|
|
68
|
+
export declare function authorizeOrThrow<E extends AppEnv>(c: Context<E>, need: PublicApiScope): Promise<PublicApiKeyAuth>;
|
|
47
69
|
//# sourceMappingURL=publicApiAuth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publicApiAuth.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/publicApiAuth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"publicApiAuth.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/publicApiAuth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAEjF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAS/C;;;;GAIG;AACH,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B;IAAE,IAAI,EAAE;QAAE,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAA;AAExE;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,SAAS,CAE/E;AAED;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EACrC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EACb,IAAI,EAAE,OAAO,CAAC,SAAS,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,MAAM,CAAC;;QAE1B,IAAI;QAAa,OAAO;;4BAClD;AAED,sFAAsF;AACtF,wBAAsB,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAUpF;AAED;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,CAAC,SAAS,MAAM,EAC9C,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EACb,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,SAAS,CAAC,CAapB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,SAAS,MAAM,EACrD,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EACb,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,gBAAgB,CAAC,CAY3B"}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import { scopeSatisfies } from '@cat-factory/integrations';
|
|
2
|
+
import { ForbiddenError, UnauthorizedError, UnavailableError } from '@cat-factory/kernel';
|
|
3
|
+
/**
|
|
4
|
+
* The raw key the caller presented, stripped of its `Bearer` prefix.
|
|
5
|
+
*
|
|
6
|
+
* Shared rather than re-derived, because the hosted MCP endpoint FORWARDS the key onto the calls its
|
|
7
|
+
* tools make: a second copy of this parse could admit a key here and hand a differently-trimmed one
|
|
8
|
+
* to the SDK, which authenticates as nobody.
|
|
9
|
+
*/
|
|
10
|
+
export function bearerToken(c) {
|
|
11
|
+
return c.req.header('authorization')?.replace(/^Bearer\s+/i, '');
|
|
12
|
+
}
|
|
2
13
|
/**
|
|
3
14
|
* Render an auth `fail` as its response. Lives here rather than in each controller because the
|
|
4
15
|
* refusal shape is part of the surface's contract, not a per-route choice: every `/api/v1` handler
|
|
@@ -18,8 +29,7 @@ export async function resolveKey(c) {
|
|
|
18
29
|
if (!svc) {
|
|
19
30
|
return { fail: { status: 503, code: 'unavailable', message: 'Public API is not configured' } };
|
|
20
31
|
}
|
|
21
|
-
const
|
|
22
|
-
const auth = await svc.authenticate(raw);
|
|
32
|
+
const auth = await svc.authenticate(bearerToken(c));
|
|
23
33
|
if (!auth) {
|
|
24
34
|
return { fail: { status: 401, code: 'unauthorized', message: 'Invalid or missing API key' } };
|
|
25
35
|
}
|
|
@@ -47,4 +57,31 @@ export async function authorize(c, need) {
|
|
|
47
57
|
}
|
|
48
58
|
return result;
|
|
49
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* {@link authorize} for a route with no contract-declared response schema: the refusal is THROWN as
|
|
62
|
+
* a `DomainError` so `handleError` renders it, correlation id and all.
|
|
63
|
+
*
|
|
64
|
+
* The `fail`-as-data shape above exists because the contract handlers must stay typed against their
|
|
65
|
+
* declared responses; a hand-mounted route (the MCP endpoint) has no such obligation and gets the
|
|
66
|
+
* repo's default instead of a fourth hand-built envelope. Same ladder either way: the scope rule
|
|
67
|
+
* lives in exactly one place, and this is a translation of its verdict rather than a second copy.
|
|
68
|
+
*
|
|
69
|
+
* `details.reason` carries the machine-readable cause, since `code` is only the status class: an
|
|
70
|
+
* `insufficient_scope` needs a wider key, a `invalid_api_key` a valid one, and an unconfigured
|
|
71
|
+
* public API needs the deployment's operator.
|
|
72
|
+
*/
|
|
73
|
+
export async function authorizeOrThrow(c, need) {
|
|
74
|
+
const result = await authorize(c, need);
|
|
75
|
+
if (!('fail' in result))
|
|
76
|
+
return result.auth;
|
|
77
|
+
const { status, code, message } = result.fail;
|
|
78
|
+
switch (status) {
|
|
79
|
+
case 401:
|
|
80
|
+
throw new UnauthorizedError(message, 'invalid_api_key');
|
|
81
|
+
case 403:
|
|
82
|
+
throw new ForbiddenError(message, { reason: code, requiredScope: need });
|
|
83
|
+
case 503:
|
|
84
|
+
throw new UnavailableError(message, 'public_api_unconfigured');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
50
87
|
//# sourceMappingURL=publicApiAuth.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publicApiAuth.js","sourceRoot":"","sources":["../../../src/modules/publicApi/publicApiAuth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAyB,MAAM,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"publicApiAuth.js","sourceRoot":"","sources":["../../../src/modules/publicApi/publicApiAuth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TelemetryIngestController.d.ts","sourceRoot":"","sources":["../../../src/modules/telemetry/TelemetryIngestController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"TelemetryIngestController.d.ts","sourceRoot":"","sources":["../../../src/modules/telemetry/TelemetryIngestController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAe3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAQ/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAAC,MAAM,CAAC,CAmJxD"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
2
|
import * as v from 'valibot';
|
|
3
|
-
import { agentContextSnapshotSchema, agentSearchQuerySchema, llmCallMetricSchema, } from '@cat-factory/contracts';
|
|
3
|
+
import { agentContextSnapshotSchema, agentSearchQuerySchema, agentToolCallSchema, llmCallMetricSchema, } from '@cat-factory/contracts';
|
|
4
4
|
import { verifyMachineRequest } from '../../auth/machineGate.js';
|
|
5
5
|
import { logger } from '../../observability/logger.js';
|
|
6
6
|
import { MAX_TELEMETRY_INGEST_CHARS, TELEMETRY_INGEST_LIMITS, } from '../../telemetry/machineTelemetry.js';
|
|
@@ -53,10 +53,12 @@ export function telemetryIngestController() {
|
|
|
53
53
|
const metricRepository = repos?.llmCallMetricRepository;
|
|
54
54
|
const snapshotRepository = repos?.agentContextSnapshotRepository;
|
|
55
55
|
const searchRepository = repos?.agentSearchQueryRepository;
|
|
56
|
+
const toolCallRepository = repos?.agentToolCallRepository;
|
|
56
57
|
if (typeof workspaceRepository?.accountOf !== 'function' ||
|
|
57
58
|
typeof metricRepository?.recordMany !== 'function' ||
|
|
58
59
|
typeof snapshotRepository?.recordMany !== 'function' ||
|
|
59
|
-
typeof searchRepository?.recordMany !== 'function'
|
|
60
|
+
typeof searchRepository?.recordMany !== 'function' ||
|
|
61
|
+
typeof toolCallRepository?.recordMany !== 'function') {
|
|
60
62
|
return c.json({ ok: false, error: { code: 'internal', message: 'telemetry ingest not enabled' } }, 503);
|
|
61
63
|
}
|
|
62
64
|
// Size backstop, in two steps, because the row caps below bound COUNT while a single
|
|
@@ -121,6 +123,7 @@ export function telemetryIngestController() {
|
|
|
121
123
|
await metricRepository.recordMany(rows.metrics.map((m) => ({ ...m, ...scope })));
|
|
122
124
|
await snapshotRepository.recordMany(rows.snapshots.map((s) => ({ ...s, ...scope })));
|
|
123
125
|
await searchRepository.recordMany(rows.searchQueries.map((q) => ({ ...q, ...scope })));
|
|
126
|
+
await toolCallRepository.recordMany(rows.toolCalls.map((t) => ({ ...t, ...scope })));
|
|
124
127
|
}
|
|
125
128
|
catch (error) {
|
|
126
129
|
// A failed append must be visible to the node: it leaves the run's high-water mark alone
|
|
@@ -138,6 +141,7 @@ export function telemetryIngestController() {
|
|
|
138
141
|
metrics: rows.metrics.length,
|
|
139
142
|
snapshots: rows.snapshots.length,
|
|
140
143
|
searchQueries: rows.searchQueries.length,
|
|
144
|
+
toolCalls: rows.toolCalls.length,
|
|
141
145
|
},
|
|
142
146
|
});
|
|
143
147
|
});
|
|
@@ -152,11 +156,14 @@ function overCap(body) {
|
|
|
152
156
|
if ((body.searchQueries?.length ?? 0) > TELEMETRY_INGEST_LIMITS.searchQueries) {
|
|
153
157
|
return 'searchQueries';
|
|
154
158
|
}
|
|
159
|
+
if ((body.toolCalls?.length ?? 0) > TELEMETRY_INGEST_LIMITS.toolCalls)
|
|
160
|
+
return 'toolCalls';
|
|
155
161
|
return null;
|
|
156
162
|
}
|
|
157
163
|
const metricsSchema = v.optional(v.array(llmCallMetricSchema), []);
|
|
158
164
|
const snapshotsSchema = v.optional(v.array(agentContextSnapshotSchema), []);
|
|
159
165
|
const searchQueriesSchema = v.optional(v.array(agentSearchQuerySchema), []);
|
|
166
|
+
const toolCallsSchema = v.optional(v.array(agentToolCallSchema), []);
|
|
160
167
|
/**
|
|
161
168
|
* Validate each sink's rows against the SAME wire schema the rest of the product reads them
|
|
162
169
|
* through, or null when any row is out of contract. Whole-batch rejection rather than
|
|
@@ -167,12 +174,15 @@ function decodeRows(body) {
|
|
|
167
174
|
const metrics = v.safeParse(metricsSchema, body.metrics);
|
|
168
175
|
const snapshots = v.safeParse(snapshotsSchema, body.snapshots);
|
|
169
176
|
const searchQueries = v.safeParse(searchQueriesSchema, body.searchQueries);
|
|
170
|
-
|
|
177
|
+
const toolCalls = v.safeParse(toolCallsSchema, body.toolCalls);
|
|
178
|
+
if (!metrics.success || !snapshots.success || !searchQueries.success || !toolCalls.success) {
|
|
171
179
|
return null;
|
|
180
|
+
}
|
|
172
181
|
return {
|
|
173
182
|
metrics: metrics.output,
|
|
174
183
|
snapshots: snapshots.output,
|
|
175
184
|
searchQueries: searchQueries.output,
|
|
185
|
+
toolCalls: toolCalls.output,
|
|
176
186
|
};
|
|
177
187
|
}
|
|
178
188
|
//# sourceMappingURL=TelemetryIngestController.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TelemetryIngestController.js","sourceRoot":"","sources":["../../../src/modules/telemetry/TelemetryIngestController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"TelemetryIngestController.js","sourceRoot":"","sources":["../../../src/modules/telemetry/TelemetryIngestController.ts"],"names":[],"mappings":"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"}
|
|
@@ -54,7 +54,7 @@ export declare const REMOTE_PERSISTENCE_METHODS: PersistenceMethodTable;
|
|
|
54
54
|
* profile but is the org's budget SAFEGUARD, whose rollups the spend gate reads remotely — see its
|
|
55
55
|
* `record` entry above.
|
|
56
56
|
*/
|
|
57
|
-
export declare const LOCAL_FIRST_PERSISTENCE_REPOSITORIES: readonly ['llmCallMetricRepository', 'agentContextSnapshotRepository', 'agentSearchQueryRepository', 'provisioningLogRepository', 'subscriptionQuotaCycleRepository'];
|
|
57
|
+
export declare const LOCAL_FIRST_PERSISTENCE_REPOSITORIES: readonly ['llmCallMetricRepository', 'agentContextSnapshotRepository', 'agentSearchQueryRepository', 'agentToolCallRepository', 'provisioningLogRepository', 'subscriptionQuotaCycleRepository'];
|
|
58
58
|
/** A repository name in {@link LOCAL_FIRST_PERSISTENCE_REPOSITORIES}. */
|
|
59
59
|
export type LocalFirstPersistenceRepository = (typeof LOCAL_FIRST_PERSISTENCE_REPOSITORIES)[number];
|
|
60
60
|
//# sourceMappingURL=rpc-allowlist.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-allowlist.d.ts","sourceRoot":"","sources":["../../src/persistence/rpc-allowlist.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AAgBtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,0BAA0B,EAAE,sBA0nCxC,CAAA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,oCAAoC,YAC/C,yBAAyB,EACzB,gCAAgC,EAChC,4BAA4B,EAC5B,2BAA2B,EAC3B,kCAAkC,CAC1B,CAAA;AAEV,yEAAyE;AACzE,MAAM,MAAM,+BAA+B,GAAG,CAAC,OAAO,oCAAoC,CAAC,CAAC,MAAM,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"rpc-allowlist.d.ts","sourceRoot":"","sources":["../../src/persistence/rpc-allowlist.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AAgBtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,0BAA0B,EAAE,sBA0nCxC,CAAA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,oCAAoC,YAC/C,yBAAyB,EACzB,gCAAgC,EAChC,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,EAC3B,kCAAkC,CAC1B,CAAA;AAEV,yEAAyE;AACzE,MAAM,MAAM,+BAA+B,GAAG,CAAC,OAAO,oCAAoC,CAAC,CAAC,MAAM,CAAC,CAAA"}
|
|
@@ -1216,6 +1216,7 @@ export const LOCAL_FIRST_PERSISTENCE_REPOSITORIES = [
|
|
|
1216
1216
|
'llmCallMetricRepository',
|
|
1217
1217
|
'agentContextSnapshotRepository',
|
|
1218
1218
|
'agentSearchQueryRepository',
|
|
1219
|
+
'agentToolCallRepository',
|
|
1219
1220
|
'provisioningLogRepository',
|
|
1220
1221
|
'subscriptionQuotaCycleRepository',
|
|
1221
1222
|
];
|