@vertesia/common 1.6.0-dev.20260923.085325Z → 1.6.0-dev.20261004.085740Z
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/lib/access-control-values.d.ts +2 -2
- package/lib/access-control-values.d.ts.map +1 -1
- package/lib/access-control-values.js +2 -2
- package/lib/access-control-values.js.map +1 -1
- package/lib/access-control.d.ts +7 -8
- package/lib/access-control.d.ts.map +1 -1
- package/lib/access-control.js +5 -0
- package/lib/access-control.js.map +1 -1
- package/lib/analytics.d.ts +6 -7
- package/lib/analytics.d.ts.map +1 -1
- package/lib/api-contract/components.generated.json +1389 -45
- package/lib/api-schemas/access-control.d.ts +33 -10
- package/lib/api-schemas/access-control.d.ts.map +1 -1
- package/lib/api-schemas/access-control.js +7 -6
- package/lib/api-schemas/access-control.js.map +1 -1
- package/lib/api-schemas/account.d.ts +5 -4
- package/lib/api-schemas/account.d.ts.map +1 -1
- package/lib/api-schemas/account.js.map +1 -1
- package/lib/api-schemas/agent-budget.d.ts +15 -0
- package/lib/api-schemas/agent-budget.d.ts.map +1 -0
- package/lib/api-schemas/agent-budget.js +55 -0
- package/lib/api-schemas/agent-budget.js.map +1 -0
- package/lib/api-schemas/agent-runs.d.ts +1525 -100
- package/lib/api-schemas/agent-runs.d.ts.map +1 -1
- package/lib/api-schemas/agent-runs.js +60 -28
- package/lib/api-schemas/agent-runs.js.map +1 -1
- package/lib/api-schemas/apikey.d.ts +11 -10
- package/lib/api-schemas/apikey.d.ts.map +1 -1
- package/lib/api-schemas/apikey.js.map +1 -1
- package/lib/api-schemas/app-lifecycle.d.ts +13 -0
- package/lib/api-schemas/app-lifecycle.d.ts.map +1 -1
- package/lib/api-schemas/app-lifecycle.js +4 -0
- package/lib/api-schemas/app-lifecycle.js.map +1 -1
- package/lib/api-schemas/app-runtime.d.ts +1821 -108
- package/lib/api-schemas/app-runtime.d.ts.map +1 -1
- package/lib/api-schemas/audit-trail.d.ts +20 -0
- package/lib/api-schemas/audit-trail.d.ts.map +1 -1
- package/lib/api-schemas/audit-trail.js +7 -1
- package/lib/api-schemas/audit-trail.js.map +1 -1
- package/lib/api-schemas/content.d.ts +665 -30
- package/lib/api-schemas/content.d.ts.map +1 -1
- package/lib/api-schemas/content.js +47 -0
- package/lib/api-schemas/content.js.map +1 -1
- package/lib/api-schemas/cost-analytics.d.ts +18 -0
- package/lib/api-schemas/cost-analytics.d.ts.map +1 -1
- package/lib/api-schemas/cost-analytics.js +31 -2
- package/lib/api-schemas/cost-analytics.js.map +1 -1
- package/lib/api-schemas/document-processing.d.ts +381 -18
- package/lib/api-schemas/document-processing.d.ts.map +1 -1
- package/lib/api-schemas/environment.d.ts +0 -5
- package/lib/api-schemas/environment.d.ts.map +1 -1
- package/lib/api-schemas/environment.js +0 -1
- package/lib/api-schemas/environment.js.map +1 -1
- package/lib/api-schemas/events.d.ts +1143 -54
- package/lib/api-schemas/events.d.ts.map +1 -1
- package/lib/api-schemas/group.d.ts +2 -1
- package/lib/api-schemas/group.d.ts.map +1 -1
- package/lib/api-schemas/group.js.map +1 -1
- package/lib/api-schemas/index.d.ts +1 -0
- package/lib/api-schemas/index.d.ts.map +1 -1
- package/lib/api-schemas/index.js +1 -0
- package/lib/api-schemas/index.js.map +1 -1
- package/lib/api-schemas/inference-profile.d.ts +5017 -0
- package/lib/api-schemas/inference-profile.d.ts.map +1 -0
- package/lib/api-schemas/inference-profile.js +135 -0
- package/lib/api-schemas/inference-profile.js.map +1 -0
- package/lib/api-schemas/integrations.d.ts +6 -6
- package/lib/api-schemas/interaction.d.ts +34391 -703
- package/lib/api-schemas/interaction.d.ts.map +1 -1
- package/lib/api-schemas/interaction.js +34 -1
- package/lib/api-schemas/interaction.js.map +1 -1
- package/lib/api-schemas/invites.d.ts +10 -9
- package/lib/api-schemas/invites.d.ts.map +1 -1
- package/lib/api-schemas/invites.js.map +1 -1
- package/lib/api-schemas/process.d.ts +653 -34
- package/lib/api-schemas/process.d.ts.map +1 -1
- package/lib/api-schemas/process.js +66 -0
- package/lib/api-schemas/process.js.map +1 -1
- package/lib/api-schemas/project-configuration.d.ts +1323 -62
- package/lib/api-schemas/project-configuration.d.ts.map +1 -1
- package/lib/api-schemas/project-configuration.js +15 -1
- package/lib/api-schemas/project-configuration.js.map +1 -1
- package/lib/api-schemas/project.d.ts +2031 -116
- package/lib/api-schemas/project.d.ts.map +1 -1
- package/lib/api-schemas/project.js +9 -1
- package/lib/api-schemas/project.js.map +1 -1
- package/lib/api-schemas/quota.d.ts +7 -6
- package/lib/api-schemas/quota.d.ts.map +1 -1
- package/lib/api-schemas/quota.js.map +1 -1
- package/lib/api-schemas/registry.d.ts +27820 -35892
- package/lib/api-schemas/registry.d.ts.map +1 -1
- package/lib/api-schemas/registry.js +55 -5
- package/lib/api-schemas/registry.js.map +1 -1
- package/lib/api-schemas/run-budget.d.ts +52 -0
- package/lib/api-schemas/run-budget.d.ts.map +1 -0
- package/lib/api-schemas/run-budget.js +55 -0
- package/lib/api-schemas/run-budget.js.map +1 -0
- package/lib/api-schemas/store.d.ts +6388 -338
- package/lib/api-schemas/store.d.ts.map +1 -1
- package/lib/api-schemas/store.js +11 -0
- package/lib/api-schemas/store.js.map +1 -1
- package/lib/api-schemas/user.d.ts +9 -8
- package/lib/api-schemas/user.d.ts.map +1 -1
- package/lib/api-schemas/user.js.map +1 -1
- package/lib/api-schemas/view-execution.d.ts +8 -0
- package/lib/api-schemas/view-execution.d.ts.map +1 -1
- package/lib/api-schemas/views.d.ts +14 -0
- package/lib/api-schemas/views.d.ts.map +1 -1
- package/lib/api-schemas/workflow-runs.d.ts +335 -12
- package/lib/api-schemas/workflow-runs.d.ts.map +1 -1
- package/lib/api-schemas/workflow-runs.js +2 -0
- package/lib/api-schemas/workflow-runs.js.map +1 -1
- package/lib/apikey.d.ts +30 -25
- package/lib/apikey.d.ts.map +1 -1
- package/lib/apikey.js.map +1 -1
- package/lib/apps.d.ts +116 -121
- package/lib/apps.d.ts.map +1 -1
- package/lib/apps.js.map +1 -1
- package/lib/audit-trail.d.ts +17 -18
- package/lib/audit-trail.d.ts.map +1 -1
- package/lib/audit-trail.js +2 -0
- package/lib/audit-trail.js.map +1 -1
- package/lib/browser-credentials.d.ts +11 -12
- package/lib/browser-credentials.d.ts.map +1 -1
- package/lib/common.d.ts +17 -24
- package/lib/common.d.ts.map +1 -1
- package/lib/content-query.d.ts +3 -4
- package/lib/content-query.d.ts.map +1 -1
- package/lib/cost-analytics.d.ts +13 -21
- package/lib/cost-analytics.d.ts.map +1 -1
- package/lib/cost-analytics.js +0 -7
- package/lib/cost-analytics.js.map +1 -1
- package/lib/data-platform.d.ts +79 -88
- package/lib/data-platform.d.ts.map +1 -1
- package/lib/data-platform.js.map +1 -1
- package/lib/delegation.d.ts +4 -5
- package/lib/delegation.d.ts.map +1 -1
- package/lib/email.d.ts +15 -17
- package/lib/email.d.ts.map +1 -1
- package/lib/email.js.map +1 -1
- package/lib/embeddings.d.ts +25 -26
- package/lib/embeddings.d.ts.map +1 -1
- package/lib/environment.d.ts +16 -17
- package/lib/environment.d.ts.map +1 -1
- package/lib/environment.js.map +1 -1
- package/lib/facets.d.ts +3 -4
- package/lib/facets.d.ts.map +1 -1
- package/lib/group.d.ts +6 -7
- package/lib/group.d.ts.map +1 -1
- package/lib/group.js.map +1 -1
- package/lib/index.d.ts +3 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/inference-profile.d.ts +17 -0
- package/lib/inference-profile.d.ts.map +1 -0
- package/lib/inference-profile.js +2 -0
- package/lib/inference-profile.js.map +1 -0
- package/lib/integrations.d.ts +19 -20
- package/lib/integrations.d.ts.map +1 -1
- package/lib/integrations.js.map +1 -1
- package/lib/interaction.d.ts +68 -73
- package/lib/interaction.d.ts.map +1 -1
- package/lib/interaction.js.map +1 -1
- package/lib/meters.d.ts +4 -5
- package/lib/meters.d.ts.map +1 -1
- package/lib/oauth-server.d.ts +40 -41
- package/lib/oauth-server.d.ts.map +1 -1
- package/lib/oauth.d.ts +9 -10
- package/lib/oauth.d.ts.map +1 -1
- package/lib/payload.d.ts +11 -14
- package/lib/payload.d.ts.map +1 -1
- package/lib/pending-asks.d.ts +8 -13
- package/lib/pending-asks.d.ts.map +1 -1
- package/lib/pending-asks.js +0 -4
- package/lib/pending-asks.js.map +1 -1
- package/lib/platform-event.d.ts +48 -51
- package/lib/platform-event.d.ts.map +1 -1
- package/lib/platform-event.js.map +1 -1
- package/lib/principal-context.d.ts +3 -3
- package/lib/principal-context.d.ts.map +1 -1
- package/lib/project.d.ts +42 -43
- package/lib/project.d.ts.map +1 -1
- package/lib/project.js.map +1 -1
- package/lib/prompt.d.ts +14 -16
- package/lib/prompt.d.ts.map +1 -1
- package/lib/prompt.js.map +1 -1
- package/lib/query.d.ts +10 -13
- package/lib/query.d.ts.map +1 -1
- package/lib/rate-limiter.d.ts +7 -11
- package/lib/rate-limiter.d.ts.map +1 -1
- package/lib/refs.d.ts +2 -3
- package/lib/refs.d.ts.map +1 -1
- package/lib/refs.js.map +1 -1
- package/lib/roles/types.d.ts +5 -6
- package/lib/roles/types.d.ts.map +1 -1
- package/lib/roles/types.js.map +1 -1
- package/lib/run-budget.d.ts +8 -0
- package/lib/run-budget.d.ts.map +1 -0
- package/lib/run-budget.js +2 -0
- package/lib/run-budget.js.map +1 -0
- package/lib/runs.d.ts +9 -10
- package/lib/runs.d.ts.map +1 -1
- package/lib/secrets.d.ts +20 -21
- package/lib/secrets.d.ts.map +1 -1
- package/lib/store/agent-approval.d.ts +4 -5
- package/lib/store/agent-approval.d.ts.map +1 -1
- package/lib/store/agent-approval.js.map +1 -1
- package/lib/store/agent-run.d.ts +50 -52
- package/lib/store/agent-run.d.ts.map +1 -1
- package/lib/store/agent-run.js.map +1 -1
- package/lib/store/collections.d.ts +11 -12
- package/lib/store/collections.d.ts.map +1 -1
- package/lib/store/collections.js.map +1 -1
- package/lib/store/conversation-state.d.ts +14 -8
- package/lib/store/conversation-state.d.ts.map +1 -1
- package/lib/store/doc-analyzer.d.ts +7 -8
- package/lib/store/doc-analyzer.d.ts.map +1 -1
- package/lib/store/dsl-workflow.d.ts +10 -12
- package/lib/store/dsl-workflow.d.ts.map +1 -1
- package/lib/store/dsl-workflow.js.map +1 -1
- package/lib/store/duration.d.ts +12 -0
- package/lib/store/duration.d.ts.map +1 -0
- package/lib/store/duration.js +2 -0
- package/lib/store/duration.js.map +1 -0
- package/lib/store/grounded-extraction.d.ts +6 -7
- package/lib/store/grounded-extraction.d.ts.map +1 -1
- package/lib/store/intake-policy-schema.generated.d.ts.map +1 -1
- package/lib/store/intake-policy-schema.generated.js +143 -2
- package/lib/store/intake-policy-schema.generated.js.map +1 -1
- package/lib/store/process.d.ts +70 -69
- package/lib/store/process.d.ts.map +1 -1
- package/lib/store/process.js.map +1 -1
- package/lib/store/rendering.d.ts +6 -12
- package/lib/store/rendering.d.ts.map +1 -1
- package/lib/store/rendering.js +0 -5
- package/lib/store/rendering.js.map +1 -1
- package/lib/store/signals.d.ts +43 -0
- package/lib/store/signals.d.ts.map +1 -1
- package/lib/store/signals.js +6 -1
- package/lib/store/signals.js.map +1 -1
- package/lib/store/store.d.ts +92 -91
- package/lib/store/store.d.ts.map +1 -1
- package/lib/store/store.js.map +1 -1
- package/lib/store/task.d.ts +10 -14
- package/lib/store/task.d.ts.map +1 -1
- package/lib/store/workflow.d.ts +35 -41
- package/lib/store/workflow.d.ts.map +1 -1
- package/lib/store/workflow.js.map +1 -1
- package/lib/sts-token-types.d.ts +14 -19
- package/lib/sts-token-types.d.ts.map +1 -1
- package/lib/tools.d.ts +12 -13
- package/lib/tools.d.ts.map +1 -1
- package/lib/transient-tokens.d.ts +3 -3
- package/lib/transient-tokens.d.ts.map +1 -1
- package/lib/user.d.ts +17 -20
- package/lib/user.d.ts.map +1 -1
- package/lib/user.js.map +1 -1
- package/lib/vertesia-common.js +2 -2
- package/lib/vertesia-common.js.map +1 -1
- package/lib/views.d.ts +61 -64
- package/lib/views.d.ts.map +1 -1
- package/lib/views.js.map +1 -1
- package/lib/wire-types.generated.d.ts +11231 -0
- package/lib/wire-types.generated.d.ts.map +1 -0
- package/lib/wire-types.generated.js +4 -0
- package/lib/wire-types.generated.js.map +1 -0
- package/lib/workflow-analytics.d.ts +21 -19
- package/lib/workflow-analytics.d.ts.map +1 -1
- package/lib/workflow-analytics.js +2 -2
- package/lib/workflow-analytics.js.map +1 -1
- package/package.json +15 -10
- package/src/access-control-values.ts +2 -2
- package/src/access-control.ts +7 -15
- package/src/analytics.ts +6 -13
- package/src/api-contract/components.generated.json +1389 -45
- package/src/api-schemas/access-control.ts +18 -16
- package/src/api-schemas/account.ts +5 -4
- package/src/api-schemas/agent-budget.ts +60 -0
- package/src/api-schemas/agent-runs.ts +63 -27
- package/src/api-schemas/apikey.ts +11 -10
- package/src/api-schemas/app-lifecycle.ts +5 -0
- package/src/api-schemas/audit-trail.ts +7 -1
- package/src/api-schemas/content.ts +55 -0
- package/src/api-schemas/cost-analytics.ts +34 -2
- package/src/api-schemas/environment.ts +0 -1
- package/src/api-schemas/group.ts +2 -1
- package/src/api-schemas/index.ts +1 -0
- package/src/api-schemas/inference-profile.ts +151 -0
- package/src/api-schemas/interaction.ts +40 -1
- package/src/api-schemas/invites.ts +10 -9
- package/src/api-schemas/process.ts +78 -2
- package/src/api-schemas/project-configuration.ts +19 -1
- package/src/api-schemas/project.ts +19 -10
- package/src/api-schemas/quota.ts +7 -6
- package/src/api-schemas/registry.ts +131 -33
- package/src/api-schemas/run-budget.ts +60 -0
- package/src/api-schemas/store.ts +12 -0
- package/src/api-schemas/user.ts +9 -8
- package/src/api-schemas/workflow-runs.ts +2 -0
- package/src/apikey.ts +30 -39
- package/src/apps.ts +116 -239
- package/src/audit-trail.ts +18 -33
- package/src/browser-credentials.ts +11 -23
- package/src/common.ts +17 -37
- package/src/content-query.ts +3 -4
- package/src/cost-analytics.ts +13 -35
- package/src/data-platform.ts +79 -168
- package/src/delegation.ts +4 -9
- package/src/email.ts +15 -29
- package/src/embeddings.ts +25 -51
- package/src/environment.ts +16 -33
- package/src/facets.ts +3 -4
- package/src/group.ts +6 -13
- package/src/index.ts +27 -0
- package/src/inference-profile.ts +20 -0
- package/src/integrations.ts +21 -41
- package/src/interaction.ts +68 -137
- package/src/meters.ts +4 -9
- package/src/oauth-server.ts +40 -81
- package/src/oauth.ts +9 -19
- package/src/payload.ts +11 -25
- package/src/pending-asks.ts +8 -22
- package/src/platform-event.ts +48 -97
- package/src/principal-context.ts +3 -3
- package/src/project.ts +43 -86
- package/src/prompt.ts +14 -31
- package/src/query.ts +10 -20
- package/src/rate-limiter.ts +7 -19
- package/src/refs.ts +2 -3
- package/src/roles/types.ts +5 -11
- package/src/run-budget.ts +8 -0
- package/src/runs.ts +9 -19
- package/src/secrets.ts +20 -41
- package/src/store/agent-approval.ts +4 -9
- package/src/store/agent-run.ts +53 -99
- package/src/store/collections.ts +11 -23
- package/src/store/conversation-state.ts +15 -15
- package/src/store/doc-analyzer.ts +7 -15
- package/src/store/dsl-workflow.ts +10 -23
- package/src/store/duration.ts +45 -0
- package/src/store/grounded-extraction.ts +6 -13
- package/src/store/intake-policy-schema.generated.ts +148 -2
- package/src/store/process.ts +70 -140
- package/src/store/rendering.ts +6 -19
- package/src/store/signals.ts +48 -0
- package/src/store/store.ts +92 -181
- package/src/store/task.ts +10 -24
- package/src/store/workflow.ts +35 -71
- package/src/sts-token-types.ts +14 -33
- package/src/tools.ts +12 -25
- package/src/transient-tokens.ts +3 -3
- package/src/user.ts +17 -39
- package/src/views.ts +61 -125
- package/src/wire-types.generated.ts +11889 -0
- package/src/workflow-analytics.ts +21 -19
- package/src/agent-resources.test.ts +0 -89
- package/src/api-contract/components.contract.test.ts +0 -99
- package/src/api-schemas/access-control.contract.test.ts +0 -209
- package/src/api-schemas/account-apikey.test.ts +0 -60
- package/src/api-schemas/account.contract.test.ts +0 -319
- package/src/api-schemas/adapter-edge-cases.test.ts +0 -499
- package/src/api-schemas/agent-communication.contract.test.ts +0 -90
- package/src/api-schemas/agent-history.contract.test.ts +0 -42
- package/src/api-schemas/agent-runs.contract.test.ts +0 -240
- package/src/api-schemas/api-discriminators.test.ts +0 -185
- package/src/api-schemas/apikey.contract.test.ts +0 -270
- package/src/api-schemas/app-delete-summary.contract.test.ts +0 -67
- package/src/api-schemas/bulk-operation.contract.test.ts +0 -39
- package/src/api-schemas/bundle-isolation.test.ts +0 -44
- package/src/api-schemas/commands.contract.test.ts +0 -51
- package/src/api-schemas/cost-analytics.contract.test.ts +0 -64
- package/src/api-schemas/dashboard.contract.test.ts +0 -138
- package/src/api-schemas/data-store.contract.test.ts +0 -97
- package/src/api-schemas/document-processing.contract.test.ts +0 -76
- package/src/api-schemas/emit-json-schema.test.ts +0 -36
- package/src/api-schemas/environment.contract.test.ts +0 -202
- package/src/api-schemas/group.contract.test.ts +0 -205
- package/src/api-schemas/indexing.contract.test.ts +0 -122
- package/src/api-schemas/interaction.contract.test.ts +0 -307
- package/src/api-schemas/invites.contract.test.ts +0 -268
- package/src/api-schemas/llumiverse.contract.test.ts +0 -179
- package/src/api-schemas/mcp-api-key.contract.test.ts +0 -125
- package/src/api-schemas/oauth.contract.test.ts +0 -181
- package/src/api-schemas/parameters.test.ts +0 -402
- package/src/api-schemas/process.contract.test.ts +0 -115
- package/src/api-schemas/project.contract.test.ts +0 -472
- package/src/api-schemas/pruning-limits.test.ts +0 -189
- package/src/api-schemas/quota.contract.test.ts +0 -147
- package/src/api-schemas/registry-groups.test.ts +0 -99
- package/src/api-schemas/response-pruning.test.ts +0 -260
- package/src/api-schemas/store.contract.test.ts +0 -378
- package/src/api-schemas/sts.contract.test.ts +0 -112
- package/src/api-schemas/user.contract.test.ts +0 -197
- package/src/api-schemas/views.contract.test.ts +0 -112
- package/src/api-schemas/zeno-response-contracts.test.ts +0 -380
- package/src/apps.test.ts +0 -89
- package/src/oauth-scopes.test.ts +0 -15
- package/src/roles.test.ts +0 -33
- package/src/schema-for-extraction.test.ts +0 -191
- package/src/store/agent-approval.test.ts +0 -18
- package/src/store/content-type-editing.test.ts +0 -17
- package/src/store/ms.d.ts +0 -42
- package/src/store/schedule.test.ts +0 -59
- package/src/store/workflow.test.ts +0 -640
- package/src/versions.test.ts +0 -13
|
@@ -23,8 +23,8 @@ export enum AgentEventType {
|
|
|
23
23
|
TurnEvaluation = 'turn_evaluation',
|
|
24
24
|
/** A user rating on an agent run, emitted by the server when it is recorded */
|
|
25
25
|
Feedback = 'feedback',
|
|
26
|
-
/**
|
|
27
|
-
|
|
26
|
+
/** LLM evaluation verdict for one turn, emitted by the evaluation workflow */
|
|
27
|
+
TurnLlmEvaluation = 'turn_llm_evaluation',
|
|
28
28
|
/** The stall circuit breaker acted: a corrective was injected, or the loop was stopped */
|
|
29
29
|
StallBreaker = 'stall_breaker',
|
|
30
30
|
}
|
|
@@ -244,6 +244,8 @@ interface BaseLlmCallEvent extends BaseAgentEvent {
|
|
|
244
244
|
attemptNumber?: number;
|
|
245
245
|
/** Error type if failed */
|
|
246
246
|
errorType?: string;
|
|
247
|
+
/** The interaction run that recorded the call, and its billing event (its `request_id`) */
|
|
248
|
+
executionRunId?: string;
|
|
247
249
|
}
|
|
248
250
|
|
|
249
251
|
export interface LlmCallEvent extends BaseLlmCallEvent {}
|
|
@@ -442,38 +444,38 @@ export interface FeedbackEvent extends BaseAgentEvent {
|
|
|
442
444
|
replaced: boolean;
|
|
443
445
|
}
|
|
444
446
|
|
|
445
|
-
/** Why
|
|
446
|
-
export type
|
|
447
|
+
/** Why a run was selected for LLM evaluation. */
|
|
448
|
+
export type EvaluationGateReason = 'signal' | 'sample' | 'opt_in' | 'always_on';
|
|
447
449
|
|
|
448
|
-
/**
|
|
449
|
-
export type
|
|
450
|
+
/** Outcome of an LLM evaluation run. */
|
|
451
|
+
export type EvaluationOutcome = 'evaluated' | 'skipped_unarchived' | 'failed';
|
|
450
452
|
|
|
451
|
-
/**
|
|
452
|
-
export type
|
|
453
|
+
/** LLM evaluation verdict for a turn. */
|
|
454
|
+
export type EvaluationVerdict = 'success' | 'partial' | 'failure';
|
|
453
455
|
|
|
454
456
|
/**
|
|
455
|
-
* Emitted by the
|
|
457
|
+
* Emitted by the evaluator workflow for each turn it evaluated (or once with a non-evaluated outcome).
|
|
456
458
|
*/
|
|
457
|
-
export interface
|
|
458
|
-
eventType: AgentEventType.
|
|
459
|
-
/** Evaluation revision the
|
|
459
|
+
export interface TurnLlmEvaluationEvent extends BaseAgentEvent {
|
|
460
|
+
eventType: AgentEventType.TurnLlmEvaluation;
|
|
461
|
+
/** Evaluation revision the evaluator run was started for */
|
|
460
462
|
evaluationRev: number;
|
|
461
463
|
workstreamId: string;
|
|
462
|
-
/** Turn
|
|
464
|
+
/** Turn evaluated; 0 when the outcome is not `evaluated` */
|
|
463
465
|
turnSeq: number;
|
|
464
|
-
gate:
|
|
466
|
+
gate: EvaluationGateReason;
|
|
465
467
|
/** Sampling rate in force when the gate was evaluated */
|
|
466
468
|
sampleRate: number;
|
|
467
469
|
/** Probability that this run was selected, for weighted calibration */
|
|
468
470
|
selectedProbability: number;
|
|
469
|
-
outcome:
|
|
470
|
-
verdict?:
|
|
471
|
+
outcome: EvaluationOutcome;
|
|
472
|
+
verdict?: EvaluationVerdict;
|
|
471
473
|
/** 0..1 */
|
|
472
474
|
score?: number;
|
|
473
475
|
reasons?: string[];
|
|
474
|
-
/** Version of the
|
|
476
|
+
/** Version of the evaluator prompt */
|
|
475
477
|
promptVersion: string;
|
|
476
|
-
/** Detector version of the evaluation the
|
|
478
|
+
/** Detector version of the evaluation the evaluator was compared against */
|
|
477
479
|
detectorVersion?: number;
|
|
478
480
|
}
|
|
479
481
|
|
|
@@ -509,7 +511,7 @@ export type AgentEvent =
|
|
|
509
511
|
| ToolCallEvent
|
|
510
512
|
| TurnEvaluationEvent
|
|
511
513
|
| FeedbackEvent
|
|
512
|
-
|
|
|
514
|
+
| TurnLlmEvaluationEvent
|
|
513
515
|
| StallBreakerEvent;
|
|
514
516
|
|
|
515
517
|
/**
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { type AgentResourceReference, normalizeAgentResources } from './interaction.js';
|
|
3
|
-
import { AgentMessageType, getResourcesFromMessage } from './store/workflow.js';
|
|
4
|
-
|
|
5
|
-
const validRef: AgentResourceReference = {
|
|
6
|
-
type: 'document',
|
|
7
|
-
id: 'doc-1',
|
|
8
|
-
label: 'My Document',
|
|
9
|
-
action: 'created',
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
describe('normalizeAgentResources', () => {
|
|
13
|
-
it('returns an empty array for non-array input', () => {
|
|
14
|
-
expect(normalizeAgentResources(undefined)).toEqual([]);
|
|
15
|
-
expect(normalizeAgentResources(null)).toEqual([]);
|
|
16
|
-
expect(normalizeAgentResources('nope')).toEqual([]);
|
|
17
|
-
expect(normalizeAgentResources({})).toEqual([]);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('keeps a well-formed reference', () => {
|
|
21
|
-
expect(normalizeAgentResources([validRef])).toEqual([validRef]);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('preserves revision_id when present and non-empty', () => {
|
|
25
|
-
const ref = { ...validRef, revision_id: 'rev-9' };
|
|
26
|
-
expect(normalizeAgentResources([ref])).toEqual([ref]);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('drops an empty revision_id rather than keeping it', () => {
|
|
30
|
-
const result = normalizeAgentResources([{ ...validRef, revision_id: '' }]);
|
|
31
|
-
expect(result[0]).not.toHaveProperty('revision_id');
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('falls back to the id when the label is missing or empty', () => {
|
|
35
|
-
const result = normalizeAgentResources([{ type: 'collection', id: 'col-1', action: 'updated' }]);
|
|
36
|
-
expect(result).toEqual([{ type: 'collection', id: 'col-1', label: 'col-1', action: 'updated' }]);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('drops entries with an unknown type or action', () => {
|
|
40
|
-
const result = normalizeAgentResources([
|
|
41
|
-
{ type: 'artifact', id: 'a', label: 'a', action: 'created' },
|
|
42
|
-
{ type: 'document', id: 'd', label: 'd', action: 'viewed' },
|
|
43
|
-
{ type: 'document', id: '', label: 'd', action: 'created' },
|
|
44
|
-
validRef,
|
|
45
|
-
]);
|
|
46
|
-
expect(result).toEqual([validRef]);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('accepts every supported resource type', () => {
|
|
50
|
-
const types = [
|
|
51
|
-
'document',
|
|
52
|
-
'collection',
|
|
53
|
-
'content_type',
|
|
54
|
-
'interaction',
|
|
55
|
-
'prompt',
|
|
56
|
-
'agent',
|
|
57
|
-
'workflow',
|
|
58
|
-
'process',
|
|
59
|
-
'process_run',
|
|
60
|
-
'interaction_run',
|
|
61
|
-
'view',
|
|
62
|
-
] as const;
|
|
63
|
-
const input = types.map((type, i) => ({ type, id: `id-${i}`, label: `L${i}`, action: 'created' }));
|
|
64
|
-
expect(normalizeAgentResources(input)).toHaveLength(types.length);
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
describe('getResourcesFromMessage', () => {
|
|
69
|
-
it('reads resources from message details', () => {
|
|
70
|
-
const msg = {
|
|
71
|
-
timestamp: 0,
|
|
72
|
-
workflow_run_id: 'run-1',
|
|
73
|
-
type: AgentMessageType.THOUGHT,
|
|
74
|
-
message: '',
|
|
75
|
-
details: { event_class: 'activity', resources: [validRef] },
|
|
76
|
-
};
|
|
77
|
-
expect(getResourcesFromMessage(msg)).toEqual([validRef]);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('returns an empty array when details or resources are absent', () => {
|
|
81
|
-
const msg = {
|
|
82
|
-
timestamp: 0,
|
|
83
|
-
workflow_run_id: 'run-1',
|
|
84
|
-
type: AgentMessageType.COMPLETE,
|
|
85
|
-
message: '',
|
|
86
|
-
};
|
|
87
|
-
expect(getResourcesFromMessage(msg)).toEqual([]);
|
|
88
|
-
});
|
|
89
|
-
});
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { execFileSync } from 'node:child_process';
|
|
2
|
-
import { readFileSync } from 'node:fs';
|
|
3
|
-
import { describe, expect, it } from 'vitest';
|
|
4
|
-
import { buildApiSchemaComponents } from '../api-schemas/registry.js';
|
|
5
|
-
import { ApiSchemaComponents } from './index.js';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Guards the two properties that make `components.generated.json` safe to serve from.
|
|
9
|
-
*
|
|
10
|
-
* 1. It is COMPILED OUTPUT, not a second source of truth. The Zod registry remains the authority;
|
|
11
|
-
* the artifact is its emission. If they diverge, servers enforce a contract the spec no longer
|
|
12
|
-
* describes — silently, since nothing else compares them.
|
|
13
|
-
* 2. Nothing reachable from the subpath imports zod. That is the entire reason the artifact exists:
|
|
14
|
-
* building the Zod graph costs ~85 MB of heap in every process that enforces contracts, which is
|
|
15
|
-
* enough to push a small API process past its memory limit.
|
|
16
|
-
*/
|
|
17
|
-
describe('api-contract components artifact', () => {
|
|
18
|
-
it('matches the Zod registry exactly', { timeout: 30_000 }, () => {
|
|
19
|
-
// Fails when an API schema was edited without re-running the generator, and equally when the
|
|
20
|
-
// artifact was regenerated but not committed — a CI checkout then has new Zod against old JSON.
|
|
21
|
-
// Rebuilding the full registry is CPU-heavy and can exceed Vitest's default timeout under parallel CI.
|
|
22
|
-
expect(
|
|
23
|
-
ApiSchemaComponents,
|
|
24
|
-
'components.generated.json is stale — run `pnpm run gen:schemas` in packages/common',
|
|
25
|
-
).toEqual(buildApiSchemaComponents());
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('round-trips through JSON without loss', () => {
|
|
29
|
-
// The artifact is only equivalent to the in-memory emission if every value survives
|
|
30
|
-
// serialization. An `undefined` property would vanish on write and change the contract.
|
|
31
|
-
expect(JSON.parse(JSON.stringify(ApiSchemaComponents))).toEqual(ApiSchemaComponents);
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
const BUILT_ENTRY = new URL('../../lib/api-contract/index.js', import.meta.url).pathname;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Every module Node actually resolves while importing the built subpath.
|
|
39
|
-
*
|
|
40
|
-
* Inspecting the entry file alone is not enough: it imports `adapter.js` and `parameters.js`, and if
|
|
41
|
-
* either ever grows a zod import — directly or through a package of its own — the entry's own text
|
|
42
|
-
* still mentions nothing and a text check passes while the servers load zod again. A `resolve` hook
|
|
43
|
-
* records the real graph, transitively, including everything under `node_modules`.
|
|
44
|
-
*
|
|
45
|
-
* Run in a child process because the hook has to be installed before the first import, and this test
|
|
46
|
-
* file has already imported the registry (and therefore zod) into its own process.
|
|
47
|
-
*/
|
|
48
|
-
function resolveRuntimeGraph(entry: string): string[] {
|
|
49
|
-
const probe = `
|
|
50
|
-
import { registerHooks } from 'node:module';
|
|
51
|
-
const resolved = [];
|
|
52
|
-
registerHooks({
|
|
53
|
-
resolve(specifier, context, nextResolve) {
|
|
54
|
-
const result = nextResolve(specifier, context);
|
|
55
|
-
resolved.push(result.url);
|
|
56
|
-
return result;
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
|
-
await import(${JSON.stringify(entry)});
|
|
60
|
-
console.log(JSON.stringify(resolved));
|
|
61
|
-
`;
|
|
62
|
-
const out = execFileSync(process.execPath, ['--input-type=module', '-e', probe], { encoding: 'utf8' });
|
|
63
|
-
return JSON.parse(out.trim().split('\n').pop() as string) as string[];
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const packageOf = (url: string): string | undefined =>
|
|
67
|
-
url.match(/node_modules\/(?:\.pnpm\/[^/]+\/node_modules\/)?((?:@[^/]+\/)?[^/]+)/)?.[1];
|
|
68
|
-
|
|
69
|
-
describe('api-contract zod isolation', () => {
|
|
70
|
-
it('does not reference zod or the Zod registry from the entry file', () => {
|
|
71
|
-
// `index.ts` imports `ApiComponentName`/`ApiComponentType` from the registry with
|
|
72
|
-
// `import type`, which tsc elides. Dropping the `type` keyword would compile fine and quietly
|
|
73
|
-
// pull the whole graph back into every server, so assert on the emitted JavaScript.
|
|
74
|
-
const emitted = readFileSync(BUILT_ENTRY, 'utf8');
|
|
75
|
-
for (const marker of ['zod', '_zod', 'ZodObject', 'registry.js']) {
|
|
76
|
-
expect(emitted, `built api-contract entry must not reference '${marker}'`).not.toContain(marker);
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('loads no zod module anywhere in its transitive runtime graph', () => {
|
|
81
|
-
const graph = resolveRuntimeGraph(BUILT_ENTRY);
|
|
82
|
-
// Guards against a vacuous pass: an entry that failed to import, or a hook that recorded
|
|
83
|
-
// nothing, would otherwise satisfy every assertion below.
|
|
84
|
-
expect(graph.length, 'resolve hook recorded no modules — the probe did not run').toBeGreaterThan(10);
|
|
85
|
-
|
|
86
|
-
const packages = [...new Set(graph.map(packageOf).filter(Boolean))].sort();
|
|
87
|
-
const offenders = graph.filter((url) => /node_modules\/(?:\.pnpm\/)?zod[@/]/.test(url));
|
|
88
|
-
expect(
|
|
89
|
-
offenders,
|
|
90
|
-
`zod reached the api-contract runtime graph — the ~85 MB object graph is back in every ` +
|
|
91
|
-
`server that enforces contracts. Packages resolved: ${packages.join(', ')}`,
|
|
92
|
-
).toEqual([]);
|
|
93
|
-
|
|
94
|
-
expect(
|
|
95
|
-
graph.filter((url) => /api-schemas\/registry\.js$/.test(url)),
|
|
96
|
-
'the Zod registry is in the runtime graph — an `import type` lost its `type` keyword',
|
|
97
|
-
).toEqual([]);
|
|
98
|
-
});
|
|
99
|
-
});
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import { Ajv2020 } from 'ajv/dist/2020.js';
|
|
2
|
-
import { describe, expect, it } from 'vitest';
|
|
3
|
-
import {
|
|
4
|
-
type ACECreatePayload,
|
|
5
|
-
type ACEUpdatePayload,
|
|
6
|
-
type AccessControlEntry,
|
|
7
|
-
AccessControlPrincipalType,
|
|
8
|
-
AccessControlResourceType,
|
|
9
|
-
Permission,
|
|
10
|
-
} from '../access-control.js';
|
|
11
|
-
import type { RoleDefinition, SystemRoleDefinition } from '../roles/types.js';
|
|
12
|
-
import type {
|
|
13
|
-
AccessControlEntryArrayFromSchema,
|
|
14
|
-
RoleDefinitionArrayFromSchema,
|
|
15
|
-
SystemRoleDefinitionArrayFromSchema,
|
|
16
|
-
} from './access-control.js';
|
|
17
|
-
import type { JsonObject } from './adapter.js';
|
|
18
|
-
import { ApiSchemaComponents, apiComponentRef, validateApiRequest, validateApiResponse } from './registry.js';
|
|
19
|
-
|
|
20
|
-
/** Exact type identity — `extends` in both directions is too weak (any/unknown slip through). */
|
|
21
|
-
type Equals<A, B> = (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2 ? true : false;
|
|
22
|
-
function assertType<T extends true>(_ok: T): void {}
|
|
23
|
-
|
|
24
|
-
function compile(name: string) {
|
|
25
|
-
const ajv = new Ajv2020({ strictSchema: false, allErrors: true });
|
|
26
|
-
ajv.addSchema({ $id: 'vertesia://openapi', components: { schemas: ApiSchemaComponents } });
|
|
27
|
-
return ajv.compile({ $ref: `vertesia://openapi${apiComponentRef(name as never)}` });
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const VALID_ACE = {
|
|
31
|
-
id: 'ace1',
|
|
32
|
-
role: 'owner',
|
|
33
|
-
resource_type: AccessControlResourceType.account,
|
|
34
|
-
resource: '68b1779130afe5403a1589ba',
|
|
35
|
-
principal_type: AccessControlPrincipalType.user,
|
|
36
|
-
principal: '68b1779130afe5403a1589bb',
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const VALID_ROLE = { name: 'owner', permissions: ['account:admin'], domain: 'system' };
|
|
40
|
-
|
|
41
|
-
describe('gate 1 — the schema is the single source of truth for the public access-control types', () => {
|
|
42
|
-
it('publishes the exact schema-derived type, not a hand-written twin', () => {
|
|
43
|
-
assertType<Equals<AccessControlEntryArrayFromSchema, AccessControlEntry[]>>(true);
|
|
44
|
-
assertType<Equals<RoleDefinitionArrayFromSchema, RoleDefinition[]>>(true);
|
|
45
|
-
assertType<Equals<SystemRoleDefinitionArrayFromSchema, SystemRoleDefinition[]>>(true);
|
|
46
|
-
expect(true).toBe(true);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('derives both ACE payloads from the entry rather than restating ten fields', () => {
|
|
50
|
-
// `ACECreatePayload extends Omit<AccessControlEntry, 'created_at' | 'updated_at' | 'id'>` is
|
|
51
|
-
// what the hand-written type said; `.omit()` is the literal translation, and the right
|
|
52
|
-
// operator when the derived shape is almost everything.
|
|
53
|
-
assertType<Equals<ACECreatePayload['role'], AccessControlEntry['role']>>(true);
|
|
54
|
-
assertType<Equals<ACECreatePayload['conditions'], AccessControlEntry['conditions']>>(true);
|
|
55
|
-
assertType<Equals<ACEUpdatePayload['role'], string | undefined>>(true);
|
|
56
|
-
// The three server-owned fields are what the omit leaves behind.
|
|
57
|
-
assertType<Equals<Extract<keyof ACECreatePayload, 'id' | 'created_at' | 'updated_at'>, never>>(true);
|
|
58
|
-
expect(true).toBe(true);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('narrows permissions on the system role view without restating the shape', () => {
|
|
62
|
-
// `.extend()` overriding one property, which is what `interface SystemRoleDefinition extends
|
|
63
|
-
// RoleDefinition` did. Overriding keeps the property's position, so the published order holds.
|
|
64
|
-
assertType<Equals<SystemRoleDefinition['name'], RoleDefinition['name']>>(true);
|
|
65
|
-
assertType<Equals<SystemRoleDefinition['domain'], RoleDefinition['domain']>>(true);
|
|
66
|
-
assertType<Equals<RoleDefinition['permissions'], string[]>>(true);
|
|
67
|
-
// `SystemRoleDefinition['permissions']` is `Permission[]` — asserted by assignment in both
|
|
68
|
-
// directions rather than by `Equals`, which distinguishes an enum type from the union of its
|
|
69
|
-
// members even though tsc reports them under the same name.
|
|
70
|
-
const fromEnum: SystemRoleDefinition['permissions'] = [Permission.account_admin];
|
|
71
|
-
const toEnum: Permission[] = fromEnum;
|
|
72
|
-
// And it is genuinely narrower than the base component: an ABAC role name is a valid
|
|
73
|
-
// `RoleDefinition` permission and not a valid system one.
|
|
74
|
-
const abac: RoleDefinition['permissions'] = ['content:reader'];
|
|
75
|
-
// @ts-expect-error 'content:reader' is not a Permission
|
|
76
|
-
const rejected: SystemRoleDefinition['permissions'] = abac;
|
|
77
|
-
expect([toEnum, rejected]).toEqual([['account:admin'], ['content:reader']]);
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
describe('gate 2 — the published components match the closure the types come from', () => {
|
|
82
|
-
it('keeps the enums as shared components rather than inlining them per property', () => {
|
|
83
|
-
// A named component becomes ONE reusable Java/Go enum; an inline copy becomes an anonymous
|
|
84
|
-
// type per property. These names are already in the published document, so keeping them is
|
|
85
|
-
// also what avoids a breaking rename for everyone generating from it.
|
|
86
|
-
const props = ApiSchemaComponents.AccessControlEntry.properties as Record<string, JsonObject>;
|
|
87
|
-
expect(props.resource_type).toEqual({ $ref: '#/components/schemas/AccessControlResourceType' });
|
|
88
|
-
expect(props.principal_type).toEqual({ $ref: '#/components/schemas/AccessControlPrincipalType' });
|
|
89
|
-
expect(ApiSchemaComponents.AccessControlResourceType.enum).toContain('content_set');
|
|
90
|
-
expect(ApiSchemaComponents.Permission.enum).toContain('account:admin');
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it('closes AceConditions, which the display-name fields would otherwise slip through', () => {
|
|
94
|
-
// Listed in STRICT_COMPONENTS by name: it is a hoisted component, so the parent entry's
|
|
95
|
-
// strict policy does not reach it.
|
|
96
|
-
expect(ApiSchemaComponents.AceConditions.additionalProperties).toBe(false);
|
|
97
|
-
expect(Object.keys(ApiSchemaComponents.AceConditions.properties as JsonObject)).toEqual([
|
|
98
|
-
'principal_props',
|
|
99
|
-
'resource_props',
|
|
100
|
-
'scope',
|
|
101
|
-
]);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it('publishes PropertyConditions as the map it is', () => {
|
|
105
|
-
// It used to be a `$ref` to a synthesized `PropertyConditionValueMap` — an artifact of
|
|
106
|
-
// deriving a `Record<>` alias through a second alias. The indirection is gone; the value
|
|
107
|
-
// schema is still its own component so the "deliberately unconstrained" statement has one
|
|
108
|
-
// place to live.
|
|
109
|
-
expect(ApiSchemaComponents.PropertyConditions.additionalProperties).toEqual({
|
|
110
|
-
$ref: '#/components/schemas/PropertyConditionValue',
|
|
111
|
-
});
|
|
112
|
-
expect(Object.keys(ApiSchemaComponents)).not.toContain('PropertyConditionValueMap');
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
it('leaves the ACE timestamps as plain strings', () => {
|
|
116
|
-
// Deliberately NOT tightened to `format: date-time` the way User and UserGroup were:
|
|
117
|
-
// `expires_at` shares the declaration and is written straight from a payload, so a stored
|
|
118
|
-
// value AJV would now reject is a real possibility rather than a hypothetical one.
|
|
119
|
-
const props = ApiSchemaComponents.AccessControlEntry.properties as Record<string, JsonObject>;
|
|
120
|
-
expect(props.created_at).toEqual({ type: 'string' });
|
|
121
|
-
expect(props.expires_at).toEqual({ type: 'string' });
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
describe('gate 3 — AJV validates the same canonical objects that are published', () => {
|
|
126
|
-
it('accepts a minimal entry and rejects a missing required field', () => {
|
|
127
|
-
const validate = compile('AccessControlEntry');
|
|
128
|
-
expect(validate(VALID_ACE)).toBe(true);
|
|
129
|
-
const { principal: _dropped, ...incomplete } = VALID_ACE;
|
|
130
|
-
expect(validate(incomplete)).toBe(false);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
it('rejects the display names the sub-document holds but the contract does not declare', () => {
|
|
134
|
-
const validate = compile('AccessControlEntry');
|
|
135
|
-
expect(validate({ ...VALID_ACE, conditions: { principal_props: { team: 'eng' } } })).toBe(true);
|
|
136
|
-
expect(validate({ ...VALID_ACE, conditions: { principal_name: 'Engineering staff' } })).toBe(false);
|
|
137
|
-
expect(validate({ ...VALID_ACE, conditions: { resource_name: 'Confidential docs' } })).toBe(false);
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it('rejects the internal fields a serialized document would have leaked', () => {
|
|
141
|
-
const validate = compile('AccessControlEntry');
|
|
142
|
-
expect(validate({ ...VALID_ACE, _id: 'deadbeef' })).toBe(false);
|
|
143
|
-
expect(validate({ ...VALID_ACE, type: 'legacy' })).toBe(false);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it('accepts any condition value, which is the point of leaving it unconstrained', () => {
|
|
147
|
-
const validate = compile('AccessControlEntry');
|
|
148
|
-
for (const value of [5, 'engineering', { $gte: 5 }, ['us-east'], '$principal.access_level', null]) {
|
|
149
|
-
expect(validate({ ...VALID_ACE, conditions: { resource_props: { key: value } } })).toBe(true);
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
it('requires the five identifying fields on a create payload and none on an update', () => {
|
|
154
|
-
const create = compile('ACECreatePayload');
|
|
155
|
-
const { id: _id, ...payload } = VALID_ACE;
|
|
156
|
-
expect(create(payload)).toBe(true);
|
|
157
|
-
// `id` and the timestamps are server-owned; the closed payload rejects them outright.
|
|
158
|
-
expect(create(VALID_ACE)).toBe(false);
|
|
159
|
-
expect(create({ role: 'owner' })).toBe(false);
|
|
160
|
-
|
|
161
|
-
const update = compile('ACEUpdatePayload');
|
|
162
|
-
expect(update({})).toBe(true);
|
|
163
|
-
expect(update({ role: 'reader' })).toBe(true);
|
|
164
|
-
expect(update({ rogue_field: 1 })).toBe(false);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it('constrains a system role to the Permission enum and a plain role to any string', () => {
|
|
168
|
-
expect(compile('RoleDefinition')(VALID_ROLE)).toBe(true);
|
|
169
|
-
expect(compile('RoleDefinition')({ ...VALID_ROLE, permissions: ['content:reader'] })).toBe(true);
|
|
170
|
-
expect(compile('SystemRoleDefinition')(VALID_ROLE)).toBe(true);
|
|
171
|
-
// 'content:reader' is an ABAC role name, not a Permission — which is exactly the distinction
|
|
172
|
-
// the two components exist to draw.
|
|
173
|
-
expect(compile('SystemRoleDefinition')({ ...VALID_ROLE, permissions: ['content:reader'] })).toBe(false);
|
|
174
|
-
expect(compile('RoleDefinition')({ ...VALID_ROLE, domain: 'billing' })).toBe(false);
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
describe('gate 4 — runtime enforcement uses the published components', () => {
|
|
179
|
-
it('checks every member of a listing against the same entry component', () => {
|
|
180
|
-
expect(validateApiResponse('AccessControlEntryArray', [VALID_ACE, VALID_ACE]).valid).toBe(true);
|
|
181
|
-
expect(validateApiResponse('AccessControlEntryArray', []).valid).toBe(true);
|
|
182
|
-
// One entry still carrying its display name is what the unmapped listing would have produced.
|
|
183
|
-
const leaked = { ...VALID_ACE, conditions: { principal_name: 'Everyone' } };
|
|
184
|
-
expect(validateApiResponse('AccessControlEntryArray', [VALID_ACE, leaked]).valid).toBe(false);
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
it('rejects an undeclared update field without removing it', () => {
|
|
188
|
-
const payload: Record<string, unknown> = { role: 'reader', rogue_field: 42 };
|
|
189
|
-
const result = validateApiRequest('ACEUpdatePayload', payload);
|
|
190
|
-
expect(result.valid).toBe(false);
|
|
191
|
-
expect(payload.rogue_field).toBe(42);
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it('hands back the component type on the valid branch', () => {
|
|
195
|
-
const result = validateApiResponse('AccessControlEntry', VALID_ACE);
|
|
196
|
-
expect(result.valid).toBe(true);
|
|
197
|
-
if (result.valid) {
|
|
198
|
-
assertType<Equals<typeof result.data, AccessControlEntry>>(true);
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
it('checks the role listings against their own components', () => {
|
|
203
|
-
expect(validateApiResponse('RoleDefinitionArray', [VALID_ROLE]).valid).toBe(true);
|
|
204
|
-
expect(validateApiResponse('SystemRoleDefinitionArray', [VALID_ROLE]).valid).toBe(true);
|
|
205
|
-
expect(validateApiResponse('RoleDefinitionArray', [{ ...VALID_ROLE, domain: 'system', extra: 1 }]).valid).toBe(
|
|
206
|
-
false,
|
|
207
|
-
);
|
|
208
|
-
});
|
|
209
|
-
});
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { ApiSchemaComponents } from '../api-contract/index.js';
|
|
3
|
-
import {
|
|
4
|
-
AccountApiKeySchema,
|
|
5
|
-
AccountApiKeyWithValueSchema,
|
|
6
|
-
ApiKeySchema,
|
|
7
|
-
CreateAccountApiKeyPayloadSchema,
|
|
8
|
-
UpdateAccountApiKeyPayloadSchema,
|
|
9
|
-
} from './apikey.js';
|
|
10
|
-
import { validateApiRequest } from './registry.js';
|
|
11
|
-
|
|
12
|
-
describe('separate account-key wire contract', () => {
|
|
13
|
-
const metadata = {
|
|
14
|
-
id: 'key',
|
|
15
|
-
name: 'IdP',
|
|
16
|
-
account: 'account',
|
|
17
|
-
scope: 'account',
|
|
18
|
-
profile: 'account_admin_v1',
|
|
19
|
-
enabled: true,
|
|
20
|
-
maskedValue: 'sk-…',
|
|
21
|
-
created_at: '2026-09-15T00:00:00Z',
|
|
22
|
-
updated_at: '2026-09-15T00:00:00Z',
|
|
23
|
-
created_by: 'user:admin',
|
|
24
|
-
updated_by: 'user:admin',
|
|
25
|
-
};
|
|
26
|
-
it('requires account scope/profile without weakening the project-key contract', () => {
|
|
27
|
-
expect(AccountApiKeySchema.safeParse(metadata).success).toBe(true);
|
|
28
|
-
expect(AccountApiKeySchema.safeParse({ ...metadata, profile: 'other' }).success).toBe(false);
|
|
29
|
-
expect(ApiKeySchema.safeParse(metadata).success).toBe(false);
|
|
30
|
-
expect(AccountApiKeyWithValueSchema.safeParse(metadata).success).toBe(false);
|
|
31
|
-
expect(AccountApiKeyWithValueSchema.safeParse({ ...metadata, value: 'test-secret' }).success).toBe(true);
|
|
32
|
-
});
|
|
33
|
-
it('publishes strict management payloads and metadata without a value or project property', () => {
|
|
34
|
-
const components = ApiSchemaComponents as Record<
|
|
35
|
-
string,
|
|
36
|
-
{ additionalProperties?: boolean; properties?: Record<string, unknown>; required?: string[] }
|
|
37
|
-
>;
|
|
38
|
-
for (const name of ['AccountApiKey', 'CreateAccountApiKeyPayload', 'UpdateAccountApiKeyPayload']) {
|
|
39
|
-
expect(components[name].additionalProperties).toBe(false);
|
|
40
|
-
expect(components[name].properties).not.toHaveProperty('value');
|
|
41
|
-
expect(components[name].properties).not.toHaveProperty('project');
|
|
42
|
-
}
|
|
43
|
-
expect(components.ApiKey.required).toContain('project');
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// AJV enforces emitted JSON Schema; Zod trimming alone cannot reject whitespace at the API boundary.
|
|
48
|
-
describe.each([
|
|
49
|
-
['CreateAccountApiKeyPayload', CreateAccountApiKeyPayloadSchema],
|
|
50
|
-
['UpdateAccountApiKeyPayload', UpdateAccountApiKeyPayloadSchema],
|
|
51
|
-
] as const)('%s name validation', (component, schema) => {
|
|
52
|
-
it.each(['', ' ', '\t\n ', '\u00a0'])('rejects blank name %j in Zod and AJV', (name) => {
|
|
53
|
-
expect(schema.safeParse({ name }).success).toBe(false);
|
|
54
|
-
expect(validateApiRequest(component, { name }).valid).toBe(false);
|
|
55
|
-
});
|
|
56
|
-
it.each(['IdP provisioning', ' IdP provisioning '])('accepts nonblank name %j in both validators', (name) => {
|
|
57
|
-
expect(schema.safeParse({ name }).success).toBe(true);
|
|
58
|
-
expect(validateApiRequest(component, { name }).valid).toBe(true);
|
|
59
|
-
});
|
|
60
|
-
});
|