cognitive-runtime 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/types.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * Cognitive Runtime - Core Types
3
+ * Version 2.1 - With envelope format, tools policy, failure contract
3
4
  */
4
5
  export interface Provider {
5
6
  name: string;
@@ -29,16 +30,91 @@ export interface CognitiveModule {
29
30
  version: string;
30
31
  responsibility: string;
31
32
  excludes: string[];
33
+ constraints?: ModuleConstraints;
34
+ policies?: ModulePolicies;
35
+ tools?: ToolsPolicy;
36
+ output?: OutputContract;
37
+ failure?: FailureContract;
38
+ runtimeRequirements?: RuntimeRequirements;
32
39
  context?: 'fork' | 'main';
33
40
  prompt: string;
34
41
  inputSchema?: object;
35
42
  outputSchema?: object;
43
+ errorSchema?: object;
36
44
  location: string;
45
+ format: 'v1' | 'v2';
46
+ }
47
+ export interface ModuleConstraints {
48
+ no_network?: boolean;
49
+ no_side_effects?: boolean;
50
+ no_file_write?: boolean;
51
+ no_inventing_data?: boolean;
52
+ behavior_equivalence_false_max_confidence?: number;
53
+ }
54
+ export interface ModulePolicies {
55
+ network?: 'allow' | 'deny';
56
+ filesystem_write?: 'allow' | 'deny';
57
+ side_effects?: 'allow' | 'deny';
58
+ code_execution?: 'allow' | 'deny';
59
+ }
60
+ export interface ToolsPolicy {
61
+ policy?: 'allow_by_default' | 'deny_by_default';
62
+ allowed: string[];
63
+ denied?: string[];
64
+ }
65
+ export interface OutputContract {
66
+ format?: 'json_strict' | 'json_lenient' | 'text';
67
+ envelope?: boolean;
68
+ require?: string[];
69
+ require_confidence?: boolean;
70
+ require_rationale?: boolean;
71
+ require_behavior_equivalence?: boolean;
72
+ }
73
+ export interface FailureContract {
74
+ contract?: 'error_union' | 'throw';
75
+ partial_allowed?: boolean;
76
+ must_return_error_schema?: boolean;
77
+ schema?: object;
78
+ }
79
+ export interface RuntimeRequirements {
80
+ structured_output?: boolean;
81
+ max_input_tokens?: number;
82
+ preferred_capabilities?: string[];
83
+ }
84
+ export interface EnvelopeSuccess<T = unknown> {
85
+ ok: true;
86
+ data: T;
87
+ }
88
+ export interface EnvelopeError {
89
+ ok: false;
90
+ error: {
91
+ code: string;
92
+ message: string;
93
+ };
94
+ partial_data?: unknown;
95
+ }
96
+ export type EnvelopeResponse<T = unknown> = EnvelopeSuccess<T> | EnvelopeError;
97
+ export interface ModuleResultData {
98
+ [key: string]: unknown;
99
+ confidence: number;
100
+ rationale: string;
101
+ behavior_equivalence?: boolean;
37
102
  }
38
103
  export interface ModuleResult {
104
+ ok: boolean;
105
+ data?: ModuleResultData;
106
+ error?: {
107
+ code: string;
108
+ message: string;
109
+ };
110
+ partial_data?: unknown;
111
+ raw?: string;
112
+ }
113
+ export interface LegacyModuleResult {
39
114
  output: unknown;
40
115
  confidence: number;
41
116
  rationale: string;
117
+ behaviorEquivalence?: boolean;
42
118
  raw?: string;
43
119
  }
44
120
  export interface CommandContext {
@@ -51,3 +127,10 @@ export interface CommandResult {
51
127
  data?: unknown;
52
128
  error?: string;
53
129
  }
130
+ export interface ModuleInput {
131
+ code?: string;
132
+ query?: string;
133
+ language?: string;
134
+ options?: Record<string, unknown>;
135
+ [key: string]: unknown;
136
+ }
package/dist/types.js CHANGED
@@ -1,4 +1,5 @@
1
1
  /**
2
2
  * Cognitive Runtime - Core Types
3
+ * Version 2.1 - With envelope format, tools policy, failure contract
3
4
  */
4
5
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cognitive-runtime",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Cognitive Runtime - Structured AI Task Execution",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/cli.ts CHANGED
@@ -13,7 +13,7 @@ import { getProvider, listProviders } from './providers/index.js';
13
13
  import { run, list, pipe, init } from './commands/index.js';
14
14
  import type { CommandContext } from './types.js';
15
15
 
16
- const VERSION = '0.3.0';
16
+ const VERSION = '0.5.0';
17
17
 
18
18
  async function main() {
19
19
  const args = process.argv.slice(2);
@@ -52,20 +52,22 @@ export async function pipe(
52
52
  const result = await runModule(module, ctx.provider, {
53
53
  args: inputData ? undefined : input,
54
54
  input: inputData,
55
- validateInput: !options.noValidate,
56
- validateOutput: !options.noValidate,
57
55
  });
58
56
 
59
- // Output JSON to stdout
60
- console.log(JSON.stringify(result.output));
57
+ // Output envelope format to stdout
58
+ console.log(JSON.stringify(result));
61
59
 
62
60
  return {
63
- success: true,
61
+ success: result.ok,
64
62
  data: result,
65
63
  };
66
64
  } catch (e) {
67
65
  const error = e instanceof Error ? e.message : String(e);
68
- console.error(JSON.stringify({ error }));
66
+ // Output error in envelope format
67
+ console.log(JSON.stringify({
68
+ ok: false,
69
+ error: { code: 'RUNTIME_ERROR', message: error }
70
+ }));
69
71
  return {
70
72
  success: false,
71
73
  error,
@@ -47,15 +47,30 @@ export async function run(
47
47
  const result = await runModule(module, ctx.provider, {
48
48
  args: options.args,
49
49
  input: inputData,
50
- validateInput: !options.noValidate,
51
- validateOutput: !options.noValidate,
52
50
  verbose: options.verbose || ctx.verbose,
53
51
  });
54
52
 
55
- return {
56
- success: true,
57
- data: options.pretty ? result : result.output,
58
- };
53
+ // Return envelope format or extracted data
54
+ if (options.pretty) {
55
+ return {
56
+ success: result.ok,
57
+ data: result,
58
+ };
59
+ } else {
60
+ // For non-pretty mode, return data (success) or error (failure)
61
+ if (result.ok) {
62
+ return {
63
+ success: true,
64
+ data: result.data,
65
+ };
66
+ } else {
67
+ return {
68
+ success: false,
69
+ error: `${result.error?.code}: ${result.error?.message}`,
70
+ data: result.partial_data,
71
+ };
72
+ }
73
+ }
59
74
  } catch (e) {
60
75
  return {
61
76
  success: false,
package/src/index.ts CHANGED
@@ -12,6 +12,11 @@ export type {
12
12
  Message,
13
13
  CognitiveModule,
14
14
  ModuleResult,
15
+ ModuleInput,
16
+ ModuleConstraints,
17
+ ToolsPolicy,
18
+ OutputContract,
19
+ FailureContract,
15
20
  CommandContext,
16
21
  CommandResult,
17
22
  } from './types.js';
@@ -1,15 +1,88 @@
1
1
  /**
2
2
  * Module Loader - Load and parse Cognitive Modules
3
+ * Supports both v1 (MODULE.md) and v2 (module.yaml + prompt.md) formats
3
4
  */
4
5
 
5
6
  import * as fs from 'node:fs/promises';
6
7
  import * as path from 'node:path';
7
8
  import yaml from 'js-yaml';
8
- import type { CognitiveModule } from '../types.js';
9
+ import type { CognitiveModule, ModuleConstraints, ModulePolicies, ToolsPolicy, OutputContract, FailureContract, RuntimeRequirements } from '../types.js';
9
10
 
10
11
  const FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n([\s\S]*))?/;
11
12
 
12
- export async function loadModule(modulePath: string): Promise<CognitiveModule> {
13
+ /**
14
+ * Detect module format version
15
+ */
16
+ async function detectFormat(modulePath: string): Promise<'v1' | 'v2'> {
17
+ const v2Manifest = path.join(modulePath, 'module.yaml');
18
+ try {
19
+ await fs.access(v2Manifest);
20
+ return 'v2';
21
+ } catch {
22
+ return 'v1';
23
+ }
24
+ }
25
+
26
+ /**
27
+ * Load v2 format module (module.yaml + prompt.md)
28
+ */
29
+ async function loadModuleV2(modulePath: string): Promise<CognitiveModule> {
30
+ const manifestFile = path.join(modulePath, 'module.yaml');
31
+ const promptFile = path.join(modulePath, 'prompt.md');
32
+ const schemaFile = path.join(modulePath, 'schema.json');
33
+
34
+ // Read module.yaml
35
+ const manifestContent = await fs.readFile(manifestFile, 'utf-8');
36
+ const manifest = yaml.load(manifestContent) as Record<string, unknown>;
37
+
38
+ // Read prompt.md
39
+ let prompt = '';
40
+ try {
41
+ prompt = await fs.readFile(promptFile, 'utf-8');
42
+ } catch {
43
+ // prompt.md is optional, manifest may include inline prompt
44
+ }
45
+
46
+ // Read schema.json
47
+ let inputSchema: object | undefined;
48
+ let outputSchema: object | undefined;
49
+ let errorSchema: object | undefined;
50
+
51
+ try {
52
+ const schemaContent = await fs.readFile(schemaFile, 'utf-8');
53
+ const schema = JSON.parse(schemaContent);
54
+ inputSchema = schema.input;
55
+ outputSchema = schema.output;
56
+ errorSchema = schema.error;
57
+ } catch {
58
+ // Schema file is optional but recommended
59
+ }
60
+
61
+ return {
62
+ name: manifest.name as string || path.basename(modulePath),
63
+ version: manifest.version as string || '1.0.0',
64
+ responsibility: manifest.responsibility as string || '',
65
+ excludes: (manifest.excludes as string[]) || [],
66
+ constraints: manifest.constraints as ModuleConstraints | undefined,
67
+ policies: manifest.policies as ModulePolicies | undefined,
68
+ tools: manifest.tools as ToolsPolicy | undefined,
69
+ output: manifest.output as OutputContract | undefined,
70
+ failure: manifest.failure as FailureContract | undefined,
71
+ runtimeRequirements: manifest.runtime_requirements as RuntimeRequirements | undefined,
72
+ context: manifest.context as 'fork' | 'main' | undefined,
73
+ prompt,
74
+ inputSchema,
75
+ outputSchema,
76
+ errorSchema,
77
+ location: modulePath,
78
+ format: 'v2',
79
+ };
80
+ }
81
+
82
+ /**
83
+ * Load v1 format module (MODULE.md with frontmatter)
84
+ */
85
+ async function loadModuleV1(modulePath: string): Promise<CognitiveModule> {
13
86
  const moduleFile = path.join(modulePath, 'MODULE.md');
14
87
  const schemaFile = path.join(modulePath, 'schema.json');
15
88
 
@@ -38,29 +111,69 @@ export async function loadModule(modulePath: string): Promise<CognitiveModule> {
38
111
  // Schema file is optional
39
112
  }
40
113
 
114
+ // Extract constraints from v1 format
115
+ const constraints: ModuleConstraints = {};
116
+ const v1Constraints = frontmatter.constraints as Record<string, boolean> | undefined;
117
+ if (v1Constraints) {
118
+ constraints.no_network = v1Constraints.no_network;
119
+ constraints.no_side_effects = v1Constraints.no_side_effects;
120
+ constraints.no_inventing_data = v1Constraints.no_inventing_data;
121
+ }
122
+
41
123
  return {
42
124
  name: frontmatter.name as string || path.basename(modulePath),
43
125
  version: frontmatter.version as string || '1.0.0',
44
126
  responsibility: frontmatter.responsibility as string || '',
45
127
  excludes: (frontmatter.excludes as string[]) || [],
128
+ constraints: Object.keys(constraints).length > 0 ? constraints : undefined,
46
129
  context: frontmatter.context as 'fork' | 'main' | undefined,
47
130
  prompt,
48
131
  inputSchema,
49
132
  outputSchema,
50
133
  location: modulePath,
134
+ format: 'v1',
51
135
  };
52
136
  }
53
137
 
138
+ /**
139
+ * Load a Cognitive Module (auto-detects format)
140
+ */
141
+ export async function loadModule(modulePath: string): Promise<CognitiveModule> {
142
+ const format = await detectFormat(modulePath);
143
+
144
+ if (format === 'v2') {
145
+ return loadModuleV2(modulePath);
146
+ } else {
147
+ return loadModuleV1(modulePath);
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Check if a directory contains a valid module
153
+ */
154
+ async function isValidModule(modulePath: string): Promise<boolean> {
155
+ const v2Manifest = path.join(modulePath, 'module.yaml');
156
+ const v1Module = path.join(modulePath, 'MODULE.md');
157
+
158
+ try {
159
+ await fs.access(v2Manifest);
160
+ return true;
161
+ } catch {
162
+ try {
163
+ await fs.access(v1Module);
164
+ return true;
165
+ } catch {
166
+ return false;
167
+ }
168
+ }
169
+ }
170
+
54
171
  export async function findModule(name: string, searchPaths: string[]): Promise<CognitiveModule | null> {
55
172
  for (const basePath of searchPaths) {
56
173
  const modulePath = path.join(basePath, name);
57
- const moduleFile = path.join(modulePath, 'MODULE.md');
58
174
 
59
- try {
60
- await fs.access(moduleFile);
175
+ if (await isValidModule(modulePath)) {
61
176
  return await loadModule(modulePath);
62
- } catch {
63
- // Module not found in this path, continue
64
177
  }
65
178
  }
66
179
 
@@ -77,14 +190,14 @@ export async function listModules(searchPaths: string[]): Promise<CognitiveModul
77
190
  for (const entry of entries) {
78
191
  if (entry.isDirectory()) {
79
192
  const modulePath = path.join(basePath, entry.name);
80
- const moduleFile = path.join(modulePath, 'MODULE.md');
81
193
 
82
- try {
83
- await fs.access(moduleFile);
84
- const module = await loadModule(modulePath);
85
- modules.push(module);
86
- } catch {
87
- // Not a valid module, skip
194
+ if (await isValidModule(modulePath)) {
195
+ try {
196
+ const module = await loadModule(modulePath);
197
+ modules.push(module);
198
+ } catch {
199
+ // Skip invalid modules
200
+ }
88
201
  }
89
202
  }
90
203
  }