@mcoda/codali 0.1.87 → 0.1.89

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.
Files changed (71) hide show
  1. package/dist/cli/EvalCommand.d.ts +8 -0
  2. package/dist/cli/EvalCommand.d.ts.map +1 -1
  3. package/dist/cli/EvalCommand.js +93 -1
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +1 -0
  6. package/dist/docdex/DocdexClient.d.ts +8 -1
  7. package/dist/docdex/DocdexClient.d.ts.map +1 -1
  8. package/dist/docdex/DocdexClient.js +126 -33
  9. package/dist/eval/CodaliGatewayLiveHarness.d.ts +169 -0
  10. package/dist/eval/CodaliGatewayLiveHarness.d.ts.map +1 -0
  11. package/dist/eval/CodaliGatewayLiveHarness.js +824 -0
  12. package/dist/eval/GatewayEvalSuite.d.ts +202 -0
  13. package/dist/eval/GatewayEvalSuite.d.ts.map +1 -0
  14. package/dist/eval/GatewayEvalSuite.js +673 -0
  15. package/dist/gateway/AgentTierResolver.d.ts +74 -0
  16. package/dist/gateway/AgentTierResolver.d.ts.map +1 -0
  17. package/dist/gateway/AgentTierResolver.js +576 -0
  18. package/dist/gateway/AppToolGatewayDispatcher.d.ts +88 -0
  19. package/dist/gateway/AppToolGatewayDispatcher.d.ts.map +1 -0
  20. package/dist/gateway/AppToolGatewayDispatcher.js +381 -0
  21. package/dist/gateway/CodaliGateway.d.ts +73 -0
  22. package/dist/gateway/CodaliGateway.d.ts.map +1 -0
  23. package/dist/gateway/CodaliGateway.js +824 -0
  24. package/dist/gateway/CodaliGatewaySchemas.d.ts +21 -0
  25. package/dist/gateway/CodaliGatewaySchemas.d.ts.map +1 -0
  26. package/dist/gateway/CodaliGatewaySchemas.js +874 -0
  27. package/dist/gateway/CodaliGatewayStore.d.ts +157 -0
  28. package/dist/gateway/CodaliGatewayStore.d.ts.map +1 -0
  29. package/dist/gateway/CodaliGatewayStore.js +206 -0
  30. package/dist/gateway/CodaliGatewayTypes.d.ts +336 -0
  31. package/dist/gateway/CodaliGatewayTypes.d.ts.map +1 -0
  32. package/dist/gateway/CodaliGatewayTypes.js +1 -0
  33. package/dist/gateway/ContextPackBuilder.d.ts +43 -0
  34. package/dist/gateway/ContextPackBuilder.d.ts.map +1 -0
  35. package/dist/gateway/ContextPackBuilder.js +317 -0
  36. package/dist/gateway/EvidenceNormalizer.d.ts +42 -0
  37. package/dist/gateway/EvidenceNormalizer.d.ts.map +1 -0
  38. package/dist/gateway/EvidenceNormalizer.js +488 -0
  39. package/dist/gateway/GatewayPlanner.d.ts +195 -0
  40. package/dist/gateway/GatewayPlanner.d.ts.map +1 -0
  41. package/dist/gateway/GatewayPlanner.js +379 -0
  42. package/dist/gateway/GatewayPolicyCompiler.d.ts +30 -0
  43. package/dist/gateway/GatewayPolicyCompiler.d.ts.map +1 -0
  44. package/dist/gateway/GatewayPolicyCompiler.js +114 -0
  45. package/dist/gateway/GatewaySecurityPolicy.d.ts +14 -0
  46. package/dist/gateway/GatewaySecurityPolicy.d.ts.map +1 -0
  47. package/dist/gateway/GatewaySecurityPolicy.js +350 -0
  48. package/dist/gateway/GatewayStateMachine.d.ts +165 -0
  49. package/dist/gateway/GatewayStateMachine.d.ts.map +1 -0
  50. package/dist/gateway/GatewayStateMachine.js +790 -0
  51. package/dist/gateway/GatewayTraceReplay.d.ts +120 -0
  52. package/dist/gateway/GatewayTraceReplay.d.ts.map +1 -0
  53. package/dist/gateway/GatewayTraceReplay.js +273 -0
  54. package/dist/gateway/ToolCapabilityCompiler.d.ts +50 -0
  55. package/dist/gateway/ToolCapabilityCompiler.d.ts.map +1 -0
  56. package/dist/gateway/ToolCapabilityCompiler.js +442 -0
  57. package/dist/index.d.ts +33 -1
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +16 -0
  60. package/dist/runtime/CodaliJobRuntime.d.ts +211 -0
  61. package/dist/runtime/CodaliJobRuntime.d.ts.map +1 -0
  62. package/dist/runtime/CodaliJobRuntime.js +590 -0
  63. package/dist/runtime/CodaliRuntime.d.ts +81 -1
  64. package/dist/runtime/CodaliRuntime.d.ts.map +1 -1
  65. package/dist/runtime/CodaliRuntime.js +619 -4
  66. package/dist/tools/ToolRegistry.d.ts.map +1 -1
  67. package/dist/tools/ToolRegistry.js +4 -0
  68. package/dist/tools/ToolTypes.d.ts +1 -1
  69. package/dist/tools/ToolTypes.d.ts.map +1 -1
  70. package/dist/tools/ToolTypes.js +5 -1
  71. package/package.json +3 -3
