@superatomai/sdk-node 0.0.88-dsp → 0.0.90-dsp
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/index.d.mts +95 -14
- package/dist/index.d.ts +95 -14
- package/dist/index.js +216 -45
- package/dist/index.mjs +213 -45
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -5160,6 +5160,56 @@ interface SourcePolicy {
|
|
|
5160
5160
|
/** Grants outside the scope above. Empty or absent means none. */
|
|
5161
5161
|
exceptions?: PolicyException[];
|
|
5162
5162
|
}
|
|
5163
|
+
/**
|
|
5164
|
+
* Operators the constraint engine builds predicates from. A superset of
|
|
5165
|
+
* {@link RowFilter.op}, which the original rewriter is limited to.
|
|
5166
|
+
*/
|
|
5167
|
+
type ConstraintOp = 'in' | 'not_in' | 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'not_like' | 'is_null' | 'is_not_null';
|
|
5168
|
+
/**
|
|
5169
|
+
* One filter in a {@link ConstraintPolicy}.
|
|
5170
|
+
*
|
|
5171
|
+
* No `table`, unlike {@link RowFilter}: these are keyed by table, so a filter
|
|
5172
|
+
* cannot fail to match the table it was written for and leave it unfiltered.
|
|
5173
|
+
*/
|
|
5174
|
+
interface ConstraintFilter {
|
|
5175
|
+
column: string;
|
|
5176
|
+
op?: ConstraintOp;
|
|
5177
|
+
/** Omitted only for `is_null` / `is_not_null`. */
|
|
5178
|
+
values?: unknown[];
|
|
5179
|
+
label?: string;
|
|
5180
|
+
}
|
|
5181
|
+
/**
|
|
5182
|
+
* What one user may see in one source, in the shape the constraint engine reads
|
|
5183
|
+
* (`sqlrewrite/v2/engine.py`).
|
|
5184
|
+
*
|
|
5185
|
+
* Not a superset of {@link SourcePolicy} but a different shape: it adds
|
|
5186
|
+
* schemas, columns and limits. A claim carries one shape or the other, never
|
|
5187
|
+
* both.
|
|
5188
|
+
*/
|
|
5189
|
+
interface ConstraintPolicy {
|
|
5190
|
+
sourceId?: string | null;
|
|
5191
|
+
label?: string;
|
|
5192
|
+
/**
|
|
5193
|
+
* Every table is read from this schema, whatever schema the query wrote —
|
|
5194
|
+
* which is what makes it a restriction: there is no other schema to reach.
|
|
5195
|
+
* Absent means schemas are left exactly as written.
|
|
5196
|
+
*/
|
|
5197
|
+
schema?: string;
|
|
5198
|
+
/** table → readable columns, or `null` for every column. Absent: every table. */
|
|
5199
|
+
readableTables?: Record<string, string[] | null>;
|
|
5200
|
+
/** table → filters, ANDed together. */
|
|
5201
|
+
rowFilters?: Record<string, ConstraintFilter[]>;
|
|
5202
|
+
limits?: {
|
|
5203
|
+
maxRows?: number;
|
|
5204
|
+
maxExecutionSeconds?: number;
|
|
5205
|
+
};
|
|
5206
|
+
/**
|
|
5207
|
+
* Why this policy could not be read. Set rather than dropping the policy:
|
|
5208
|
+
* a dropped policy leaves its source UNRESTRICTED, which is the opposite of
|
|
5209
|
+
* what a malformed restriction should mean. The gate refuses the source.
|
|
5210
|
+
*/
|
|
5211
|
+
invalid?: string;
|
|
5212
|
+
}
|
|
5163
5213
|
interface RequestContext {
|
|
5164
5214
|
principal: Principal;
|
|
5165
5215
|
projectId?: string;
|
|
@@ -5169,6 +5219,11 @@ interface RequestContext {
|
|
|
5169
5219
|
* — see the backend's policy-gate.
|
|
5170
5220
|
*/
|
|
5171
5221
|
policies?: SourcePolicy[];
|
|
5222
|
+
/**
|
|
5223
|
+
* The same restrictions in the constraint shape. Present only when the claim
|
|
5224
|
+
* said `version: 2`, and then `policies` is empty: one claim, one engine.
|
|
5225
|
+
*/
|
|
5226
|
+
constraintPolicies?: ConstraintPolicy[];
|
|
5172
5227
|
/**
|
|
5173
5228
|
* The data sources this user may reach AT ALL, by source id.
|
|
5174
5229
|
*
|
|
@@ -5221,6 +5276,7 @@ declare function runAsUser<T>(user: {
|
|
|
5221
5276
|
projectId?: string;
|
|
5222
5277
|
requestId?: string;
|
|
5223
5278
|
policies?: SourcePolicy[];
|
|
5279
|
+
constraintPolicies?: ConstraintPolicy[];
|
|
5224
5280
|
allowedSources?: string[] | null;
|
|
5225
5281
|
graphVersion?: GraphVersion;
|
|
5226
5282
|
}, fn: () => T): T;
|
|
@@ -5269,6 +5325,35 @@ declare function describeContext(ctx?: RequestContext | undefined): string;
|
|
|
5269
5325
|
/** True when the context represents a signed-in user rather than a trusted job. */
|
|
5270
5326
|
declare function isUserContext(ctx?: RequestContext | undefined): boolean;
|
|
5271
5327
|
|
|
5328
|
+
/**
|
|
5329
|
+
* The constraint policy shape (`version: 2`), read onto the request context.
|
|
5330
|
+
*
|
|
5331
|
+
* Strict, and failing CLOSED, which is the opposite of the legacy parser beside
|
|
5332
|
+
* it. There, dropping something malformed grants LESS. Here it grants MORE: a
|
|
5333
|
+
* dropped policy leaves its source with no restriction at all. So a policy that
|
|
5334
|
+
* cannot be read is kept, marked `invalid`, and the gate refuses the source.
|
|
5335
|
+
*/
|
|
5336
|
+
|
|
5337
|
+
declare function constraintPoliciesFromConfig(raw: unknown): ConstraintPolicy[];
|
|
5338
|
+
|
|
5339
|
+
/**
|
|
5340
|
+
* The original policy shape, read out of the admin-authored per-user config.
|
|
5341
|
+
*
|
|
5342
|
+
* Every step here is defensive and DROPS what it cannot read, because the
|
|
5343
|
+
* config is free-form JSON typed by a human into an admin field. That is a
|
|
5344
|
+
* deliberate trade with a sharp edge — a typo'd policy silently becomes no
|
|
5345
|
+
* policy, i.e. unrestricted. The constraint shape next door takes the opposite
|
|
5346
|
+
* approach for exactly that reason.
|
|
5347
|
+
*/
|
|
5348
|
+
|
|
5349
|
+
/**
|
|
5350
|
+
* Read access policies out of the admin-authored per-user config.
|
|
5351
|
+
*
|
|
5352
|
+
* Accepts either a single object or an array, so one user can be scoped across
|
|
5353
|
+
* several sources — and the object form, whose policies sit under `policies`.
|
|
5354
|
+
*/
|
|
5355
|
+
declare function policiesFromConfig(config: unknown): SourcePolicy[];
|
|
5356
|
+
|
|
5272
5357
|
/**
|
|
5273
5358
|
* Deriving "who is asking" from an incoming WebSocket message.
|
|
5274
5359
|
*
|
|
@@ -5283,6 +5368,8 @@ declare function isUserContext(ctx?: RequestContext | undefined): boolean;
|
|
|
5283
5368
|
/** Everything one request's config says about what the caller may see. */
|
|
5284
5369
|
interface ResolvedAccess {
|
|
5285
5370
|
policies: SourcePolicy[];
|
|
5371
|
+
/** Set instead of `policies` when the claim said `version: 2`. */
|
|
5372
|
+
constraintPolicies: ConstraintPolicy[];
|
|
5286
5373
|
/** `null` means every source; `[]` means none — see `RequestContext.allowedSources`. */
|
|
5287
5374
|
allowedSources: string[] | null;
|
|
5288
5375
|
}
|
|
@@ -5296,19 +5383,6 @@ interface ResolvedAccess {
|
|
|
5296
5383
|
* drop EVERY row filter the customer wrote.
|
|
5297
5384
|
*/
|
|
5298
5385
|
declare function accessFromConfig(config: unknown): ResolvedAccess;
|
|
5299
|
-
/**
|
|
5300
|
-
* Read access policies out of the admin-authored per-user config.
|
|
5301
|
-
*
|
|
5302
|
-
* The config is free-form JSON typed by a human into an admin field, so every
|
|
5303
|
-
* step here is defensive: a malformed entry is DROPPED, never guessed at. That
|
|
5304
|
-
* is a deliberate trade-off with a sharp edge — a typo'd policy silently
|
|
5305
|
-
* becomes no policy, i.e. unrestricted. Validating shapes against the source
|
|
5306
|
-
* schema (and refusing, rather than dropping) is the fix, and is not built yet.
|
|
5307
|
-
*
|
|
5308
|
-
* Accepts either a single object or an array, so one user can be scoped across
|
|
5309
|
-
* several sources — and the object form, whose policies sit under `policies`.
|
|
5310
|
-
*/
|
|
5311
|
-
declare function policiesFromConfig(config: unknown): SourcePolicy[];
|
|
5312
5386
|
/**
|
|
5313
5387
|
* Run `fn` with the caller's identity established.
|
|
5314
5388
|
*
|
|
@@ -5655,6 +5729,13 @@ interface CodexSessionOptions extends CodingAgentSessionOptions {
|
|
|
5655
5729
|
extraConfig?: Record<string, unknown>;
|
|
5656
5730
|
approvalPolicy?: 'never' | 'on-request' | 'on-failure' | 'untrusted';
|
|
5657
5731
|
}
|
|
5732
|
+
/**
|
|
5733
|
+
* codex reads only the first `project_doc_max_bytes` of the instructions file (default 32 KiB) and
|
|
5734
|
+
* drops the rest without a word; composed instructions run past that, losing their closing rules.
|
|
5735
|
+
*/
|
|
5736
|
+
declare const CODEX_DOC_MAX_BYTES: number;
|
|
5737
|
+
/** The `--config` overrides for one run: per run, so no host's config.toml decides them. */
|
|
5738
|
+
declare function codexRunConfig(opts: Pick<CodexSessionOptions, 'mcpServers' | 'instructionsFile' | 'extraConfig'>): Record<string, unknown>;
|
|
5658
5739
|
declare function createCodexSession(opts: CodexSessionOptions): CodingAgentSession;
|
|
5659
5740
|
|
|
5660
5741
|
/**
|
|
@@ -6759,4 +6840,4 @@ declare class SuperatomSDK {
|
|
|
6759
6840
|
getConversationSimilarityThreshold(): number;
|
|
6760
6841
|
}
|
|
6761
6842
|
|
|
6762
|
-
export { ALL_COLUMN_KEYS, ANSWER_COMPONENT_NAMES, type AgentConfig, type AgentEvent, type AgentResponse, type AgentRunContext, type AgentRunHandlers, type AgentRunRecord, type AgentRunResult, type AgentTrigger, type AgentUsage, type AnalyticsEventType, type AnalyticsStatus, type AnswerProvider, type AnswerProviderContext, type ApplySummary, BM25L, type BM25LOptions, type BaseLLMConfig, type BuildTriggerInput, CATEGORY_KEYS, CONTEXT_CONFIG, type CapturedLog, CleanupService, type CodexSessionOptions, type CodingAgentCollectionConfig, type CodingAgentDefinition, type CodingAgentSession, type CodingAgentSessionOptions, type CodingAgentsConfig, type ColInfo, type ColType, type CollectionHandler, type CollectionOperation, type Component, type DBUIBlock, DEFAULT_AGENT_CONFIG, DEFAULT_FMT_CONFIG, type DashboardAgentCollectionConfig, type DatabaseType, type FindingCode, type Fmt, type FmtConfig, type GeneratedFile, type GraphVersion, type Harness, type HybridSearchOptions, INSTRUCTIONS_FILE, type IncomingMessage, type KbNodesQueryFilters, type KbNodesRequestPayload, LLM, type LLMUsageEntry, type LogLevel, MainAgent, type McpServerSpec, type Message, MissingRequestContextError, type ModelStrategy, NUMERIC_KEYS, type NarrationUpdate, type OutputContract, type OutputField, type OutputValidator, type PiSessionListener, type PiSessionState, type PiTranscriptEntry, type PolicyException, type PolicyExceptionTable, type Principal, type PromptAttachment, type PromptContext, type RequestContext, type RerankedResult, type ResolvedAccess, type RowFilter, type RunAgentOptions, STORAGE_CONFIG, type ScriptComponentSpec, ScriptMatcher, type ScriptParameter, type ScriptRecipe, type ScriptRecipeMetaRow, type ScriptRecipeStore, type ScriptResult, ScriptStore, type ScriptStoreOptions, type SelectedWorkflow, type ShimDef, type ShimSummary, type ShimTarget, type SourcePolicy, type SpecToValidate, SuperatomSDK, type SuperatomSDKConfig, type T_RESPONSE, type TaskType, Thread, ThreadManager, type Tool$1 as Tool, type ToolOutputSchema, type TriggerEvent, type TriggerFireInfo, UIBlock, UILogCollector, type User, UserManager, type UsersData, type ValidationContext, type ValidationFinding, type WorkflowDescriptor, type Workspace, accessFromConfig, analyticsClient, answerCatalogForBinding, answerComponents, anthropicLLM, assertReadOnlySql, bindContext, bridgePreamble, captureContext, clearContextTokens, contextTokenCount, createCodexSession, createCodingAgentSession, dashboardConversationHistory, dataFingerprint, describeContext, describeTriggers, emitAgentEvent, extractNamedExport, formatFindingsForAgent, geminiLLM, getCodingAgent, getCodingAgentsConfig, getPiSessionState, getRequestContext, groqLLM, hybridRerank, inferColumns, isUserContext, listCodingAgents, llmUsageLogger, logger, makeFmt, mintContextToken, normalizeScriptBody, onAgentRun, onPiSessionUpdate, openaiLLM, policiesFromConfig, projectForDatasetBinding, promptLoader, queryCache, registerCodingAgentCollection, registerCodingAgents, registerDashboardAgentCollection, requireRequestContext, rerankChromaResults, rerankConversationResults, resolveContextToken, resolveScriptRecipeStore, revokeContextToken, runAsSystem, runAsUser, runCodingAgent, runScript, runWithContext, runWithMessageIdentity, startAgentTriggers, stopAgentTriggers, userPromptErrorLogger, validateComponentSpec, withCapturedContext, writeBridgeShims, writeShims };
|
|
6843
|
+
export { ALL_COLUMN_KEYS, ANSWER_COMPONENT_NAMES, type AgentConfig, type AgentEvent, type AgentResponse, type AgentRunContext, type AgentRunHandlers, type AgentRunRecord, type AgentRunResult, type AgentTrigger, type AgentUsage, type AnalyticsEventType, type AnalyticsStatus, type AnswerProvider, type AnswerProviderContext, type ApplySummary, BM25L, type BM25LOptions, type BaseLLMConfig, type BuildTriggerInput, CATEGORY_KEYS, CODEX_DOC_MAX_BYTES, CONTEXT_CONFIG, type CapturedLog, CleanupService, type CodexSessionOptions, type CodingAgentCollectionConfig, type CodingAgentDefinition, type CodingAgentSession, type CodingAgentSessionOptions, type CodingAgentsConfig, type ColInfo, type ColType, type CollectionHandler, type CollectionOperation, type Component, type ConstraintFilter, type ConstraintOp, type ConstraintPolicy, type DBUIBlock, DEFAULT_AGENT_CONFIG, DEFAULT_FMT_CONFIG, type DashboardAgentCollectionConfig, type DatabaseType, type FindingCode, type Fmt, type FmtConfig, type GeneratedFile, type GraphVersion, type Harness, type HybridSearchOptions, INSTRUCTIONS_FILE, type IncomingMessage, type KbNodesQueryFilters, type KbNodesRequestPayload, LLM, type LLMUsageEntry, type LogLevel, MainAgent, type McpServerSpec, type Message, MissingRequestContextError, type ModelStrategy, NUMERIC_KEYS, type NarrationUpdate, type OutputContract, type OutputField, type OutputValidator, type PiSessionListener, type PiSessionState, type PiTranscriptEntry, type PolicyException, type PolicyExceptionTable, type Principal, type PromptAttachment, type PromptContext, type RequestContext, type RerankedResult, type ResolvedAccess, type RowFilter, type RunAgentOptions, STORAGE_CONFIG, type ScriptComponentSpec, ScriptMatcher, type ScriptParameter, type ScriptRecipe, type ScriptRecipeMetaRow, type ScriptRecipeStore, type ScriptResult, ScriptStore, type ScriptStoreOptions, type SelectedWorkflow, type ShimDef, type ShimSummary, type ShimTarget, type SourcePolicy, type SpecToValidate, SuperatomSDK, type SuperatomSDKConfig, type T_RESPONSE, type TaskType, Thread, ThreadManager, type Tool$1 as Tool, type ToolOutputSchema, type TriggerEvent, type TriggerFireInfo, UIBlock, UILogCollector, type User, UserManager, type UsersData, type ValidationContext, type ValidationFinding, type WorkflowDescriptor, type Workspace, accessFromConfig, analyticsClient, answerCatalogForBinding, answerComponents, anthropicLLM, assertReadOnlySql, bindContext, bridgePreamble, captureContext, clearContextTokens, codexRunConfig, constraintPoliciesFromConfig, contextTokenCount, createCodexSession, createCodingAgentSession, dashboardConversationHistory, dataFingerprint, describeContext, describeTriggers, emitAgentEvent, extractNamedExport, formatFindingsForAgent, geminiLLM, getCodingAgent, getCodingAgentsConfig, getPiSessionState, getRequestContext, groqLLM, hybridRerank, inferColumns, isUserContext, listCodingAgents, llmUsageLogger, logger, makeFmt, mintContextToken, normalizeScriptBody, onAgentRun, onPiSessionUpdate, openaiLLM, policiesFromConfig, projectForDatasetBinding, promptLoader, queryCache, registerCodingAgentCollection, registerCodingAgents, registerDashboardAgentCollection, requireRequestContext, rerankChromaResults, rerankConversationResults, resolveContextToken, resolveScriptRecipeStore, revokeContextToken, runAsSystem, runAsUser, runCodingAgent, runScript, runWithContext, runWithMessageIdentity, startAgentTriggers, stopAgentTriggers, userPromptErrorLogger, validateComponentSpec, withCapturedContext, writeBridgeShims, writeShims };
|
package/dist/index.d.ts
CHANGED
|
@@ -5160,6 +5160,56 @@ interface SourcePolicy {
|
|
|
5160
5160
|
/** Grants outside the scope above. Empty or absent means none. */
|
|
5161
5161
|
exceptions?: PolicyException[];
|
|
5162
5162
|
}
|
|
5163
|
+
/**
|
|
5164
|
+
* Operators the constraint engine builds predicates from. A superset of
|
|
5165
|
+
* {@link RowFilter.op}, which the original rewriter is limited to.
|
|
5166
|
+
*/
|
|
5167
|
+
type ConstraintOp = 'in' | 'not_in' | 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'not_like' | 'is_null' | 'is_not_null';
|
|
5168
|
+
/**
|
|
5169
|
+
* One filter in a {@link ConstraintPolicy}.
|
|
5170
|
+
*
|
|
5171
|
+
* No `table`, unlike {@link RowFilter}: these are keyed by table, so a filter
|
|
5172
|
+
* cannot fail to match the table it was written for and leave it unfiltered.
|
|
5173
|
+
*/
|
|
5174
|
+
interface ConstraintFilter {
|
|
5175
|
+
column: string;
|
|
5176
|
+
op?: ConstraintOp;
|
|
5177
|
+
/** Omitted only for `is_null` / `is_not_null`. */
|
|
5178
|
+
values?: unknown[];
|
|
5179
|
+
label?: string;
|
|
5180
|
+
}
|
|
5181
|
+
/**
|
|
5182
|
+
* What one user may see in one source, in the shape the constraint engine reads
|
|
5183
|
+
* (`sqlrewrite/v2/engine.py`).
|
|
5184
|
+
*
|
|
5185
|
+
* Not a superset of {@link SourcePolicy} but a different shape: it adds
|
|
5186
|
+
* schemas, columns and limits. A claim carries one shape or the other, never
|
|
5187
|
+
* both.
|
|
5188
|
+
*/
|
|
5189
|
+
interface ConstraintPolicy {
|
|
5190
|
+
sourceId?: string | null;
|
|
5191
|
+
label?: string;
|
|
5192
|
+
/**
|
|
5193
|
+
* Every table is read from this schema, whatever schema the query wrote —
|
|
5194
|
+
* which is what makes it a restriction: there is no other schema to reach.
|
|
5195
|
+
* Absent means schemas are left exactly as written.
|
|
5196
|
+
*/
|
|
5197
|
+
schema?: string;
|
|
5198
|
+
/** table → readable columns, or `null` for every column. Absent: every table. */
|
|
5199
|
+
readableTables?: Record<string, string[] | null>;
|
|
5200
|
+
/** table → filters, ANDed together. */
|
|
5201
|
+
rowFilters?: Record<string, ConstraintFilter[]>;
|
|
5202
|
+
limits?: {
|
|
5203
|
+
maxRows?: number;
|
|
5204
|
+
maxExecutionSeconds?: number;
|
|
5205
|
+
};
|
|
5206
|
+
/**
|
|
5207
|
+
* Why this policy could not be read. Set rather than dropping the policy:
|
|
5208
|
+
* a dropped policy leaves its source UNRESTRICTED, which is the opposite of
|
|
5209
|
+
* what a malformed restriction should mean. The gate refuses the source.
|
|
5210
|
+
*/
|
|
5211
|
+
invalid?: string;
|
|
5212
|
+
}
|
|
5163
5213
|
interface RequestContext {
|
|
5164
5214
|
principal: Principal;
|
|
5165
5215
|
projectId?: string;
|
|
@@ -5169,6 +5219,11 @@ interface RequestContext {
|
|
|
5169
5219
|
* — see the backend's policy-gate.
|
|
5170
5220
|
*/
|
|
5171
5221
|
policies?: SourcePolicy[];
|
|
5222
|
+
/**
|
|
5223
|
+
* The same restrictions in the constraint shape. Present only when the claim
|
|
5224
|
+
* said `version: 2`, and then `policies` is empty: one claim, one engine.
|
|
5225
|
+
*/
|
|
5226
|
+
constraintPolicies?: ConstraintPolicy[];
|
|
5172
5227
|
/**
|
|
5173
5228
|
* The data sources this user may reach AT ALL, by source id.
|
|
5174
5229
|
*
|
|
@@ -5221,6 +5276,7 @@ declare function runAsUser<T>(user: {
|
|
|
5221
5276
|
projectId?: string;
|
|
5222
5277
|
requestId?: string;
|
|
5223
5278
|
policies?: SourcePolicy[];
|
|
5279
|
+
constraintPolicies?: ConstraintPolicy[];
|
|
5224
5280
|
allowedSources?: string[] | null;
|
|
5225
5281
|
graphVersion?: GraphVersion;
|
|
5226
5282
|
}, fn: () => T): T;
|
|
@@ -5269,6 +5325,35 @@ declare function describeContext(ctx?: RequestContext | undefined): string;
|
|
|
5269
5325
|
/** True when the context represents a signed-in user rather than a trusted job. */
|
|
5270
5326
|
declare function isUserContext(ctx?: RequestContext | undefined): boolean;
|
|
5271
5327
|
|
|
5328
|
+
/**
|
|
5329
|
+
* The constraint policy shape (`version: 2`), read onto the request context.
|
|
5330
|
+
*
|
|
5331
|
+
* Strict, and failing CLOSED, which is the opposite of the legacy parser beside
|
|
5332
|
+
* it. There, dropping something malformed grants LESS. Here it grants MORE: a
|
|
5333
|
+
* dropped policy leaves its source with no restriction at all. So a policy that
|
|
5334
|
+
* cannot be read is kept, marked `invalid`, and the gate refuses the source.
|
|
5335
|
+
*/
|
|
5336
|
+
|
|
5337
|
+
declare function constraintPoliciesFromConfig(raw: unknown): ConstraintPolicy[];
|
|
5338
|
+
|
|
5339
|
+
/**
|
|
5340
|
+
* The original policy shape, read out of the admin-authored per-user config.
|
|
5341
|
+
*
|
|
5342
|
+
* Every step here is defensive and DROPS what it cannot read, because the
|
|
5343
|
+
* config is free-form JSON typed by a human into an admin field. That is a
|
|
5344
|
+
* deliberate trade with a sharp edge — a typo'd policy silently becomes no
|
|
5345
|
+
* policy, i.e. unrestricted. The constraint shape next door takes the opposite
|
|
5346
|
+
* approach for exactly that reason.
|
|
5347
|
+
*/
|
|
5348
|
+
|
|
5349
|
+
/**
|
|
5350
|
+
* Read access policies out of the admin-authored per-user config.
|
|
5351
|
+
*
|
|
5352
|
+
* Accepts either a single object or an array, so one user can be scoped across
|
|
5353
|
+
* several sources — and the object form, whose policies sit under `policies`.
|
|
5354
|
+
*/
|
|
5355
|
+
declare function policiesFromConfig(config: unknown): SourcePolicy[];
|
|
5356
|
+
|
|
5272
5357
|
/**
|
|
5273
5358
|
* Deriving "who is asking" from an incoming WebSocket message.
|
|
5274
5359
|
*
|
|
@@ -5283,6 +5368,8 @@ declare function isUserContext(ctx?: RequestContext | undefined): boolean;
|
|
|
5283
5368
|
/** Everything one request's config says about what the caller may see. */
|
|
5284
5369
|
interface ResolvedAccess {
|
|
5285
5370
|
policies: SourcePolicy[];
|
|
5371
|
+
/** Set instead of `policies` when the claim said `version: 2`. */
|
|
5372
|
+
constraintPolicies: ConstraintPolicy[];
|
|
5286
5373
|
/** `null` means every source; `[]` means none — see `RequestContext.allowedSources`. */
|
|
5287
5374
|
allowedSources: string[] | null;
|
|
5288
5375
|
}
|
|
@@ -5296,19 +5383,6 @@ interface ResolvedAccess {
|
|
|
5296
5383
|
* drop EVERY row filter the customer wrote.
|
|
5297
5384
|
*/
|
|
5298
5385
|
declare function accessFromConfig(config: unknown): ResolvedAccess;
|
|
5299
|
-
/**
|
|
5300
|
-
* Read access policies out of the admin-authored per-user config.
|
|
5301
|
-
*
|
|
5302
|
-
* The config is free-form JSON typed by a human into an admin field, so every
|
|
5303
|
-
* step here is defensive: a malformed entry is DROPPED, never guessed at. That
|
|
5304
|
-
* is a deliberate trade-off with a sharp edge — a typo'd policy silently
|
|
5305
|
-
* becomes no policy, i.e. unrestricted. Validating shapes against the source
|
|
5306
|
-
* schema (and refusing, rather than dropping) is the fix, and is not built yet.
|
|
5307
|
-
*
|
|
5308
|
-
* Accepts either a single object or an array, so one user can be scoped across
|
|
5309
|
-
* several sources — and the object form, whose policies sit under `policies`.
|
|
5310
|
-
*/
|
|
5311
|
-
declare function policiesFromConfig(config: unknown): SourcePolicy[];
|
|
5312
5386
|
/**
|
|
5313
5387
|
* Run `fn` with the caller's identity established.
|
|
5314
5388
|
*
|
|
@@ -5655,6 +5729,13 @@ interface CodexSessionOptions extends CodingAgentSessionOptions {
|
|
|
5655
5729
|
extraConfig?: Record<string, unknown>;
|
|
5656
5730
|
approvalPolicy?: 'never' | 'on-request' | 'on-failure' | 'untrusted';
|
|
5657
5731
|
}
|
|
5732
|
+
/**
|
|
5733
|
+
* codex reads only the first `project_doc_max_bytes` of the instructions file (default 32 KiB) and
|
|
5734
|
+
* drops the rest without a word; composed instructions run past that, losing their closing rules.
|
|
5735
|
+
*/
|
|
5736
|
+
declare const CODEX_DOC_MAX_BYTES: number;
|
|
5737
|
+
/** The `--config` overrides for one run: per run, so no host's config.toml decides them. */
|
|
5738
|
+
declare function codexRunConfig(opts: Pick<CodexSessionOptions, 'mcpServers' | 'instructionsFile' | 'extraConfig'>): Record<string, unknown>;
|
|
5658
5739
|
declare function createCodexSession(opts: CodexSessionOptions): CodingAgentSession;
|
|
5659
5740
|
|
|
5660
5741
|
/**
|
|
@@ -6759,4 +6840,4 @@ declare class SuperatomSDK {
|
|
|
6759
6840
|
getConversationSimilarityThreshold(): number;
|
|
6760
6841
|
}
|
|
6761
6842
|
|
|
6762
|
-
export { ALL_COLUMN_KEYS, ANSWER_COMPONENT_NAMES, type AgentConfig, type AgentEvent, type AgentResponse, type AgentRunContext, type AgentRunHandlers, type AgentRunRecord, type AgentRunResult, type AgentTrigger, type AgentUsage, type AnalyticsEventType, type AnalyticsStatus, type AnswerProvider, type AnswerProviderContext, type ApplySummary, BM25L, type BM25LOptions, type BaseLLMConfig, type BuildTriggerInput, CATEGORY_KEYS, CONTEXT_CONFIG, type CapturedLog, CleanupService, type CodexSessionOptions, type CodingAgentCollectionConfig, type CodingAgentDefinition, type CodingAgentSession, type CodingAgentSessionOptions, type CodingAgentsConfig, type ColInfo, type ColType, type CollectionHandler, type CollectionOperation, type Component, type DBUIBlock, DEFAULT_AGENT_CONFIG, DEFAULT_FMT_CONFIG, type DashboardAgentCollectionConfig, type DatabaseType, type FindingCode, type Fmt, type FmtConfig, type GeneratedFile, type GraphVersion, type Harness, type HybridSearchOptions, INSTRUCTIONS_FILE, type IncomingMessage, type KbNodesQueryFilters, type KbNodesRequestPayload, LLM, type LLMUsageEntry, type LogLevel, MainAgent, type McpServerSpec, type Message, MissingRequestContextError, type ModelStrategy, NUMERIC_KEYS, type NarrationUpdate, type OutputContract, type OutputField, type OutputValidator, type PiSessionListener, type PiSessionState, type PiTranscriptEntry, type PolicyException, type PolicyExceptionTable, type Principal, type PromptAttachment, type PromptContext, type RequestContext, type RerankedResult, type ResolvedAccess, type RowFilter, type RunAgentOptions, STORAGE_CONFIG, type ScriptComponentSpec, ScriptMatcher, type ScriptParameter, type ScriptRecipe, type ScriptRecipeMetaRow, type ScriptRecipeStore, type ScriptResult, ScriptStore, type ScriptStoreOptions, type SelectedWorkflow, type ShimDef, type ShimSummary, type ShimTarget, type SourcePolicy, type SpecToValidate, SuperatomSDK, type SuperatomSDKConfig, type T_RESPONSE, type TaskType, Thread, ThreadManager, type Tool$1 as Tool, type ToolOutputSchema, type TriggerEvent, type TriggerFireInfo, UIBlock, UILogCollector, type User, UserManager, type UsersData, type ValidationContext, type ValidationFinding, type WorkflowDescriptor, type Workspace, accessFromConfig, analyticsClient, answerCatalogForBinding, answerComponents, anthropicLLM, assertReadOnlySql, bindContext, bridgePreamble, captureContext, clearContextTokens, contextTokenCount, createCodexSession, createCodingAgentSession, dashboardConversationHistory, dataFingerprint, describeContext, describeTriggers, emitAgentEvent, extractNamedExport, formatFindingsForAgent, geminiLLM, getCodingAgent, getCodingAgentsConfig, getPiSessionState, getRequestContext, groqLLM, hybridRerank, inferColumns, isUserContext, listCodingAgents, llmUsageLogger, logger, makeFmt, mintContextToken, normalizeScriptBody, onAgentRun, onPiSessionUpdate, openaiLLM, policiesFromConfig, projectForDatasetBinding, promptLoader, queryCache, registerCodingAgentCollection, registerCodingAgents, registerDashboardAgentCollection, requireRequestContext, rerankChromaResults, rerankConversationResults, resolveContextToken, resolveScriptRecipeStore, revokeContextToken, runAsSystem, runAsUser, runCodingAgent, runScript, runWithContext, runWithMessageIdentity, startAgentTriggers, stopAgentTriggers, userPromptErrorLogger, validateComponentSpec, withCapturedContext, writeBridgeShims, writeShims };
|
|
6843
|
+
export { ALL_COLUMN_KEYS, ANSWER_COMPONENT_NAMES, type AgentConfig, type AgentEvent, type AgentResponse, type AgentRunContext, type AgentRunHandlers, type AgentRunRecord, type AgentRunResult, type AgentTrigger, type AgentUsage, type AnalyticsEventType, type AnalyticsStatus, type AnswerProvider, type AnswerProviderContext, type ApplySummary, BM25L, type BM25LOptions, type BaseLLMConfig, type BuildTriggerInput, CATEGORY_KEYS, CODEX_DOC_MAX_BYTES, CONTEXT_CONFIG, type CapturedLog, CleanupService, type CodexSessionOptions, type CodingAgentCollectionConfig, type CodingAgentDefinition, type CodingAgentSession, type CodingAgentSessionOptions, type CodingAgentsConfig, type ColInfo, type ColType, type CollectionHandler, type CollectionOperation, type Component, type ConstraintFilter, type ConstraintOp, type ConstraintPolicy, type DBUIBlock, DEFAULT_AGENT_CONFIG, DEFAULT_FMT_CONFIG, type DashboardAgentCollectionConfig, type DatabaseType, type FindingCode, type Fmt, type FmtConfig, type GeneratedFile, type GraphVersion, type Harness, type HybridSearchOptions, INSTRUCTIONS_FILE, type IncomingMessage, type KbNodesQueryFilters, type KbNodesRequestPayload, LLM, type LLMUsageEntry, type LogLevel, MainAgent, type McpServerSpec, type Message, MissingRequestContextError, type ModelStrategy, NUMERIC_KEYS, type NarrationUpdate, type OutputContract, type OutputField, type OutputValidator, type PiSessionListener, type PiSessionState, type PiTranscriptEntry, type PolicyException, type PolicyExceptionTable, type Principal, type PromptAttachment, type PromptContext, type RequestContext, type RerankedResult, type ResolvedAccess, type RowFilter, type RunAgentOptions, STORAGE_CONFIG, type ScriptComponentSpec, ScriptMatcher, type ScriptParameter, type ScriptRecipe, type ScriptRecipeMetaRow, type ScriptRecipeStore, type ScriptResult, ScriptStore, type ScriptStoreOptions, type SelectedWorkflow, type ShimDef, type ShimSummary, type ShimTarget, type SourcePolicy, type SpecToValidate, SuperatomSDK, type SuperatomSDKConfig, type T_RESPONSE, type TaskType, Thread, ThreadManager, type Tool$1 as Tool, type ToolOutputSchema, type TriggerEvent, type TriggerFireInfo, UIBlock, UILogCollector, type User, UserManager, type UsersData, type ValidationContext, type ValidationFinding, type WorkflowDescriptor, type Workspace, accessFromConfig, analyticsClient, answerCatalogForBinding, answerComponents, anthropicLLM, assertReadOnlySql, bindContext, bridgePreamble, captureContext, clearContextTokens, codexRunConfig, constraintPoliciesFromConfig, contextTokenCount, createCodexSession, createCodingAgentSession, dashboardConversationHistory, dataFingerprint, describeContext, describeTriggers, emitAgentEvent, extractNamedExport, formatFindingsForAgent, geminiLLM, getCodingAgent, getCodingAgentsConfig, getPiSessionState, getRequestContext, groqLLM, hybridRerank, inferColumns, isUserContext, listCodingAgents, llmUsageLogger, logger, makeFmt, mintContextToken, normalizeScriptBody, onAgentRun, onPiSessionUpdate, openaiLLM, policiesFromConfig, projectForDatasetBinding, promptLoader, queryCache, registerCodingAgentCollection, registerCodingAgents, registerDashboardAgentCollection, requireRequestContext, rerankChromaResults, rerankConversationResults, resolveContextToken, resolveScriptRecipeStore, revokeContextToken, runAsSystem, runAsUser, runCodingAgent, runScript, runWithContext, runWithMessageIdentity, startAgentTriggers, stopAgentTriggers, userPromptErrorLogger, validateComponentSpec, withCapturedContext, writeBridgeShims, writeShims };
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,7 @@ __export(index_exports, {
|
|
|
34
34
|
ANSWER_COMPONENT_NAMES: () => ANSWER_COMPONENT_NAMES,
|
|
35
35
|
BM25L: () => BM25L,
|
|
36
36
|
CATEGORY_KEYS: () => CATEGORY_KEYS,
|
|
37
|
+
CODEX_DOC_MAX_BYTES: () => CODEX_DOC_MAX_BYTES,
|
|
37
38
|
CONTEXT_CONFIG: () => CONTEXT_CONFIG,
|
|
38
39
|
CleanupService: () => CleanupService,
|
|
39
40
|
DEFAULT_AGENT_CONFIG: () => DEFAULT_AGENT_CONFIG,
|
|
@@ -62,6 +63,8 @@ __export(index_exports, {
|
|
|
62
63
|
bridgePreamble: () => bridgePreamble,
|
|
63
64
|
captureContext: () => captureContext,
|
|
64
65
|
clearContextTokens: () => clearContextTokens,
|
|
66
|
+
codexRunConfig: () => codexRunConfig,
|
|
67
|
+
constraintPoliciesFromConfig: () => constraintPoliciesFromConfig,
|
|
65
68
|
contextTokenCount: () => contextTokenCount,
|
|
66
69
|
createCodexSession: () => createCodexSession,
|
|
67
70
|
createCodingAgentSession: () => createCodingAgentSession,
|
|
@@ -1952,7 +1955,17 @@ function runWithContext(ctx, fn) {
|
|
|
1952
1955
|
return getStorage().run(ctx, fn);
|
|
1953
1956
|
}
|
|
1954
1957
|
function runAsUser(user, fn) {
|
|
1955
|
-
const {
|
|
1958
|
+
const {
|
|
1959
|
+
userId,
|
|
1960
|
+
orgId,
|
|
1961
|
+
role,
|
|
1962
|
+
projectId,
|
|
1963
|
+
requestId,
|
|
1964
|
+
policies,
|
|
1965
|
+
constraintPolicies,
|
|
1966
|
+
allowedSources,
|
|
1967
|
+
graphVersion
|
|
1968
|
+
} = user;
|
|
1956
1969
|
return runWithContext(
|
|
1957
1970
|
// `allowedSources` is spread in only when given, so an absent restriction
|
|
1958
1971
|
// stays absent rather than becoming an explicit `undefined` that a later
|
|
@@ -1962,6 +1975,7 @@ function runAsUser(user, fn) {
|
|
|
1962
1975
|
projectId,
|
|
1963
1976
|
requestId,
|
|
1964
1977
|
policies,
|
|
1978
|
+
...constraintPolicies?.length ? { constraintPolicies } : {},
|
|
1965
1979
|
...allowedSources !== void 0 ? { allowedSources } : {},
|
|
1966
1980
|
...graphVersion !== void 0 ? { graphVersion } : {}
|
|
1967
1981
|
},
|
|
@@ -2642,42 +2656,148 @@ function buildDirectToolCacheKey(toolId, parameters) {
|
|
|
2642
2656
|
return `et-direct:${toolId}:${stableStringify(parameters || {})}`;
|
|
2643
2657
|
}
|
|
2644
2658
|
|
|
2645
|
-
// src/handlers/
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2659
|
+
// src/handlers/data-access/v2/policies.ts
|
|
2660
|
+
var CONSTRAINT_OPS = [
|
|
2661
|
+
"in",
|
|
2662
|
+
"not_in",
|
|
2663
|
+
"eq",
|
|
2664
|
+
"ne",
|
|
2665
|
+
"gt",
|
|
2666
|
+
"gte",
|
|
2667
|
+
"lt",
|
|
2668
|
+
"lte",
|
|
2669
|
+
"like",
|
|
2670
|
+
"not_like",
|
|
2671
|
+
"is_null",
|
|
2672
|
+
"is_not_null"
|
|
2673
|
+
];
|
|
2674
|
+
var NO_VALUE_OPS = /* @__PURE__ */ new Set(["is_null", "is_not_null"]);
|
|
2675
|
+
function constraintPoliciesFromConfig(raw) {
|
|
2676
|
+
const entries = Array.isArray(raw) ? raw : [raw];
|
|
2677
|
+
const out = [];
|
|
2678
|
+
for (const entry of entries) {
|
|
2679
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
|
|
2680
|
+
const e = entry;
|
|
2681
|
+
const sourceId = typeof e.sourceId === "string" && e.sourceId ? e.sourceId : null;
|
|
2682
|
+
const label = typeof e.label === "string" && e.label.trim() ? e.label.trim() : void 0;
|
|
2683
|
+
const bad = (why) => ({ sourceId, label, invalid: why });
|
|
2684
|
+
let schema2;
|
|
2685
|
+
if (e.schema !== void 0 && e.schema !== null) {
|
|
2686
|
+
if (typeof e.schema !== "string" || !e.schema.trim()) {
|
|
2687
|
+
out.push(bad("schema must be a schema name"));
|
|
2688
|
+
continue;
|
|
2689
|
+
}
|
|
2690
|
+
schema2 = e.schema.trim();
|
|
2691
|
+
}
|
|
2692
|
+
let readableTables;
|
|
2693
|
+
let tablesBad;
|
|
2694
|
+
if (e.readableTables !== void 0 && e.readableTables !== null) {
|
|
2695
|
+
if (typeof e.readableTables !== "object" || Array.isArray(e.readableTables)) {
|
|
2696
|
+
out.push(bad("readableTables must be an object of table to columns"));
|
|
2697
|
+
continue;
|
|
2698
|
+
}
|
|
2699
|
+
readableTables = {};
|
|
2700
|
+
for (const [table, cols] of Object.entries(e.readableTables)) {
|
|
2701
|
+
if (cols === null) {
|
|
2702
|
+
readableTables[table] = null;
|
|
2703
|
+
continue;
|
|
2704
|
+
}
|
|
2705
|
+
if (!Array.isArray(cols) || cols.length === 0) {
|
|
2706
|
+
tablesBad = `readableTables["${table}"] must be a non-empty list or null`;
|
|
2707
|
+
break;
|
|
2708
|
+
}
|
|
2709
|
+
const columns = cols.filter((c) => typeof c === "string" && !!c.trim()).map((c) => c.trim());
|
|
2710
|
+
if (columns.length !== cols.length) {
|
|
2711
|
+
tablesBad = `readableTables["${table}"] has an entry that is not a column name`;
|
|
2712
|
+
break;
|
|
2713
|
+
}
|
|
2714
|
+
readableTables[table] = columns;
|
|
2715
|
+
}
|
|
2716
|
+
if (!tablesBad && Object.keys(readableTables).length === 0) {
|
|
2717
|
+
tablesBad = "readableTables names no tables \u2014 omit it to allow every table";
|
|
2718
|
+
}
|
|
2719
|
+
if (tablesBad) {
|
|
2720
|
+
out.push(bad(tablesBad));
|
|
2721
|
+
continue;
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
const rowFilters = {};
|
|
2725
|
+
let filtersBad;
|
|
2726
|
+
const rawFilters = e.rowFilters;
|
|
2727
|
+
if (rawFilters !== void 0 && rawFilters !== null) {
|
|
2728
|
+
if (typeof rawFilters !== "object" || Array.isArray(rawFilters)) {
|
|
2729
|
+
filtersBad = "rowFilters must be an object keyed by table";
|
|
2730
|
+
} else {
|
|
2731
|
+
for (const [table, items] of Object.entries(rawFilters)) {
|
|
2732
|
+
if (readableTables && !(table in readableTables)) {
|
|
2733
|
+
filtersBad = `rowFilters names "${table}", which readableTables does not allow`;
|
|
2734
|
+
break;
|
|
2735
|
+
}
|
|
2736
|
+
if (!Array.isArray(items) || items.length === 0) {
|
|
2737
|
+
filtersBad = `rowFilters["${table}"] must be a non-empty list`;
|
|
2738
|
+
break;
|
|
2739
|
+
}
|
|
2740
|
+
const parsed = [];
|
|
2741
|
+
for (const item of items) {
|
|
2742
|
+
if (!item || typeof item !== "object") {
|
|
2743
|
+
filtersBad = `rowFilters["${table}"] has an entry that is not an object`;
|
|
2744
|
+
break;
|
|
2745
|
+
}
|
|
2746
|
+
const f = item;
|
|
2747
|
+
if (typeof f.column !== "string" || !f.column.trim()) {
|
|
2748
|
+
filtersBad = `a filter on "${table}" has no column`;
|
|
2749
|
+
break;
|
|
2750
|
+
}
|
|
2751
|
+
const op = typeof f.op === "string" ? f.op.toLowerCase() : "in";
|
|
2752
|
+
if (!CONSTRAINT_OPS.includes(op)) {
|
|
2753
|
+
filtersBad = `unsupported operator "${f.op}" on "${table}.${f.column}"`;
|
|
2754
|
+
break;
|
|
2755
|
+
}
|
|
2756
|
+
const values = Array.isArray(f.values) ? f.values : [];
|
|
2757
|
+
if (!NO_VALUE_OPS.has(op) && values.length === 0) {
|
|
2758
|
+
filtersBad = `the filter on "${table}.${f.column}" has no values`;
|
|
2759
|
+
break;
|
|
2760
|
+
}
|
|
2761
|
+
parsed.push({
|
|
2762
|
+
column: f.column.trim(),
|
|
2763
|
+
op,
|
|
2764
|
+
...NO_VALUE_OPS.has(op) ? {} : { values },
|
|
2765
|
+
label: typeof f.label === "string" && f.label.trim() ? f.label.trim() : void 0
|
|
2766
|
+
});
|
|
2767
|
+
}
|
|
2768
|
+
if (filtersBad) break;
|
|
2769
|
+
rowFilters[table] = parsed;
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
if (filtersBad) {
|
|
2774
|
+
out.push(bad(filtersBad));
|
|
2775
|
+
continue;
|
|
2776
|
+
}
|
|
2777
|
+
const rawLimits = e.limits;
|
|
2778
|
+
const num = (v) => typeof v === "number" && Number.isInteger(v) && v > 0 ? v : void 0;
|
|
2779
|
+
const limits = rawLimits ? { maxRows: num(rawLimits.maxRows), maxExecutionSeconds: num(rawLimits.maxExecutionSeconds) } : void 0;
|
|
2780
|
+
out.push({
|
|
2781
|
+
sourceId,
|
|
2782
|
+
label,
|
|
2783
|
+
...schema2 ? { schema: schema2 } : {},
|
|
2784
|
+
...readableTables ? { readableTables } : {},
|
|
2785
|
+
...Object.keys(rowFilters).length ? { rowFilters } : {},
|
|
2786
|
+
...limits ? { limits } : {}
|
|
2787
|
+
});
|
|
2788
|
+
}
|
|
2789
|
+
return out;
|
|
2649
2790
|
}
|
|
2791
|
+
|
|
2792
|
+
// src/handlers/data-access/shape.ts
|
|
2650
2793
|
function scopedForm(config2) {
|
|
2651
2794
|
if (!config2 || typeof config2 !== "object" || Array.isArray(config2)) return void 0;
|
|
2652
2795
|
const c = config2;
|
|
2653
2796
|
return "allowedSources" in c || "policies" in c ? c : void 0;
|
|
2654
2797
|
}
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
if (!warnedBadSources) {
|
|
2659
|
-
warnedBadSources = true;
|
|
2660
|
-
logger.warn(
|
|
2661
|
-
`[RequestIdentity] "allowedSources" is ${typeof value}, not a list of source ids \u2014 treating it as NO sources rather than all of them. Fix the config: "allowedSources": ["mssql-1a2b"].`
|
|
2662
|
-
);
|
|
2663
|
-
}
|
|
2664
|
-
return [];
|
|
2665
|
-
}
|
|
2666
|
-
const out = [];
|
|
2667
|
-
for (const item of value) {
|
|
2668
|
-
if (typeof item !== "string" || !item.trim()) continue;
|
|
2669
|
-
const id = item.trim();
|
|
2670
|
-
if (!out.includes(id)) out.push(id);
|
|
2671
|
-
}
|
|
2672
|
-
return out;
|
|
2673
|
-
}
|
|
2674
|
-
function accessFromConfig(config2) {
|
|
2675
|
-
const scoped = scopedForm(config2);
|
|
2676
|
-
return {
|
|
2677
|
-
policies: policiesFromConfig(config2),
|
|
2678
|
-
allowedSources: scoped ? allowedSourcesFrom(scoped.allowedSources) : null
|
|
2679
|
-
};
|
|
2680
|
-
}
|
|
2798
|
+
|
|
2799
|
+
// src/handlers/data-access/v1/policies.ts
|
|
2800
|
+
var warnedUnlabelled = false;
|
|
2681
2801
|
function exceptionsFromConfig(raw) {
|
|
2682
2802
|
if (!Array.isArray(raw)) return [];
|
|
2683
2803
|
const str = (v) => typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
@@ -2756,16 +2876,55 @@ function policiesFromConfig(config2) {
|
|
|
2756
2876
|
}
|
|
2757
2877
|
return out;
|
|
2758
2878
|
}
|
|
2879
|
+
|
|
2880
|
+
// src/handlers/request-identity.ts
|
|
2881
|
+
function graphVersionOf(v) {
|
|
2882
|
+
if (v === "draft") return "draft";
|
|
2883
|
+
return Number.isInteger(v) && v > 0 ? v : void 0;
|
|
2884
|
+
}
|
|
2885
|
+
function allowedSourcesFrom(value) {
|
|
2886
|
+
if (value === void 0 || value === null) return null;
|
|
2887
|
+
if (!Array.isArray(value)) {
|
|
2888
|
+
if (!warnedBadSources) {
|
|
2889
|
+
warnedBadSources = true;
|
|
2890
|
+
logger.warn(
|
|
2891
|
+
`[RequestIdentity] "allowedSources" is ${typeof value}, not a list of source ids \u2014 treating it as NO sources rather than all of them. Fix the config: "allowedSources": ["mssql-1a2b"].`
|
|
2892
|
+
);
|
|
2893
|
+
}
|
|
2894
|
+
return [];
|
|
2895
|
+
}
|
|
2896
|
+
const out = [];
|
|
2897
|
+
for (const item of value) {
|
|
2898
|
+
if (typeof item !== "string" || !item.trim()) continue;
|
|
2899
|
+
const id = item.trim();
|
|
2900
|
+
if (!out.includes(id)) out.push(id);
|
|
2901
|
+
}
|
|
2902
|
+
return out;
|
|
2903
|
+
}
|
|
2904
|
+
function accessFromConfig(config2) {
|
|
2905
|
+
const scoped = scopedForm(config2);
|
|
2906
|
+
const allowedSources = scoped ? allowedSourcesFrom(scoped.allowedSources) : null;
|
|
2907
|
+
if (scoped?.version === 2) {
|
|
2908
|
+
return {
|
|
2909
|
+
policies: [],
|
|
2910
|
+
constraintPolicies: constraintPoliciesFromConfig(scoped.policies),
|
|
2911
|
+
allowedSources
|
|
2912
|
+
};
|
|
2913
|
+
}
|
|
2914
|
+
return { policies: policiesFromConfig(config2), constraintPolicies: [], allowedSources };
|
|
2915
|
+
}
|
|
2759
2916
|
var warnedUntrusted = false;
|
|
2760
2917
|
var warnedAnonymous = false;
|
|
2761
|
-
var warnedUnlabelled = false;
|
|
2762
2918
|
var warnedBadSources = false;
|
|
2763
2919
|
var announcedVerified = false;
|
|
2764
2920
|
var reportedIdMismatches = /* @__PURE__ */ new Set();
|
|
2765
2921
|
function runWithMessageIdentity(message, fn) {
|
|
2766
2922
|
const verified = message?.authContext;
|
|
2767
2923
|
const requestId = message?.id;
|
|
2768
|
-
const { policies, allowedSources } = verified ? accessFromConfig(verified.config) : accessFromConfig(message?.payload?.config);
|
|
2924
|
+
const { policies, constraintPolicies, allowedSources } = verified ? accessFromConfig(verified.config) : accessFromConfig(message?.payload?.config);
|
|
2925
|
+
logger.info(
|
|
2926
|
+
`[RequestIdentity] ${message?.type ?? "?"}: access from ${verified ? "authContext" : "payload"}${verified && verified.config == null ? " (none on it)" : ""}, allowedSources=${allowedSources === null ? "every source" : `[${allowedSources.join(", ") || "NONE"}]`}, ${constraintPolicies.length} constraint policy(ies), ${policies.length} row policy(ies)`
|
|
2927
|
+
);
|
|
2769
2928
|
if (verified?.userId) {
|
|
2770
2929
|
const claimedId = message?.payload?.userId;
|
|
2771
2930
|
if (!announcedVerified) {
|
|
@@ -2790,6 +2949,7 @@ function runWithMessageIdentity(message, fn) {
|
|
|
2790
2949
|
role: verified.role,
|
|
2791
2950
|
requestId,
|
|
2792
2951
|
policies,
|
|
2952
|
+
constraintPolicies,
|
|
2793
2953
|
// `?? undefined` so "no restriction" leaves the key off the context
|
|
2794
2954
|
// entirely; `[]` is passed through as the deny-everything it means.
|
|
2795
2955
|
allowedSources: allowedSources ?? void 0,
|
|
@@ -2807,7 +2967,10 @@ function runWithMessageIdentity(message, fn) {
|
|
|
2807
2967
|
"[RequestIdentity] Using the client-supplied payload.userId as the principal \u2014 the relay is not stamping a verified authContext yet, so this identity is NOT trustworthy. Fine for plumbing; do not enable policy enforcement until the relay change lands."
|
|
2808
2968
|
);
|
|
2809
2969
|
}
|
|
2810
|
-
return runAsUser(
|
|
2970
|
+
return runAsUser(
|
|
2971
|
+
{ userId: claimed, requestId, policies, constraintPolicies, allowedSources: allowedSources ?? void 0 },
|
|
2972
|
+
fn
|
|
2973
|
+
);
|
|
2811
2974
|
}
|
|
2812
2975
|
if (!warnedAnonymous) {
|
|
2813
2976
|
warnedAnonymous = true;
|
|
@@ -24649,6 +24812,20 @@ function buildEnv(opts) {
|
|
|
24649
24812
|
}
|
|
24650
24813
|
return { ...env, ...opts.env ?? {} };
|
|
24651
24814
|
}
|
|
24815
|
+
var CODEX_DOC_MAX_BYTES = 256 * 1024;
|
|
24816
|
+
function codexRunConfig(opts) {
|
|
24817
|
+
return {
|
|
24818
|
+
// Tools reach codex as MCP servers; each server's name shows up on
|
|
24819
|
+
// every tool event, so the runner can tell ours from codex's own.
|
|
24820
|
+
...opts.mcpServers && Object.keys(opts.mcpServers).length ? { mcp_servers: opts.mcpServers } : {},
|
|
24821
|
+
// Per run, not ~/.codex/config.toml: a host without that line would run
|
|
24822
|
+
// the agent with no instructions at all. AGENTS.md still wins if present.
|
|
24823
|
+
...opts.instructionsFile && opts.instructionsFile !== "AGENTS.md" ? { project_doc_fallback_filenames: [opts.instructionsFile] } : {},
|
|
24824
|
+
project_doc_max_bytes: CODEX_DOC_MAX_BYTES,
|
|
24825
|
+
// Last: a deployment's own value wins.
|
|
24826
|
+
...opts.extraConfig ?? {}
|
|
24827
|
+
};
|
|
24828
|
+
}
|
|
24652
24829
|
function createCodexSession(opts) {
|
|
24653
24830
|
const model = opts.model ?? process.env.CODEX_AGENT_MODEL;
|
|
24654
24831
|
let thread = null;
|
|
@@ -24671,21 +24848,12 @@ function createCodexSession(opts) {
|
|
|
24671
24848
|
async function ensureThread() {
|
|
24672
24849
|
if (thread) return thread;
|
|
24673
24850
|
const { Codex } = await loadCodex();
|
|
24674
|
-
const config2 =
|
|
24675
|
-
// Tools reach codex as MCP servers; each server's name shows up on
|
|
24676
|
-
// every tool event, so the runner can tell ours from codex's own.
|
|
24677
|
-
...opts.mcpServers && Object.keys(opts.mcpServers).length ? { mcp_servers: opts.mcpServers } : {},
|
|
24678
|
-
// Per run, not ~/.codex/config.toml: a host without that line would run
|
|
24679
|
-
// the agent with no instructions at all. AGENTS.md still wins if present.
|
|
24680
|
-
...opts.instructionsFile && opts.instructionsFile !== "AGENTS.md" ? { project_doc_fallback_filenames: [opts.instructionsFile] } : {},
|
|
24681
|
-
...opts.extraConfig ?? {}
|
|
24682
|
-
};
|
|
24851
|
+
const config2 = codexRunConfig(opts);
|
|
24683
24852
|
const codex = new Codex({
|
|
24684
24853
|
...opts.apiKey ? { apiKey: opts.apiKey } : {},
|
|
24685
24854
|
...opts.baseUrl ? { baseUrl: opts.baseUrl } : {},
|
|
24686
24855
|
env: buildEnv(opts),
|
|
24687
|
-
|
|
24688
|
-
...Object.keys(config2).length ? { config: config2 } : {}
|
|
24856
|
+
config: config2
|
|
24689
24857
|
});
|
|
24690
24858
|
thread = resumeId ? codex.resumeThread(resumeId, threadOptions()) : codex.startThread(threadOptions());
|
|
24691
24859
|
return thread;
|
|
@@ -30181,6 +30349,7 @@ var SuperatomSDK = class {
|
|
|
30181
30349
|
ANSWER_COMPONENT_NAMES,
|
|
30182
30350
|
BM25L,
|
|
30183
30351
|
CATEGORY_KEYS,
|
|
30352
|
+
CODEX_DOC_MAX_BYTES,
|
|
30184
30353
|
CONTEXT_CONFIG,
|
|
30185
30354
|
CleanupService,
|
|
30186
30355
|
DEFAULT_AGENT_CONFIG,
|
|
@@ -30209,6 +30378,8 @@ var SuperatomSDK = class {
|
|
|
30209
30378
|
bridgePreamble,
|
|
30210
30379
|
captureContext,
|
|
30211
30380
|
clearContextTokens,
|
|
30381
|
+
codexRunConfig,
|
|
30382
|
+
constraintPoliciesFromConfig,
|
|
30212
30383
|
contextTokenCount,
|
|
30213
30384
|
createCodexSession,
|
|
30214
30385
|
createCodingAgentSession,
|
package/dist/index.mjs
CHANGED
|
@@ -1840,7 +1840,17 @@ function runWithContext(ctx, fn) {
|
|
|
1840
1840
|
return getStorage().run(ctx, fn);
|
|
1841
1841
|
}
|
|
1842
1842
|
function runAsUser(user, fn) {
|
|
1843
|
-
const {
|
|
1843
|
+
const {
|
|
1844
|
+
userId,
|
|
1845
|
+
orgId,
|
|
1846
|
+
role,
|
|
1847
|
+
projectId,
|
|
1848
|
+
requestId,
|
|
1849
|
+
policies,
|
|
1850
|
+
constraintPolicies,
|
|
1851
|
+
allowedSources,
|
|
1852
|
+
graphVersion
|
|
1853
|
+
} = user;
|
|
1844
1854
|
return runWithContext(
|
|
1845
1855
|
// `allowedSources` is spread in only when given, so an absent restriction
|
|
1846
1856
|
// stays absent rather than becoming an explicit `undefined` that a later
|
|
@@ -1850,6 +1860,7 @@ function runAsUser(user, fn) {
|
|
|
1850
1860
|
projectId,
|
|
1851
1861
|
requestId,
|
|
1852
1862
|
policies,
|
|
1863
|
+
...constraintPolicies?.length ? { constraintPolicies } : {},
|
|
1853
1864
|
...allowedSources !== void 0 ? { allowedSources } : {},
|
|
1854
1865
|
...graphVersion !== void 0 ? { graphVersion } : {}
|
|
1855
1866
|
},
|
|
@@ -2530,42 +2541,148 @@ function buildDirectToolCacheKey(toolId, parameters) {
|
|
|
2530
2541
|
return `et-direct:${toolId}:${stableStringify(parameters || {})}`;
|
|
2531
2542
|
}
|
|
2532
2543
|
|
|
2533
|
-
// src/handlers/
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2544
|
+
// src/handlers/data-access/v2/policies.ts
|
|
2545
|
+
var CONSTRAINT_OPS = [
|
|
2546
|
+
"in",
|
|
2547
|
+
"not_in",
|
|
2548
|
+
"eq",
|
|
2549
|
+
"ne",
|
|
2550
|
+
"gt",
|
|
2551
|
+
"gte",
|
|
2552
|
+
"lt",
|
|
2553
|
+
"lte",
|
|
2554
|
+
"like",
|
|
2555
|
+
"not_like",
|
|
2556
|
+
"is_null",
|
|
2557
|
+
"is_not_null"
|
|
2558
|
+
];
|
|
2559
|
+
var NO_VALUE_OPS = /* @__PURE__ */ new Set(["is_null", "is_not_null"]);
|
|
2560
|
+
function constraintPoliciesFromConfig(raw) {
|
|
2561
|
+
const entries = Array.isArray(raw) ? raw : [raw];
|
|
2562
|
+
const out = [];
|
|
2563
|
+
for (const entry of entries) {
|
|
2564
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
|
|
2565
|
+
const e = entry;
|
|
2566
|
+
const sourceId = typeof e.sourceId === "string" && e.sourceId ? e.sourceId : null;
|
|
2567
|
+
const label = typeof e.label === "string" && e.label.trim() ? e.label.trim() : void 0;
|
|
2568
|
+
const bad = (why) => ({ sourceId, label, invalid: why });
|
|
2569
|
+
let schema2;
|
|
2570
|
+
if (e.schema !== void 0 && e.schema !== null) {
|
|
2571
|
+
if (typeof e.schema !== "string" || !e.schema.trim()) {
|
|
2572
|
+
out.push(bad("schema must be a schema name"));
|
|
2573
|
+
continue;
|
|
2574
|
+
}
|
|
2575
|
+
schema2 = e.schema.trim();
|
|
2576
|
+
}
|
|
2577
|
+
let readableTables;
|
|
2578
|
+
let tablesBad;
|
|
2579
|
+
if (e.readableTables !== void 0 && e.readableTables !== null) {
|
|
2580
|
+
if (typeof e.readableTables !== "object" || Array.isArray(e.readableTables)) {
|
|
2581
|
+
out.push(bad("readableTables must be an object of table to columns"));
|
|
2582
|
+
continue;
|
|
2583
|
+
}
|
|
2584
|
+
readableTables = {};
|
|
2585
|
+
for (const [table, cols] of Object.entries(e.readableTables)) {
|
|
2586
|
+
if (cols === null) {
|
|
2587
|
+
readableTables[table] = null;
|
|
2588
|
+
continue;
|
|
2589
|
+
}
|
|
2590
|
+
if (!Array.isArray(cols) || cols.length === 0) {
|
|
2591
|
+
tablesBad = `readableTables["${table}"] must be a non-empty list or null`;
|
|
2592
|
+
break;
|
|
2593
|
+
}
|
|
2594
|
+
const columns = cols.filter((c) => typeof c === "string" && !!c.trim()).map((c) => c.trim());
|
|
2595
|
+
if (columns.length !== cols.length) {
|
|
2596
|
+
tablesBad = `readableTables["${table}"] has an entry that is not a column name`;
|
|
2597
|
+
break;
|
|
2598
|
+
}
|
|
2599
|
+
readableTables[table] = columns;
|
|
2600
|
+
}
|
|
2601
|
+
if (!tablesBad && Object.keys(readableTables).length === 0) {
|
|
2602
|
+
tablesBad = "readableTables names no tables \u2014 omit it to allow every table";
|
|
2603
|
+
}
|
|
2604
|
+
if (tablesBad) {
|
|
2605
|
+
out.push(bad(tablesBad));
|
|
2606
|
+
continue;
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2609
|
+
const rowFilters = {};
|
|
2610
|
+
let filtersBad;
|
|
2611
|
+
const rawFilters = e.rowFilters;
|
|
2612
|
+
if (rawFilters !== void 0 && rawFilters !== null) {
|
|
2613
|
+
if (typeof rawFilters !== "object" || Array.isArray(rawFilters)) {
|
|
2614
|
+
filtersBad = "rowFilters must be an object keyed by table";
|
|
2615
|
+
} else {
|
|
2616
|
+
for (const [table, items] of Object.entries(rawFilters)) {
|
|
2617
|
+
if (readableTables && !(table in readableTables)) {
|
|
2618
|
+
filtersBad = `rowFilters names "${table}", which readableTables does not allow`;
|
|
2619
|
+
break;
|
|
2620
|
+
}
|
|
2621
|
+
if (!Array.isArray(items) || items.length === 0) {
|
|
2622
|
+
filtersBad = `rowFilters["${table}"] must be a non-empty list`;
|
|
2623
|
+
break;
|
|
2624
|
+
}
|
|
2625
|
+
const parsed = [];
|
|
2626
|
+
for (const item of items) {
|
|
2627
|
+
if (!item || typeof item !== "object") {
|
|
2628
|
+
filtersBad = `rowFilters["${table}"] has an entry that is not an object`;
|
|
2629
|
+
break;
|
|
2630
|
+
}
|
|
2631
|
+
const f = item;
|
|
2632
|
+
if (typeof f.column !== "string" || !f.column.trim()) {
|
|
2633
|
+
filtersBad = `a filter on "${table}" has no column`;
|
|
2634
|
+
break;
|
|
2635
|
+
}
|
|
2636
|
+
const op = typeof f.op === "string" ? f.op.toLowerCase() : "in";
|
|
2637
|
+
if (!CONSTRAINT_OPS.includes(op)) {
|
|
2638
|
+
filtersBad = `unsupported operator "${f.op}" on "${table}.${f.column}"`;
|
|
2639
|
+
break;
|
|
2640
|
+
}
|
|
2641
|
+
const values = Array.isArray(f.values) ? f.values : [];
|
|
2642
|
+
if (!NO_VALUE_OPS.has(op) && values.length === 0) {
|
|
2643
|
+
filtersBad = `the filter on "${table}.${f.column}" has no values`;
|
|
2644
|
+
break;
|
|
2645
|
+
}
|
|
2646
|
+
parsed.push({
|
|
2647
|
+
column: f.column.trim(),
|
|
2648
|
+
op,
|
|
2649
|
+
...NO_VALUE_OPS.has(op) ? {} : { values },
|
|
2650
|
+
label: typeof f.label === "string" && f.label.trim() ? f.label.trim() : void 0
|
|
2651
|
+
});
|
|
2652
|
+
}
|
|
2653
|
+
if (filtersBad) break;
|
|
2654
|
+
rowFilters[table] = parsed;
|
|
2655
|
+
}
|
|
2656
|
+
}
|
|
2657
|
+
}
|
|
2658
|
+
if (filtersBad) {
|
|
2659
|
+
out.push(bad(filtersBad));
|
|
2660
|
+
continue;
|
|
2661
|
+
}
|
|
2662
|
+
const rawLimits = e.limits;
|
|
2663
|
+
const num = (v) => typeof v === "number" && Number.isInteger(v) && v > 0 ? v : void 0;
|
|
2664
|
+
const limits = rawLimits ? { maxRows: num(rawLimits.maxRows), maxExecutionSeconds: num(rawLimits.maxExecutionSeconds) } : void 0;
|
|
2665
|
+
out.push({
|
|
2666
|
+
sourceId,
|
|
2667
|
+
label,
|
|
2668
|
+
...schema2 ? { schema: schema2 } : {},
|
|
2669
|
+
...readableTables ? { readableTables } : {},
|
|
2670
|
+
...Object.keys(rowFilters).length ? { rowFilters } : {},
|
|
2671
|
+
...limits ? { limits } : {}
|
|
2672
|
+
});
|
|
2673
|
+
}
|
|
2674
|
+
return out;
|
|
2537
2675
|
}
|
|
2676
|
+
|
|
2677
|
+
// src/handlers/data-access/shape.ts
|
|
2538
2678
|
function scopedForm(config2) {
|
|
2539
2679
|
if (!config2 || typeof config2 !== "object" || Array.isArray(config2)) return void 0;
|
|
2540
2680
|
const c = config2;
|
|
2541
2681
|
return "allowedSources" in c || "policies" in c ? c : void 0;
|
|
2542
2682
|
}
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
if (!warnedBadSources) {
|
|
2547
|
-
warnedBadSources = true;
|
|
2548
|
-
logger.warn(
|
|
2549
|
-
`[RequestIdentity] "allowedSources" is ${typeof value}, not a list of source ids \u2014 treating it as NO sources rather than all of them. Fix the config: "allowedSources": ["mssql-1a2b"].`
|
|
2550
|
-
);
|
|
2551
|
-
}
|
|
2552
|
-
return [];
|
|
2553
|
-
}
|
|
2554
|
-
const out = [];
|
|
2555
|
-
for (const item of value) {
|
|
2556
|
-
if (typeof item !== "string" || !item.trim()) continue;
|
|
2557
|
-
const id = item.trim();
|
|
2558
|
-
if (!out.includes(id)) out.push(id);
|
|
2559
|
-
}
|
|
2560
|
-
return out;
|
|
2561
|
-
}
|
|
2562
|
-
function accessFromConfig(config2) {
|
|
2563
|
-
const scoped = scopedForm(config2);
|
|
2564
|
-
return {
|
|
2565
|
-
policies: policiesFromConfig(config2),
|
|
2566
|
-
allowedSources: scoped ? allowedSourcesFrom(scoped.allowedSources) : null
|
|
2567
|
-
};
|
|
2568
|
-
}
|
|
2683
|
+
|
|
2684
|
+
// src/handlers/data-access/v1/policies.ts
|
|
2685
|
+
var warnedUnlabelled = false;
|
|
2569
2686
|
function exceptionsFromConfig(raw) {
|
|
2570
2687
|
if (!Array.isArray(raw)) return [];
|
|
2571
2688
|
const str = (v) => typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
@@ -2644,16 +2761,55 @@ function policiesFromConfig(config2) {
|
|
|
2644
2761
|
}
|
|
2645
2762
|
return out;
|
|
2646
2763
|
}
|
|
2764
|
+
|
|
2765
|
+
// src/handlers/request-identity.ts
|
|
2766
|
+
function graphVersionOf(v) {
|
|
2767
|
+
if (v === "draft") return "draft";
|
|
2768
|
+
return Number.isInteger(v) && v > 0 ? v : void 0;
|
|
2769
|
+
}
|
|
2770
|
+
function allowedSourcesFrom(value) {
|
|
2771
|
+
if (value === void 0 || value === null) return null;
|
|
2772
|
+
if (!Array.isArray(value)) {
|
|
2773
|
+
if (!warnedBadSources) {
|
|
2774
|
+
warnedBadSources = true;
|
|
2775
|
+
logger.warn(
|
|
2776
|
+
`[RequestIdentity] "allowedSources" is ${typeof value}, not a list of source ids \u2014 treating it as NO sources rather than all of them. Fix the config: "allowedSources": ["mssql-1a2b"].`
|
|
2777
|
+
);
|
|
2778
|
+
}
|
|
2779
|
+
return [];
|
|
2780
|
+
}
|
|
2781
|
+
const out = [];
|
|
2782
|
+
for (const item of value) {
|
|
2783
|
+
if (typeof item !== "string" || !item.trim()) continue;
|
|
2784
|
+
const id = item.trim();
|
|
2785
|
+
if (!out.includes(id)) out.push(id);
|
|
2786
|
+
}
|
|
2787
|
+
return out;
|
|
2788
|
+
}
|
|
2789
|
+
function accessFromConfig(config2) {
|
|
2790
|
+
const scoped = scopedForm(config2);
|
|
2791
|
+
const allowedSources = scoped ? allowedSourcesFrom(scoped.allowedSources) : null;
|
|
2792
|
+
if (scoped?.version === 2) {
|
|
2793
|
+
return {
|
|
2794
|
+
policies: [],
|
|
2795
|
+
constraintPolicies: constraintPoliciesFromConfig(scoped.policies),
|
|
2796
|
+
allowedSources
|
|
2797
|
+
};
|
|
2798
|
+
}
|
|
2799
|
+
return { policies: policiesFromConfig(config2), constraintPolicies: [], allowedSources };
|
|
2800
|
+
}
|
|
2647
2801
|
var warnedUntrusted = false;
|
|
2648
2802
|
var warnedAnonymous = false;
|
|
2649
|
-
var warnedUnlabelled = false;
|
|
2650
2803
|
var warnedBadSources = false;
|
|
2651
2804
|
var announcedVerified = false;
|
|
2652
2805
|
var reportedIdMismatches = /* @__PURE__ */ new Set();
|
|
2653
2806
|
function runWithMessageIdentity(message, fn) {
|
|
2654
2807
|
const verified = message?.authContext;
|
|
2655
2808
|
const requestId = message?.id;
|
|
2656
|
-
const { policies, allowedSources } = verified ? accessFromConfig(verified.config) : accessFromConfig(message?.payload?.config);
|
|
2809
|
+
const { policies, constraintPolicies, allowedSources } = verified ? accessFromConfig(verified.config) : accessFromConfig(message?.payload?.config);
|
|
2810
|
+
logger.info(
|
|
2811
|
+
`[RequestIdentity] ${message?.type ?? "?"}: access from ${verified ? "authContext" : "payload"}${verified && verified.config == null ? " (none on it)" : ""}, allowedSources=${allowedSources === null ? "every source" : `[${allowedSources.join(", ") || "NONE"}]`}, ${constraintPolicies.length} constraint policy(ies), ${policies.length} row policy(ies)`
|
|
2812
|
+
);
|
|
2657
2813
|
if (verified?.userId) {
|
|
2658
2814
|
const claimedId = message?.payload?.userId;
|
|
2659
2815
|
if (!announcedVerified) {
|
|
@@ -2678,6 +2834,7 @@ function runWithMessageIdentity(message, fn) {
|
|
|
2678
2834
|
role: verified.role,
|
|
2679
2835
|
requestId,
|
|
2680
2836
|
policies,
|
|
2837
|
+
constraintPolicies,
|
|
2681
2838
|
// `?? undefined` so "no restriction" leaves the key off the context
|
|
2682
2839
|
// entirely; `[]` is passed through as the deny-everything it means.
|
|
2683
2840
|
allowedSources: allowedSources ?? void 0,
|
|
@@ -2695,7 +2852,10 @@ function runWithMessageIdentity(message, fn) {
|
|
|
2695
2852
|
"[RequestIdentity] Using the client-supplied payload.userId as the principal \u2014 the relay is not stamping a verified authContext yet, so this identity is NOT trustworthy. Fine for plumbing; do not enable policy enforcement until the relay change lands."
|
|
2696
2853
|
);
|
|
2697
2854
|
}
|
|
2698
|
-
return runAsUser(
|
|
2855
|
+
return runAsUser(
|
|
2856
|
+
{ userId: claimed, requestId, policies, constraintPolicies, allowedSources: allowedSources ?? void 0 },
|
|
2857
|
+
fn
|
|
2858
|
+
);
|
|
2699
2859
|
}
|
|
2700
2860
|
if (!warnedAnonymous) {
|
|
2701
2861
|
warnedAnonymous = true;
|
|
@@ -24537,6 +24697,20 @@ function buildEnv(opts) {
|
|
|
24537
24697
|
}
|
|
24538
24698
|
return { ...env, ...opts.env ?? {} };
|
|
24539
24699
|
}
|
|
24700
|
+
var CODEX_DOC_MAX_BYTES = 256 * 1024;
|
|
24701
|
+
function codexRunConfig(opts) {
|
|
24702
|
+
return {
|
|
24703
|
+
// Tools reach codex as MCP servers; each server's name shows up on
|
|
24704
|
+
// every tool event, so the runner can tell ours from codex's own.
|
|
24705
|
+
...opts.mcpServers && Object.keys(opts.mcpServers).length ? { mcp_servers: opts.mcpServers } : {},
|
|
24706
|
+
// Per run, not ~/.codex/config.toml: a host without that line would run
|
|
24707
|
+
// the agent with no instructions at all. AGENTS.md still wins if present.
|
|
24708
|
+
...opts.instructionsFile && opts.instructionsFile !== "AGENTS.md" ? { project_doc_fallback_filenames: [opts.instructionsFile] } : {},
|
|
24709
|
+
project_doc_max_bytes: CODEX_DOC_MAX_BYTES,
|
|
24710
|
+
// Last: a deployment's own value wins.
|
|
24711
|
+
...opts.extraConfig ?? {}
|
|
24712
|
+
};
|
|
24713
|
+
}
|
|
24540
24714
|
function createCodexSession(opts) {
|
|
24541
24715
|
const model = opts.model ?? process.env.CODEX_AGENT_MODEL;
|
|
24542
24716
|
let thread = null;
|
|
@@ -24559,21 +24733,12 @@ function createCodexSession(opts) {
|
|
|
24559
24733
|
async function ensureThread() {
|
|
24560
24734
|
if (thread) return thread;
|
|
24561
24735
|
const { Codex } = await loadCodex();
|
|
24562
|
-
const config2 =
|
|
24563
|
-
// Tools reach codex as MCP servers; each server's name shows up on
|
|
24564
|
-
// every tool event, so the runner can tell ours from codex's own.
|
|
24565
|
-
...opts.mcpServers && Object.keys(opts.mcpServers).length ? { mcp_servers: opts.mcpServers } : {},
|
|
24566
|
-
// Per run, not ~/.codex/config.toml: a host without that line would run
|
|
24567
|
-
// the agent with no instructions at all. AGENTS.md still wins if present.
|
|
24568
|
-
...opts.instructionsFile && opts.instructionsFile !== "AGENTS.md" ? { project_doc_fallback_filenames: [opts.instructionsFile] } : {},
|
|
24569
|
-
...opts.extraConfig ?? {}
|
|
24570
|
-
};
|
|
24736
|
+
const config2 = codexRunConfig(opts);
|
|
24571
24737
|
const codex = new Codex({
|
|
24572
24738
|
...opts.apiKey ? { apiKey: opts.apiKey } : {},
|
|
24573
24739
|
...opts.baseUrl ? { baseUrl: opts.baseUrl } : {},
|
|
24574
24740
|
env: buildEnv(opts),
|
|
24575
|
-
|
|
24576
|
-
...Object.keys(config2).length ? { config: config2 } : {}
|
|
24741
|
+
config: config2
|
|
24577
24742
|
});
|
|
24578
24743
|
thread = resumeId ? codex.resumeThread(resumeId, threadOptions()) : codex.startThread(threadOptions());
|
|
24579
24744
|
return thread;
|
|
@@ -30068,6 +30233,7 @@ export {
|
|
|
30068
30233
|
ANSWER_COMPONENT_NAMES,
|
|
30069
30234
|
BM25L,
|
|
30070
30235
|
CATEGORY_KEYS,
|
|
30236
|
+
CODEX_DOC_MAX_BYTES,
|
|
30071
30237
|
CONTEXT_CONFIG,
|
|
30072
30238
|
CleanupService,
|
|
30073
30239
|
DEFAULT_AGENT_CONFIG,
|
|
@@ -30096,6 +30262,8 @@ export {
|
|
|
30096
30262
|
bridgePreamble,
|
|
30097
30263
|
captureContext,
|
|
30098
30264
|
clearContextTokens,
|
|
30265
|
+
codexRunConfig,
|
|
30266
|
+
constraintPoliciesFromConfig,
|
|
30099
30267
|
contextTokenCount,
|
|
30100
30268
|
createCodexSession,
|
|
30101
30269
|
createCodingAgentSession,
|