cognitive-modules-cli 2.2.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +65 -12
- package/dist/commands/compose.d.ts +31 -0
- package/dist/commands/compose.js +148 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.js +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -1
- package/dist/modules/composition.d.ts +251 -0
- package/dist/modules/composition.js +1265 -0
- package/dist/modules/composition.test.d.ts +11 -0
- package/dist/modules/composition.test.js +450 -0
- package/dist/modules/index.d.ts +2 -0
- package/dist/modules/index.js +2 -0
- package/dist/modules/loader.d.ts +22 -2
- package/dist/modules/loader.js +167 -4
- package/dist/modules/policy.test.d.ts +10 -0
- package/dist/modules/policy.test.js +369 -0
- package/dist/modules/runner.d.ts +357 -1
- package/dist/modules/runner.js +1221 -64
- package/dist/modules/subagent.js +2 -0
- package/dist/modules/validator.d.ts +28 -0
- package/dist/modules/validator.js +629 -0
- package/dist/types.d.ts +92 -8
- package/package.json +2 -1
- package/src/cli.ts +73 -12
- package/src/commands/compose.ts +185 -0
- package/src/commands/index.ts +1 -0
- package/src/index.ts +35 -0
- package/src/modules/composition.test.ts +558 -0
- package/src/modules/composition.ts +1674 -0
- package/src/modules/index.ts +2 -0
- package/src/modules/loader.ts +196 -6
- package/src/modules/policy.test.ts +455 -0
- package/src/modules/runner.ts +1562 -74
- package/src/modules/subagent.ts +2 -0
- package/src/modules/validator.ts +700 -0
- package/src/types.ts +112 -8
- package/tsconfig.json +1 -1
package/dist/modules/runner.d.ts
CHANGED
|
@@ -1,14 +1,370 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Module Runner - Execute Cognitive Modules
|
|
3
3
|
* v2.2: Envelope format with meta/data separation, risk_rule, repair pass
|
|
4
|
+
* v2.2.1: Version field, enhanced error taxonomy, observability hooks, streaming
|
|
4
5
|
*/
|
|
5
|
-
import type { Provider, CognitiveModule, ModuleResult, ModuleInput } from '../types.js';
|
|
6
|
+
import type { Provider, CognitiveModule, ModuleResult, ModuleInput, EnvelopeResponseV22, EnvelopeMeta, RiskLevel } from '../types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Validate data against JSON schema. Returns list of errors.
|
|
9
|
+
*/
|
|
10
|
+
export declare function validateData(data: unknown, schema: object, label?: string): string[];
|
|
11
|
+
/** Action types that can be checked against policies */
|
|
12
|
+
export type PolicyAction = 'network' | 'filesystem_write' | 'side_effects' | 'code_execution';
|
|
13
|
+
/** Result of a policy check */
|
|
14
|
+
export interface PolicyCheckResult {
|
|
15
|
+
allowed: boolean;
|
|
16
|
+
reason?: string;
|
|
17
|
+
policy?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Check if a tool is allowed by the module's tools policy.
|
|
21
|
+
*
|
|
22
|
+
* @param toolName The name of the tool to check
|
|
23
|
+
* @param module The cognitive module config
|
|
24
|
+
* @returns PolicyCheckResult indicating if the tool is allowed
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* const result = checkToolPolicy('write_file', module);
|
|
28
|
+
* if (!result.allowed) {
|
|
29
|
+
* throw new Error(result.reason);
|
|
30
|
+
* }
|
|
31
|
+
*/
|
|
32
|
+
export declare function checkToolPolicy(toolName: string, module: CognitiveModule): PolicyCheckResult;
|
|
33
|
+
/**
|
|
34
|
+
* Check if an action is allowed by the module's policies.
|
|
35
|
+
*
|
|
36
|
+
* @param action The action to check (network, filesystem_write, etc.)
|
|
37
|
+
* @param module The cognitive module config
|
|
38
|
+
* @returns PolicyCheckResult indicating if the action is allowed
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* const result = checkPolicy('network', module);
|
|
42
|
+
* if (!result.allowed) {
|
|
43
|
+
* throw new Error(result.reason);
|
|
44
|
+
* }
|
|
45
|
+
*/
|
|
46
|
+
export declare function checkPolicy(action: PolicyAction, module: CognitiveModule): PolicyCheckResult;
|
|
47
|
+
/**
|
|
48
|
+
* Check if a tool is allowed considering both tools policy and general policies.
|
|
49
|
+
* This performs a comprehensive check that:
|
|
50
|
+
* 1. Checks the tools policy (allowed/denied lists)
|
|
51
|
+
* 2. Maps the tool to policy actions and checks those
|
|
52
|
+
*
|
|
53
|
+
* @param toolName The name of the tool to check
|
|
54
|
+
* @param module The cognitive module config
|
|
55
|
+
* @returns PolicyCheckResult with detailed information
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* const result = checkToolAllowed('write_file', module);
|
|
59
|
+
* if (!result.allowed) {
|
|
60
|
+
* return makeErrorResponse({
|
|
61
|
+
* code: 'POLICY_VIOLATION',
|
|
62
|
+
* message: result.reason,
|
|
63
|
+
* });
|
|
64
|
+
* }
|
|
65
|
+
*/
|
|
66
|
+
export declare function checkToolAllowed(toolName: string, module: CognitiveModule): PolicyCheckResult;
|
|
67
|
+
/**
|
|
68
|
+
* Validate that a list of tools are all allowed by the module's policies.
|
|
69
|
+
* Returns all violations found.
|
|
70
|
+
*
|
|
71
|
+
* @param toolNames List of tool names to check
|
|
72
|
+
* @param module The cognitive module config
|
|
73
|
+
* @returns Array of PolicyCheckResult for denied tools
|
|
74
|
+
*/
|
|
75
|
+
export declare function validateToolsAllowed(toolNames: string[], module: CognitiveModule): PolicyCheckResult[];
|
|
76
|
+
/**
|
|
77
|
+
* Get all denied actions for a module based on its policies.
|
|
78
|
+
* Useful for informing LLM about restrictions.
|
|
79
|
+
*/
|
|
80
|
+
export declare function getDeniedActions(module: CognitiveModule): PolicyAction[];
|
|
81
|
+
/**
|
|
82
|
+
* Get all denied tools for a module based on its tools policy.
|
|
83
|
+
*/
|
|
84
|
+
export declare function getDeniedTools(module: CognitiveModule): string[];
|
|
85
|
+
/**
|
|
86
|
+
* Get all allowed tools for a module (only meaningful in deny_by_default mode).
|
|
87
|
+
*/
|
|
88
|
+
export declare function getAllowedTools(module: CognitiveModule): string[] | null;
|
|
89
|
+
/** Tool call request from LLM */
|
|
90
|
+
export interface ToolCallRequest {
|
|
91
|
+
name: string;
|
|
92
|
+
arguments: Record<string, unknown>;
|
|
93
|
+
}
|
|
94
|
+
/** Tool call result */
|
|
95
|
+
export interface ToolCallResult {
|
|
96
|
+
success: boolean;
|
|
97
|
+
result?: unknown;
|
|
98
|
+
error?: {
|
|
99
|
+
code: string;
|
|
100
|
+
message: string;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/** Tool executor function type */
|
|
104
|
+
export type ToolExecutor = (args: Record<string, unknown>) => Promise<unknown>;
|
|
105
|
+
/**
|
|
106
|
+
* ToolCallInterceptor - Intercepts and validates tool calls against module policies.
|
|
107
|
+
*
|
|
108
|
+
* Use this class to wrap tool execution with policy enforcement:
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* const interceptor = new ToolCallInterceptor(module);
|
|
112
|
+
*
|
|
113
|
+
* // Register tool executors
|
|
114
|
+
* interceptor.registerTool('read_file', async (args) => {
|
|
115
|
+
* return fs.readFile(args.path as string, 'utf-8');
|
|
116
|
+
* });
|
|
117
|
+
*
|
|
118
|
+
* // Execute tool with policy check
|
|
119
|
+
* const result = await interceptor.execute({
|
|
120
|
+
* name: 'write_file',
|
|
121
|
+
* arguments: { path: '/tmp/test.txt', content: 'hello' }
|
|
122
|
+
* });
|
|
123
|
+
*
|
|
124
|
+
* if (!result.success) {
|
|
125
|
+
* console.error('Tool blocked:', result.error);
|
|
126
|
+
* }
|
|
127
|
+
*/
|
|
128
|
+
export declare class ToolCallInterceptor {
|
|
129
|
+
private module;
|
|
130
|
+
private tools;
|
|
131
|
+
private callLog;
|
|
132
|
+
constructor(module: CognitiveModule);
|
|
133
|
+
/**
|
|
134
|
+
* Register a tool executor.
|
|
135
|
+
*/
|
|
136
|
+
registerTool(name: string, executor: ToolExecutor): void;
|
|
137
|
+
/**
|
|
138
|
+
* Register multiple tools at once.
|
|
139
|
+
*/
|
|
140
|
+
registerTools(tools: Record<string, ToolExecutor>): void;
|
|
141
|
+
/**
|
|
142
|
+
* Check if a tool call is allowed without executing it.
|
|
143
|
+
*/
|
|
144
|
+
checkAllowed(toolName: string): PolicyCheckResult;
|
|
145
|
+
/**
|
|
146
|
+
* Execute a tool call with policy enforcement.
|
|
147
|
+
*
|
|
148
|
+
* @param request The tool call request
|
|
149
|
+
* @returns ToolCallResult with success/error
|
|
150
|
+
*/
|
|
151
|
+
execute(request: ToolCallRequest): Promise<ToolCallResult>;
|
|
152
|
+
/**
|
|
153
|
+
* Execute multiple tool calls in sequence.
|
|
154
|
+
* Stops on first policy violation.
|
|
155
|
+
*/
|
|
156
|
+
executeMany(requests: ToolCallRequest[]): Promise<ToolCallResult[]>;
|
|
157
|
+
/**
|
|
158
|
+
* Get the call log for auditing.
|
|
159
|
+
*/
|
|
160
|
+
getCallLog(): Array<{
|
|
161
|
+
tool: string;
|
|
162
|
+
allowed: boolean;
|
|
163
|
+
timestamp: number;
|
|
164
|
+
}>;
|
|
165
|
+
/**
|
|
166
|
+
* Get summary of denied calls.
|
|
167
|
+
*/
|
|
168
|
+
getDeniedCalls(): Array<{
|
|
169
|
+
tool: string;
|
|
170
|
+
timestamp: number;
|
|
171
|
+
}>;
|
|
172
|
+
/**
|
|
173
|
+
* Clear the call log.
|
|
174
|
+
*/
|
|
175
|
+
clearLog(): void;
|
|
176
|
+
/**
|
|
177
|
+
* Get policy summary for this module.
|
|
178
|
+
*/
|
|
179
|
+
getPolicySummary(): {
|
|
180
|
+
deniedActions: PolicyAction[];
|
|
181
|
+
deniedTools: string[];
|
|
182
|
+
allowedTools: string[] | null;
|
|
183
|
+
toolsPolicy: 'allow_by_default' | 'deny_by_default' | undefined;
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Create a policy-aware tool executor wrapper.
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* const safeExecutor = createPolicyAwareExecutor(module, 'write_file', async (args) => {
|
|
191
|
+
* return fs.writeFile(args.path, args.content);
|
|
192
|
+
* });
|
|
193
|
+
*
|
|
194
|
+
* // This will throw if write_file is denied
|
|
195
|
+
* await safeExecutor({ path: '/tmp/test.txt', content: 'hello' });
|
|
196
|
+
*/
|
|
197
|
+
export declare function createPolicyAwareExecutor(module: CognitiveModule, toolName: string, executor: ToolExecutor): ToolExecutor;
|
|
198
|
+
/**
|
|
199
|
+
* Validate overflow.insights against module's max_items config.
|
|
200
|
+
*
|
|
201
|
+
* @param data The response data object
|
|
202
|
+
* @param module The cognitive module config
|
|
203
|
+
* @returns Array of errors if insights exceed limit
|
|
204
|
+
*/
|
|
205
|
+
export declare function validateOverflowLimits(data: Record<string, unknown>, module: CognitiveModule): string[];
|
|
206
|
+
/**
|
|
207
|
+
* Validate enum values against module's enum strategy.
|
|
208
|
+
* For strict mode, custom enum objects are not allowed.
|
|
209
|
+
*
|
|
210
|
+
* @param data The response data object
|
|
211
|
+
* @param module The cognitive module config
|
|
212
|
+
* @returns Array of errors if enum violations found
|
|
213
|
+
*/
|
|
214
|
+
export declare function validateEnumStrategy(data: Record<string, unknown>, module: CognitiveModule): string[];
|
|
215
|
+
/** Hook called before module execution */
|
|
216
|
+
export type BeforeCallHook = (moduleName: string, inputData: ModuleInput, moduleConfig: CognitiveModule) => void;
|
|
217
|
+
/** Hook called after successful module execution */
|
|
218
|
+
export type AfterCallHook = (moduleName: string, result: EnvelopeResponseV22<unknown>, latencyMs: number) => void;
|
|
219
|
+
/** Hook called when an error occurs */
|
|
220
|
+
export type ErrorHook = (moduleName: string, error: Error, partialResult: unknown | null) => void;
|
|
221
|
+
/**
|
|
222
|
+
* Decorator to register a before-call hook.
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* onBeforeCall((moduleName, inputData, config) => {
|
|
226
|
+
* console.log(`Calling ${moduleName} with`, inputData);
|
|
227
|
+
* });
|
|
228
|
+
*/
|
|
229
|
+
export declare function onBeforeCall(hook: BeforeCallHook): BeforeCallHook;
|
|
230
|
+
/**
|
|
231
|
+
* Decorator to register an after-call hook.
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* onAfterCall((moduleName, result, latencyMs) => {
|
|
235
|
+
* console.log(`${moduleName} completed in ${latencyMs}ms`);
|
|
236
|
+
* });
|
|
237
|
+
*/
|
|
238
|
+
export declare function onAfterCall(hook: AfterCallHook): AfterCallHook;
|
|
239
|
+
/**
|
|
240
|
+
* Decorator to register an error hook.
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* onError((moduleName, error, partialResult) => {
|
|
244
|
+
* console.error(`Error in ${moduleName}:`, error);
|
|
245
|
+
* });
|
|
246
|
+
*/
|
|
247
|
+
export declare function onError(hook: ErrorHook): ErrorHook;
|
|
248
|
+
/**
|
|
249
|
+
* Register a hook programmatically.
|
|
250
|
+
*/
|
|
251
|
+
export declare function registerHook(hookType: 'before_call' | 'after_call' | 'error', hook: BeforeCallHook | AfterCallHook | ErrorHook): void;
|
|
252
|
+
/**
|
|
253
|
+
* Unregister a hook. Returns true if found and removed.
|
|
254
|
+
*/
|
|
255
|
+
export declare function unregisterHook(hookType: 'before_call' | 'after_call' | 'error', hook: BeforeCallHook | AfterCallHook | ErrorHook): boolean;
|
|
256
|
+
/**
|
|
257
|
+
* Clear all registered hooks.
|
|
258
|
+
*/
|
|
259
|
+
export declare function clearHooks(): void;
|
|
260
|
+
/** Error codes and their default properties */
|
|
261
|
+
export declare const ERROR_PROPERTIES: Record<string, {
|
|
262
|
+
recoverable: boolean;
|
|
263
|
+
retry_after_ms: number | null;
|
|
264
|
+
}>;
|
|
265
|
+
export interface MakeErrorResponseOptions {
|
|
266
|
+
code: string;
|
|
267
|
+
message: string;
|
|
268
|
+
explain?: string;
|
|
269
|
+
partialData?: unknown;
|
|
270
|
+
details?: Record<string, unknown>;
|
|
271
|
+
recoverable?: boolean;
|
|
272
|
+
retryAfterMs?: number;
|
|
273
|
+
confidence?: number;
|
|
274
|
+
risk?: RiskLevel;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Build a standardized error response with enhanced taxonomy.
|
|
278
|
+
*/
|
|
279
|
+
export declare function makeErrorResponse(options: MakeErrorResponseOptions): EnvelopeResponseV22<unknown>;
|
|
280
|
+
export interface MakeSuccessResponseOptions {
|
|
281
|
+
data: unknown;
|
|
282
|
+
confidence: number;
|
|
283
|
+
risk: RiskLevel;
|
|
284
|
+
explain: string;
|
|
285
|
+
latencyMs?: number;
|
|
286
|
+
model?: string;
|
|
287
|
+
traceId?: string;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Build a standardized success response.
|
|
291
|
+
*/
|
|
292
|
+
export declare function makeSuccessResponse(options: MakeSuccessResponseOptions): EnvelopeResponseV22<unknown>;
|
|
6
293
|
export interface RunOptions {
|
|
7
294
|
input?: ModuleInput;
|
|
8
295
|
args?: string;
|
|
9
296
|
verbose?: boolean;
|
|
297
|
+
validateInput?: boolean;
|
|
298
|
+
validateOutput?: boolean;
|
|
10
299
|
useEnvelope?: boolean;
|
|
11
300
|
useV22?: boolean;
|
|
12
301
|
enableRepair?: boolean;
|
|
302
|
+
traceId?: string;
|
|
303
|
+
model?: string;
|
|
13
304
|
}
|
|
14
305
|
export declare function runModule(module: CognitiveModule, provider: Provider, options?: RunOptions): Promise<ModuleResult>;
|
|
306
|
+
/** Event types emitted during streaming execution */
|
|
307
|
+
export type StreamEventType = 'start' | 'chunk' | 'meta' | 'complete' | 'error';
|
|
308
|
+
/** Event emitted during streaming execution */
|
|
309
|
+
export interface StreamEvent {
|
|
310
|
+
type: StreamEventType;
|
|
311
|
+
timestamp_ms: number;
|
|
312
|
+
module_name: string;
|
|
313
|
+
chunk?: string;
|
|
314
|
+
meta?: EnvelopeMeta;
|
|
315
|
+
result?: EnvelopeResponseV22<unknown>;
|
|
316
|
+
error?: {
|
|
317
|
+
code: string;
|
|
318
|
+
message: string;
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
export interface StreamOptions {
|
|
322
|
+
input?: ModuleInput;
|
|
323
|
+
args?: string;
|
|
324
|
+
validateInput?: boolean;
|
|
325
|
+
validateOutput?: boolean;
|
|
326
|
+
useV22?: boolean;
|
|
327
|
+
enableRepair?: boolean;
|
|
328
|
+
traceId?: string;
|
|
329
|
+
model?: string;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Run a cognitive module with streaming output.
|
|
333
|
+
*
|
|
334
|
+
* Yields StreamEvent objects as the module executes:
|
|
335
|
+
* - type="start": Module execution started
|
|
336
|
+
* - type="chunk": Incremental data chunk (if LLM supports streaming)
|
|
337
|
+
* - type="meta": Meta information available early
|
|
338
|
+
* - type="complete": Final complete result
|
|
339
|
+
* - type="error": Error occurred
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* for await (const event of runModuleStream(module, provider, options)) {
|
|
343
|
+
* if (event.type === 'chunk') {
|
|
344
|
+
* process.stdout.write(event.chunk);
|
|
345
|
+
* } else if (event.type === 'complete') {
|
|
346
|
+
* console.log('Result:', event.result);
|
|
347
|
+
* }
|
|
348
|
+
* }
|
|
349
|
+
*/
|
|
350
|
+
export declare function runModuleStream(module: CognitiveModule, provider: Provider, options?: StreamOptions): AsyncGenerator<StreamEvent>;
|
|
351
|
+
export interface RunModuleLegacyOptions {
|
|
352
|
+
validateInput?: boolean;
|
|
353
|
+
validateOutput?: boolean;
|
|
354
|
+
model?: string;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Run a cognitive module (legacy API, returns raw output).
|
|
358
|
+
* For backward compatibility. Throws on error instead of returning error envelope.
|
|
359
|
+
*/
|
|
360
|
+
export declare function runModuleLegacy(module: CognitiveModule, provider: Provider, input: ModuleInput, options?: RunModuleLegacyOptions): Promise<unknown>;
|
|
361
|
+
/**
|
|
362
|
+
* Extract meta from v2.2 envelope for routing/logging.
|
|
363
|
+
*/
|
|
364
|
+
export declare function extractMeta(result: EnvelopeResponseV22<unknown>): EnvelopeMeta;
|
|
365
|
+
export declare const extractMetaV22: typeof extractMeta;
|
|
366
|
+
/**
|
|
367
|
+
* Determine if result should be escalated to human review based on meta.
|
|
368
|
+
*/
|
|
369
|
+
export declare function shouldEscalate(result: EnvelopeResponseV22<unknown>, confidenceThreshold?: number): boolean;
|
|
370
|
+
export declare const shouldEscalateV22: typeof shouldEscalate;
|