@@ -0,0 +1,379 @@
1
+ import { validateCodaliGatewayPlannerOutput, } from "./CodaliGatewaySchemas.js";
2
+ import { compileCodaliGatewayPolicy, } from "./GatewayPolicyCompiler.js";
3
+ import { CODALI_GATEWAY_SECURITY_PROMPT_HARDENING } from "./GatewaySecurityPolicy.js";
4
+ export class CodaliGatewayPlannerError extends Error {
5
+ constructor(code, message, issues) {
6
+ super(`${code}: ${message}`);
7
+ this.name = "CodaliGatewayPlannerError";
8
+ this.code = code;
9
+ this.issues = issues;
10
+ }
11
+ }
12
+ export const CODALI_GATEWAY_CLASSIFIER_SCHEMA = {
13
+ type: "object",
14
+ additionalProperties: false,
15
+ required: [
16
+ "queryType",
17
+ "needsPrivateData",
18
+ "needsFreshData",
19
+ "needsDocdex",
20
+ "needsAppTools",
21
+ "needsImageWorker",
22
+ ],
23
+ properties: {
24
+ queryType: { type: "string", minLength: 1 },
25
+ needsPrivateData: { type: "boolean" },
26
+ needsFreshData: { type: "boolean" },
27
+ needsDocdex: { type: "boolean" },
28
+ needsAppTools: { type: "boolean" },
29
+ needsImageWorker: { type: "boolean" },
30
+ directAnswerCandidate: { type: "string" },
31
+ rationale: { type: "string" },
32
+ confidence: { enum: ["high", "medium", "low"] },
33
+ metadata: { type: "object" },
34
+ },
35
+ };
36
+ export const CODALI_GATEWAY_PLANNER_SCHEMA = {
37
+ type: "object",
38
+ additionalProperties: true,
39
+ required: ["queryType", "subquestions", "workerTasks"],
40
+ properties: {
41
+ runId: { type: "string" },
42
+ queryType: { type: "string", minLength: 1 },
43
+ summary: { type: "string" },
44
+ subquestions: {
45
+ type: "array",
46
+ items: {
47
+ type: "object",
48
+ additionalProperties: true,
49
+ required: ["id", "question"],
50
+ properties: {
51
+ id: { type: "string", minLength: 1 },
52
+ question: { type: "string", minLength: 1 },
53
+ rationale: { type: "string" },
54
+ priority: { type: "number" },
55
+ },
56
+ },
57
+ },
58
+ workerTasks: {
59
+ type: "array",
60
+ items: {
61
+ type: "object",
62
+ additionalProperties: true,
63
+ required: ["id", "workerRole", "objective", "toolsAllowed", "outputFormat"],
64
+ properties: {
65
+ id: { type: "string", minLength: 1 },
66
+ workerRole: { type: "string", minLength: 1 },
67
+ objective: { type: "string", minLength: 1 },
68
+ query: { type: "string" },
69
+ toolsAllowed: { type: "array", items: { type: "string" } },
70
+ outputFormat: { type: "string", minLength: 1 },
71
+ expectedSources: { type: "array", items: { type: "string" } },
72
+ constraints: { type: "array", items: { type: "string" } },
73
+ priority: { type: "number" },
74
+ metadata: { type: "object" },
75
+ },
76
+ },
77
+ },
78
+ expectedEvidenceCount: { type: "number" },
79
+ maxIterations: { type: "number" },
80
+ requiresFinalLargeModel: { type: "boolean" },
81
+ metadata: { type: "object" },
82
+ },
83
+ };
84
+ const CLASSIFIER_RESPONSE_FORMAT = {
85
+ type: "json_schema",
86
+ schema: CODALI_GATEWAY_CLASSIFIER_SCHEMA,
87
+ };
88
+ const PLANNER_RESPONSE_FORMAT = {
89
+ type: "json_schema",
90
+ schema: CODALI_GATEWAY_PLANNER_SCHEMA,
91
+ };
92
+ const isRecord = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
93
+ const readString = (record, key) => typeof record[key] === "string" && record[key].trim()
94
+ ? record[key].trim()
95
+ : undefined;
96
+ const readBoolean = (record, key) => typeof record[key] === "boolean" ? record[key] : undefined;
97
+ const parseJsonObject = (content) => {
98
+ const trimmed = content.trim();
99
+ const fenced = trimmed.match(/^```(?:json)?\s*([\s\S]*?)\s*```$/i)?.[1]?.trim();
100
+ const candidate = fenced ?? trimmed;
101
+ try {
102
+ return JSON.parse(candidate);
103
+ }
104
+ catch {
105
+ const start = candidate.indexOf("{");
106
+ const end = candidate.lastIndexOf("}");
107
+ if (start >= 0 && end > start) {
108
+ return JSON.parse(candidate.slice(start, end + 1));
109
+ }
110
+ throw new CodaliGatewayPlannerError("GATEWAY_JSON_PARSE_FAILED", "Planner stage returned non-JSON content.");
111
+ }
112
+ };
113
+ const validateClassifierOutput = (value) => {
114
+ const issues = [];
115
+ if (!isRecord(value)) {
116
+ return {
117
+ issues: [
118
+ {
119
+ path: "$",
120
+ code: "expected_object",
121
+ message: "Classifier output must be an object.",
122
+ },
123
+ ],
124
+ };
125
+ }
126
+ const queryType = readString(value, "queryType") ?? readString(value, "query_type");
127
+ if (!queryType) {
128
+ issues.push({
129
+ path: "$.queryType",
130
+ code: "expected_non_empty_string",
131
+ message: "queryType is required.",
132
+ });
133
+ }
134
+ const requiredBooleans = [
135
+ "needsPrivateData",
136
+ "needsFreshData",
137
+ "needsDocdex",
138
+ "needsAppTools",
139
+ "needsImageWorker",
140
+ ];
141
+ const booleans = {};
142
+ for (const key of requiredBooleans) {
143
+ const snakeKey = key.replace(/[A-Z]/g, (char) => `_${char.toLowerCase()}`);
144
+ const valueForKey = readBoolean(value, key) ?? readBoolean(value, snakeKey);
145
+ if (valueForKey === undefined) {
146
+ issues.push({
147
+ path: `$.${key}`,
148
+ code: "expected_boolean",
149
+ message: `${key} is required and must be a boolean.`,
150
+ });
151
+ }
152
+ else {
153
+ booleans[key] = valueForKey;
154
+ }
155
+ }
156
+ const confidence = readString(value, "confidence");
157
+ if (confidence !== undefined &&
158
+ confidence !== "high" &&
159
+ confidence !== "medium" &&
160
+ confidence !== "low") {
161
+ issues.push({
162
+ path: "$.confidence",
163
+ code: "expected_enum",
164
+ message: "confidence must be high, medium, or low.",
165
+ });
166
+ }
167
+ if (issues.length > 0 || !queryType) {
168
+ return { issues };
169
+ }
170
+ return {
171
+ issues,
172
+ output: {
173
+ queryType,
174
+ needsPrivateData: booleans.needsPrivateData ?? false,
175
+ needsFreshData: booleans.needsFreshData ?? false,
176
+ needsDocdex: booleans.needsDocdex ?? false,
177
+ needsAppTools: booleans.needsAppTools ?? false,
178
+ needsImageWorker: booleans.needsImageWorker ?? false,
179
+ directAnswerCandidate: readString(value, "directAnswerCandidate") ??
180
+ readString(value, "direct_answer_candidate"),
181
+ rationale: readString(value, "rationale"),
182
+ confidence,
183
+ metadata: isRecord(value.metadata) ? value.metadata : undefined,
184
+ },
185
+ };
186
+ };
187
+ const describeTool = (name, descriptors) => {
188
+ const descriptor = descriptors?.[name];
189
+ if (!descriptor) {
190
+ return `${name}: read-only allowed tool`;
191
+ }
192
+ if (typeof descriptor === "string") {
193
+ return `${name}: ${descriptor}`;
194
+ }
195
+ return `${name}: ${descriptor.description ?? "read-only allowed tool"}`;
196
+ };
197
+ const allowedToolNames = (compilation) => [...compilation.effectiveAllowedTools].sort();
198
+ export const buildCodaliGatewayClassifierMessages = (input) => {
199
+ const policy = input.policyCompilation ?? compileCodaliGatewayPolicy({ request: input.request });
200
+ const tools = allowedToolNames(policy);
201
+ const system = [
202
+ "You are Codali gateway classifier.",
203
+ "Return JSON only. Do not answer the user.",
204
+ "Classify the request into routing facts for a product-neutral orchestration gateway.",
205
+ "Small models only produce structured artifacts; final user-visible prose is handled later.",
206
+ CODALI_GATEWAY_SECURITY_PROMPT_HARDENING.policyImmutability,
207
+ CODALI_GATEWAY_SECURITY_PROMPT_HARDENING.tenantScope,
208
+ ].join("\n");
209
+ const user = [
210
+ `Query: ${input.request.query}`,
211
+ `Mode: ${input.request.mode ?? "balanced"}`,
212
+ `Product: ${input.request.product?.name ?? "generic"}`,
213
+ `Tenant scoped: ${input.request.tenant?.id || input.request.tenant?.slug ? "yes" : "unknown"}`,
214
+ `Image worker allowed: ${input.request.policy.allowImageWorker === true ? "yes" : "no"}`,
215
+ `Available tools: ${tools.length > 0 ? tools.join(", ") : "none"}`,
216
+ "Decide these booleans: needsPrivateData, needsFreshData, needsDocdex, needsAppTools, needsImageWorker.",
217
+ "If a direct answer is possible without private/runtime tools, include directAnswerCandidate.",
218
+ ].join("\n");
219
+ return [
220
+ { role: "system", content: system },
221
+ { role: "user", content: user },
222
+ ];
223
+ };
224
+ export const buildCodaliGatewayPlannerMessages = (input, classifier) => {
225
+ const policy = input.policyCompilation ?? compileCodaliGatewayPolicy({ request: input.request });
226
+ const tools = allowedToolNames(policy);
227
+ const toolLines = tools.length > 0
228
+ ? tools.map((tool) => `- ${describeTool(tool, input.toolDescriptions)}`).join("\n")
229
+ : "- none";
230
+ const workerRoles = [
231
+ "direct_answer",
232
+ "rag_worker",
233
+ "tool_worker",
234
+ "extractor",
235
+ "verifier",
236
+ input.request.policy.allowImageWorker === true ? "image_worker" : undefined,
237
+ ].filter(Boolean).join(", ");
238
+ const system = [
239
+ "You are Codali gateway planner.",
240
+ "Return JSON only. Do not answer the user.",
241
+ "Create bounded worker tasks that gather evidence or produce structured artifacts.",
242
+ "Only use tool names listed in the allowed tool section.",
243
+ "Do not include denied, disabled, write, shell, destructive, or outside-workspace tools.",
244
+ CODALI_GATEWAY_SECURITY_PROMPT_HARDENING.toolOutputBoundary,
245
+ CODALI_GATEWAY_SECURITY_PROMPT_HARDENING.policyImmutability,
246
+ CODALI_GATEWAY_SECURITY_PROMPT_HARDENING.tenantScope,
247
+ ].join("\n");
248
+ const user = [
249
+ `Query: ${input.request.query}`,
250
+ `Classifier: ${JSON.stringify(classifier)}`,
251
+ `Policy limits: maxIterations=${input.request.policy.maxIterations}, maxToolCalls=${policy.security.limits.maxToolCalls}, maxModelCalls=${policy.security.limits.maxModelCalls}, maxEvidenceItems=${policy.security.limits.maxEvidenceItems}, maxImageArtifacts=${policy.security.limits.maxImageArtifacts}`,
252
+ `Worker roles available: ${workerRoles}`,
253
+ "Allowed tools:",
254
+ toolLines,
255
+ "Output planner JSON with queryType, subquestions, workerTasks, expectedEvidenceCount, maxIterations, requiresFinalLargeModel, and metadata.",
256
+ ].join("\n");
257
+ return [
258
+ { role: "system", content: system },
259
+ { role: "user", content: user },
260
+ ];
261
+ };
262
+ const buildRepairMessages = (stage, originalMessages, rawContent, error) => [
263
+ ...originalMessages,
264
+ { role: "assistant", content: rawContent },
265
+ {
266
+ role: "user",
267
+ content: [
268
+ `Repair the ${stage} JSON output.`,
269
+ "Return JSON only and match the required schema exactly.",
270
+ `Validation error: ${error instanceof Error ? error.message : String(error)}`,
271
+ ].join("\n"),
272
+ },
273
+ ];
274
+ const sanitizePlannerOutput = (planner, input) => {
275
+ const policy = input.policyCompilation ?? compileCodaliGatewayPolicy({ request: input.request });
276
+ const allowed = new Set(allowedToolNames(policy));
277
+ const warnings = [];
278
+ const workerTasks = [];
279
+ for (const task of planner.workerTasks) {
280
+ if (task.workerRole === "image_worker" && input.request.policy.allowImageWorker !== true) {
281
+ warnings.push(`planner_task_removed_image_worker_disabled:${task.id}`);
282
+ continue;
283
+ }
284
+ const filteredTools = task.toolsAllowed.filter((tool) => allowed.has(tool));
285
+ const removed = task.toolsAllowed.filter((tool) => !allowed.has(tool));
286
+ if (removed.length > 0) {
287
+ warnings.push(`planner_task_tools_removed:${task.id}:${removed.join(",")}`);
288
+ }
289
+ workerTasks.push({ ...task, toolsAllowed: filteredTools });
290
+ }
291
+ return {
292
+ warnings,
293
+ planner: {
294
+ ...planner,
295
+ maxIterations: planner.maxIterations === undefined
296
+ ? undefined
297
+ : Math.min(planner.maxIterations, input.request.policy.maxIterations),
298
+ workerTasks,
299
+ },
300
+ };
301
+ };
302
+ export class CodaliGatewayPlanner {
303
+ constructor(provider, options = {}) {
304
+ this.provider = provider;
305
+ this.options = options;
306
+ this.maxRepairAttempts = options.maxRepairAttempts ?? 1;
307
+ }
308
+ async classify(input) {
309
+ const messages = buildCodaliGatewayClassifierMessages(input);
310
+ const response = await this.generateValidated("classifier", messages, CLASSIFIER_RESPONSE_FORMAT, validateClassifierOutput);
311
+ const warnings = [];
312
+ const classifier = { ...response.value };
313
+ if (classifier.needsImageWorker && input.request.policy.allowImageWorker !== true) {
314
+ classifier.needsImageWorker = false;
315
+ warnings.push("classifier_image_worker_disabled");
316
+ }
317
+ return { ...response, classifier, warnings };
318
+ }
319
+ async plan(input) {
320
+ const policyCompilation = input.policyCompilation ?? compileCodaliGatewayPolicy({ request: input.request });
321
+ if (!policyCompilation.ok) {
322
+ throw new CodaliGatewayPlannerError("GATEWAY_POLICY_COMPILE_FAILED", "Cannot plan with invalid gateway policy.");
323
+ }
324
+ const classifierResult = await this.classify({ ...input, policyCompilation });
325
+ const plannerMessages = buildCodaliGatewayPlannerMessages({ ...input, policyCompilation }, classifierResult.classifier);
326
+ const plannerResult = await this.generateValidated("planner", plannerMessages, PLANNER_RESPONSE_FORMAT, (value) => {
327
+ const validation = validateCodaliGatewayPlannerOutput(value);
328
+ return validation.ok
329
+ ? { output: validation.value, issues: [] }
330
+ : { issues: validation.issues };
331
+ });
332
+ const sanitized = sanitizePlannerOutput(plannerResult.value, { ...input, policyCompilation });
333
+ return {
334
+ policyCompilation,
335
+ classifier: classifierResult.classifier,
336
+ planner: sanitized.planner,
337
+ warnings: [...classifierResult.warnings, ...sanitized.warnings],
338
+ classifierRepairAttempts: classifierResult.repairAttempts,
339
+ plannerRepairAttempts: plannerResult.repairAttempts,
340
+ classifierRawContent: classifierResult.rawContent,
341
+ plannerRawContent: plannerResult.rawContent,
342
+ };
343
+ }
344
+ async generateValidated(stage, messages, responseFormat, validator) {
345
+ let currentMessages = messages;
346
+ let repairAttempts = 0;
347
+ let lastError;
348
+ let lastRaw = "";
349
+ for (;;) {
350
+ const response = await this.provider.generate({
351
+ messages: currentMessages,
352
+ maxTokens: this.options.maxTokens,
353
+ temperature: this.options.temperature ?? 0,
354
+ responseFormat,
355
+ });
356
+ lastRaw = response.message.content;
357
+ try {
358
+ const parsed = parseJsonObject(lastRaw);
359
+ const validated = validator(parsed);
360
+ if (validated.output) {
361
+ return { value: validated.output, repairAttempts, rawContent: lastRaw };
362
+ }
363
+ throw new CodaliGatewayPlannerError("GATEWAY_STAGE_SCHEMA_INVALID", `${stage} output failed schema validation.`, validated.issues);
364
+ }
365
+ catch (error) {
366
+ lastError = error;
367
+ if (repairAttempts >= this.maxRepairAttempts) {
368
+ if (error instanceof CodaliGatewayPlannerError) {
369
+ throw error;
370
+ }
371
+ throw new CodaliGatewayPlannerError("GATEWAY_STAGE_SCHEMA_INVALID", `${stage} output could not be parsed or validated.`);
372
+ }
373
+ repairAttempts += 1;
374
+ currentMessages = buildRepairMessages(stage, messages, lastRaw, lastError);
375
+ }
376
+ }
377
+ }
378
+ }
379
+ export const createCodaliGatewayPlanner = (provider, options) => new CodaliGatewayPlanner(provider, options);
@@ -0,0 +1,30 @@
1
+ import type { CodaliRuntimeDocdexInput, CodaliRuntimePolicy, CodaliRuntimeToolManifest } from "../runtime/CodaliRuntime.js";
2
+ import type { CodaliJobBudgets } from "../runtime/CodaliJobRuntime.js";
3
+ import type { CodaliGatewayMode, CodaliGatewayPolicy, CodaliGatewayRequest, CodaliGatewaySecurityReview } from "./CodaliGatewayTypes.js";
4
+ import { type CodaliGatewayCompiledToolCapability, type CodaliGatewayCompilerIssue, type CodaliGatewaySkippedTool, type ToolCapabilityCompilation } from "./ToolCapabilityCompiler.js";
5
+ export interface GatewayPolicyCompilerInput {
6
+ request?: Pick<CodaliGatewayRequest, "policy" | "docdex" | "tools" | "mode" | "tenant" | "metadata">;
7
+ policy?: CodaliGatewayPolicy;
8
+ docdex?: CodaliRuntimeDocdexInput;
9
+ tools?: CodaliRuntimeToolManifest;
10
+ mode?: CodaliGatewayMode;
11
+ runtimeMode?: CodaliRuntimePolicy["mode"];
12
+ requiredDocdexOperations?: string[];
13
+ maxParallelStages?: number;
14
+ }
15
+ export interface GatewayPolicyCompilation {
16
+ ok: boolean;
17
+ runtimePolicy: CodaliRuntimePolicy;
18
+ jobBudgets: CodaliJobBudgets;
19
+ effectiveAllowedTools: string[];
20
+ effectiveDeniedTools: string[];
21
+ skippedTools: CodaliGatewaySkippedTool[];
22
+ toolCapabilities: CodaliGatewayCompiledToolCapability[];
23
+ toolCompilation: ToolCapabilityCompilation;
24
+ security: CodaliGatewaySecurityReview;
25
+ warnings: CodaliGatewayCompilerIssue[];
26
+ errors: CodaliGatewayCompilerIssue[];
27
+ }
28
+ export declare const compileCodaliGatewayPolicy: (input: GatewayPolicyCompilerInput) => GatewayPolicyCompilation;
29
+ export declare const compileGatewayPolicy: (input: GatewayPolicyCompilerInput) => GatewayPolicyCompilation;
30
+ //# sourceMappingURL=GatewayPolicyCompiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GatewayPolicyCompiler.d.ts","sourceRoot":"","sources":["../../src/gateway/GatewayPolicyCompiler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,mBAAmB,EACnB,yBAAyB,EAC1B,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,2BAA2B,EAC5B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAEL,KAAK,mCAAmC,EACxC,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC/B,MAAM,6BAA6B,CAAC;AAErC,MAAM,WAAW,0BAA0B;IACzC,OAAO,CAAC,EAAE,IAAI,CACZ,oBAAoB,EACpB,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAC/D,CAAC;IACF,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAClC,KAAK,CAAC,EAAE,yBAAyB,CAAC;IAClC,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,WAAW,CAAC,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC1C,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,OAAO,CAAC;IACZ,aAAa,EAAE,mBAAmB,CAAC;IACnC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,YAAY,EAAE,wBAAwB,EAAE,CAAC;IACzC,gBAAgB,EAAE,mCAAmC,EAAE,CAAC;IACxD,eAAe,EAAE,yBAAyB,CAAC;IAC3C,QAAQ,EAAE,2BAA2B,CAAC;IACtC,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,MAAM,EAAE,0BAA0B,EAAE,CAAC;CACtC;AAyDD,eAAO,MAAM,0BAA0B,GACrC,OAAO,0BAA0B,KAChC,wBA+FF,CAAC;AAEF,eAAO,MAAM,oBAAoB,UAlGxB,0BAA0B,KAChC,wBAiG2D,CAAC"}
@@ -0,0 +1,114 @@
1
+ import { resolveCodaliGatewaySecurityPolicy } from "./GatewaySecurityPolicy.js";
2
+ import { compileToolCapabilities, } from "./ToolCapabilityCompiler.js";
3
+ const isUnsafePolicyEnabled = (policy) => {
4
+ const unsafe = [];
5
+ if (policy.allowWrites !== false)
6
+ unsafe.push("allowWrites");
7
+ if (policy.allowShell !== false)
8
+ unsafe.push("allowShell");
9
+ if (policy.allowDestructiveOperations !== false) {
10
+ unsafe.push("allowDestructiveOperations");
11
+ }
12
+ if (policy.allowOutsideWorkspace !== false)
13
+ unsafe.push("allowOutsideWorkspace");
14
+ return unsafe;
15
+ };
16
+ const issue = (code, message, details) => ({
17
+ code,
18
+ message,
19
+ severity: "error",
20
+ details,
21
+ });
22
+ const modeToRuntimeMode = (mode) => {
23
+ switch (mode) {
24
+ case "cheap":
25
+ case "fast":
26
+ return "tool_loop";
27
+ case "deep":
28
+ case "image":
29
+ return "smart_pipeline";
30
+ case "balanced":
31
+ default:
32
+ return "tool_loop";
33
+ }
34
+ };
35
+ const positiveOrDefault = (value, fallback) => Number.isFinite(value) && value > 0 ? Math.floor(value) : fallback;
36
+ export const compileCodaliGatewayPolicy = (input) => {
37
+ const policy = input.policy ?? input.request?.policy;
38
+ if (!policy) {
39
+ throw new Error("GATEWAY_POLICY_REQUIRED: Gateway policy is required.");
40
+ }
41
+ const docdex = input.docdex ?? input.request?.docdex;
42
+ const tools = input.tools ?? input.request?.tools ?? docdex?.toolManifest;
43
+ const mode = input.mode ?? input.request?.mode;
44
+ const toolCompilation = compileToolCapabilities({
45
+ policy,
46
+ docdex,
47
+ tools,
48
+ requiredDocdexOperations: input.requiredDocdexOperations,
49
+ });
50
+ const errors = [...toolCompilation.errors];
51
+ const warnings = [...toolCompilation.warnings];
52
+ const unsafeFlags = isUnsafePolicyEnabled(policy);
53
+ if (unsafeFlags.length > 0) {
54
+ errors.push(issue("GATEWAY_READ_ONLY_POLICY_REQUIRED", "Codali gateway policies must disable shell, writes, destructive operations, and outside-workspace access.", { flags: unsafeFlags }));
55
+ }
56
+ if (policy.maxToolCalls < 0) {
57
+ errors.push(issue("GATEWAY_INVALID_MAX_TOOL_CALLS", "maxToolCalls must be zero or greater."));
58
+ }
59
+ const effectiveAllowedTools = toolCompilation.visibleTools;
60
+ const effectiveDeniedTools = toolCompilation.deniedTools;
61
+ const security = resolveCodaliGatewaySecurityPolicy({
62
+ request: input.request ? { ...input.request, policy } : {
63
+ policy,
64
+ tenant: undefined,
65
+ metadata: undefined,
66
+ },
67
+ effectiveAllowedTools,
68
+ effectiveDeniedTools,
69
+ toolCapabilities: toolCompilation.capabilities,
70
+ });
71
+ warnings.push(...security.warnings);
72
+ errors.push(...security.errors);
73
+ const runtimePolicy = {
74
+ allowWrites: false,
75
+ allowShell: false,
76
+ allowDestructiveOperations: false,
77
+ allowOutsideWorkspace: false,
78
+ allowedTools: effectiveAllowedTools,
79
+ deniedTools: effectiveDeniedTools,
80
+ appToolContracts: Object.keys(toolCompilation.appToolContracts).length > 0
81
+ ? toolCompilation.appToolContracts
82
+ : undefined,
83
+ appVirtualTools: toolCompilation.appVirtualTools.length > 0
84
+ ? toolCompilation.appVirtualTools
85
+ : undefined,
86
+ appToolGateway: toolCompilation.appToolGateway,
87
+ maxSteps: positiveOrDefault(policy.maxIterations, 1),
88
+ maxToolCalls: security.limits.maxToolCalls,
89
+ maxTokens: positiveOrDefault(policy.maxContextPackTokens, 1),
90
+ timeoutMs: security.limits.maxRuntimeMs,
91
+ mode: input.runtimeMode ?? modeToRuntimeMode(mode),
92
+ };
93
+ const jobBudgets = {
94
+ maxRuntimeMs: runtimePolicy.timeoutMs,
95
+ maxToolCalls: runtimePolicy.maxToolCalls,
96
+ maxFollowups: runtimePolicy.maxSteps,
97
+ maxParallelStages: input.maxParallelStages ??
98
+ Math.max(1, Math.min(security.limits.maxModelCalls, 8)),
99
+ };
100
+ return {
101
+ ok: errors.length === 0,
102
+ runtimePolicy,
103
+ jobBudgets,
104
+ effectiveAllowedTools,
105
+ effectiveDeniedTools,
106
+ skippedTools: toolCompilation.skippedTools,
107
+ toolCapabilities: toolCompilation.capabilities,
108
+ toolCompilation,
109
+ security,
110
+ warnings,
111
+ errors,
112
+ };
113
+ };
114
+ export const compileGatewayPolicy = compileCodaliGatewayPolicy;
@@ -0,0 +1,14 @@
1
+ import type { CodaliGatewayApprovalRecord, CodaliGatewayPromptHardening, CodaliGatewayRequest, CodaliGatewaySecurityReview, CodaliGatewayTenantLimitProfile, CodaliGatewayToolRiskCategory } from "./CodaliGatewayTypes.js";
2
+ import type { CodaliGatewayCompiledToolCapability } from "./ToolCapabilityCompiler.js";
3
+ export declare const CODALI_GATEWAY_SECURITY_PROMPT_HARDENING: CodaliGatewayPromptHardening;
4
+ export interface ResolveCodaliGatewaySecurityPolicyInput {
5
+ request: Pick<CodaliGatewayRequest, "policy" | "tenant" | "metadata">;
6
+ effectiveAllowedTools?: string[];
7
+ effectiveDeniedTools?: string[];
8
+ toolCapabilities?: CodaliGatewayCompiledToolCapability[];
9
+ tenantLimits?: CodaliGatewayTenantLimitProfile;
10
+ approvals?: CodaliGatewayApprovalRecord[];
11
+ }
12
+ export declare const classifyCodaliGatewayToolRisk: (tool: string, capability?: Pick<CodaliGatewayCompiledToolCapability, "readOnly" | "riskCategory">) => CodaliGatewayToolRiskCategory;
13
+ export declare const resolveCodaliGatewaySecurityPolicy: (input: ResolveCodaliGatewaySecurityPolicyInput) => CodaliGatewaySecurityReview;
14
+ //# sourceMappingURL=GatewaySecurityPolicy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GatewaySecurityPolicy.d.ts","sourceRoot":"","sources":["../../src/gateway/GatewaySecurityPolicy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,2BAA2B,EAI3B,4BAA4B,EAC5B,oBAAoB,EAEpB,2BAA2B,EAC3B,+BAA+B,EAE/B,6BAA6B,EAC9B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,6BAA6B,CAAC;AAEvF,eAAO,MAAM,wCAAwC,EAAE,4BAStD,CAAC;AAiDF,MAAM,WAAW,uCAAuC;IACtD,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC,CAAC;IACtE,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,gBAAgB,CAAC,EAAE,mCAAmC,EAAE,CAAC;IACzD,YAAY,CAAC,EAAE,+BAA+B,CAAC;IAC/C,SAAS,CAAC,EAAE,2BAA2B,EAAE,CAAC;CAC3C;AAiMD,eAAO,MAAM,6BAA6B,GACxC,MAAM,MAAM,EACZ,aAAa,IAAI,CAAC,mCAAmC,EAAE,UAAU,GAAG,cAAc,CAAC,KAClF,6BAWF,CAAC;AA2GF,eAAO,MAAM,kCAAkC,GAC7C,OAAO,uCAAuC,KAC7C,2BAmEF,CAAC"}