cognitive-runtime 0.1.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.
Files changed (51) hide show
  1. package/README.md +124 -0
  2. package/dist/cli.d.ts +10 -0
  3. package/dist/cli.js +200 -0
  4. package/dist/commands/index.d.ts +7 -0
  5. package/dist/commands/index.js +7 -0
  6. package/dist/commands/init.d.ts +5 -0
  7. package/dist/commands/init.js +78 -0
  8. package/dist/commands/list.d.ts +5 -0
  9. package/dist/commands/list.js +28 -0
  10. package/dist/commands/pipe.d.ts +9 -0
  11. package/dist/commands/pipe.js +57 -0
  12. package/dist/commands/run.d.ts +12 -0
  13. package/dist/commands/run.js +48 -0
  14. package/dist/index.d.ts +9 -0
  15. package/dist/index.js +11 -0
  16. package/dist/modules/index.d.ts +5 -0
  17. package/dist/modules/index.js +5 -0
  18. package/dist/modules/loader.d.ts +8 -0
  19. package/dist/modules/loader.js +91 -0
  20. package/dist/modules/runner.d.ts +12 -0
  21. package/dist/modules/runner.js +93 -0
  22. package/dist/providers/anthropic.d.ts +14 -0
  23. package/dist/providers/anthropic.js +70 -0
  24. package/dist/providers/base.d.ts +11 -0
  25. package/dist/providers/base.js +19 -0
  26. package/dist/providers/gemini.d.ts +19 -0
  27. package/dist/providers/gemini.js +94 -0
  28. package/dist/providers/index.d.ts +13 -0
  29. package/dist/providers/index.js +38 -0
  30. package/dist/providers/openai.d.ts +14 -0
  31. package/dist/providers/openai.js +67 -0
  32. package/dist/types.d.ts +53 -0
  33. package/dist/types.js +4 -0
  34. package/package.json +33 -0
  35. package/src/cli.ts +223 -0
  36. package/src/commands/index.ts +8 -0
  37. package/src/commands/init.ts +94 -0
  38. package/src/commands/list.ts +33 -0
  39. package/src/commands/pipe.ts +74 -0
  40. package/src/commands/run.ts +65 -0
  41. package/src/index.ts +39 -0
  42. package/src/modules/index.ts +6 -0
  43. package/src/modules/loader.ts +106 -0
  44. package/src/modules/runner.ts +121 -0
  45. package/src/providers/anthropic.ts +89 -0
  46. package/src/providers/base.ts +29 -0
  47. package/src/providers/gemini.ts +117 -0
  48. package/src/providers/index.ts +43 -0
  49. package/src/providers/openai.ts +84 -0
  50. package/src/types.ts +64 -0
  51. package/tsconfig.json +17 -0
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Module Loader - Load and parse Cognitive Modules
3
+ */
4
+ import * as fs from 'node:fs/promises';
5
+ import * as path from 'node:path';
6
+ import yaml from 'js-yaml';
7
+ const FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n([\s\S]*))?/;
8
+ export async function loadModule(modulePath) {
9
+ const moduleFile = path.join(modulePath, 'MODULE.md');
10
+ const schemaFile = path.join(modulePath, 'schema.json');
11
+ // Read MODULE.md
12
+ const moduleContent = await fs.readFile(moduleFile, 'utf-8');
13
+ // Parse frontmatter
14
+ const match = moduleContent.match(FRONTMATTER_REGEX);
15
+ if (!match) {
16
+ throw new Error(`Invalid MODULE.md: missing YAML frontmatter in ${moduleFile}`);
17
+ }
18
+ const frontmatter = yaml.load(match[1]);
19
+ const prompt = (match[2] || '').trim();
20
+ // Read schema.json
21
+ let inputSchema;
22
+ let outputSchema;
23
+ try {
24
+ const schemaContent = await fs.readFile(schemaFile, 'utf-8');
25
+ const schema = JSON.parse(schemaContent);
26
+ inputSchema = schema.input;
27
+ outputSchema = schema.output;
28
+ }
29
+ catch {
30
+ // Schema file is optional
31
+ }
32
+ return {
33
+ name: frontmatter.name || path.basename(modulePath),
34
+ version: frontmatter.version || '1.0.0',
35
+ responsibility: frontmatter.responsibility || '',
36
+ excludes: frontmatter.excludes || [],
37
+ context: frontmatter.context,
38
+ prompt,
39
+ inputSchema,
40
+ outputSchema,
41
+ location: modulePath,
42
+ };
43
+ }
44
+ export async function findModule(name, searchPaths) {
45
+ for (const basePath of searchPaths) {
46
+ const modulePath = path.join(basePath, name);
47
+ const moduleFile = path.join(modulePath, 'MODULE.md');
48
+ try {
49
+ await fs.access(moduleFile);
50
+ return await loadModule(modulePath);
51
+ }
52
+ catch {
53
+ // Module not found in this path, continue
54
+ }
55
+ }
56
+ return null;
57
+ }
58
+ export async function listModules(searchPaths) {
59
+ const modules = [];
60
+ for (const basePath of searchPaths) {
61
+ try {
62
+ const entries = await fs.readdir(basePath, { withFileTypes: true });
63
+ for (const entry of entries) {
64
+ if (entry.isDirectory()) {
65
+ const modulePath = path.join(basePath, entry.name);
66
+ const moduleFile = path.join(modulePath, 'MODULE.md');
67
+ try {
68
+ await fs.access(moduleFile);
69
+ const module = await loadModule(modulePath);
70
+ modules.push(module);
71
+ }
72
+ catch {
73
+ // Not a valid module, skip
74
+ }
75
+ }
76
+ }
77
+ }
78
+ catch {
79
+ // Path doesn't exist, skip
80
+ }
81
+ }
82
+ return modules;
83
+ }
84
+ export function getDefaultSearchPaths(cwd) {
85
+ const home = process.env.HOME || '';
86
+ return [
87
+ path.join(cwd, 'cognitive', 'modules'),
88
+ path.join(cwd, '.cognitive', 'modules'),
89
+ path.join(home, '.cognitive', 'modules'),
90
+ ];
91
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Module Runner - Execute Cognitive Modules
3
+ */
4
+ import type { Provider, CognitiveModule, ModuleResult } from '../types.js';
5
+ export interface RunOptions {
6
+ args?: string;
7
+ input?: Record<string, unknown>;
8
+ validateInput?: boolean;
9
+ validateOutput?: boolean;
10
+ verbose?: boolean;
11
+ }
12
+ export declare function runModule(module: CognitiveModule, provider: Provider, options?: RunOptions): Promise<ModuleResult>;
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Module Runner - Execute Cognitive Modules
3
+ */
4
+ export async function runModule(module, provider, options = {}) {
5
+ const { args, input, verbose = false } = options;
6
+ // Build input data
7
+ let inputData = input || {};
8
+ if (args) {
9
+ inputData = { $ARGUMENTS: args, query: args };
10
+ }
11
+ // Build prompt
12
+ const prompt = buildPrompt(module, inputData);
13
+ if (verbose) {
14
+ console.error('--- Prompt ---');
15
+ console.error(prompt);
16
+ console.error('--- End Prompt ---');
17
+ }
18
+ // Build messages
19
+ const messages = [
20
+ {
21
+ role: 'system',
22
+ content: `You are executing the "${module.name}" Cognitive Module.
23
+
24
+ RESPONSIBILITY: ${module.responsibility}
25
+
26
+ YOU MUST NOT:
27
+ ${module.excludes.map(e => `- ${e}`).join('\n')}
28
+
29
+ REQUIRED OUTPUT FORMAT:
30
+ You MUST respond with a valid JSON object. Include these fields:
31
+ - All fields required by the output schema
32
+ - "confidence": a number between 0 and 1
33
+ - "rationale": a string explaining your reasoning
34
+
35
+ Respond with ONLY valid JSON, no markdown code blocks.`,
36
+ },
37
+ {
38
+ role: 'user',
39
+ content: prompt,
40
+ },
41
+ ];
42
+ // Invoke provider
43
+ const result = await provider.invoke({
44
+ messages,
45
+ jsonSchema: module.outputSchema,
46
+ temperature: 0.3,
47
+ });
48
+ if (verbose) {
49
+ console.error('--- Response ---');
50
+ console.error(result.content);
51
+ console.error('--- End Response ---');
52
+ }
53
+ // Parse response
54
+ let output;
55
+ try {
56
+ // Try to extract JSON from markdown code blocks
57
+ const jsonMatch = result.content.match(/```(?:json)?\s*([\s\S]*?)\s*```/);
58
+ const jsonStr = jsonMatch ? jsonMatch[1] : result.content;
59
+ output = JSON.parse(jsonStr.trim());
60
+ }
61
+ catch {
62
+ throw new Error(`Failed to parse JSON response: ${result.content.substring(0, 500)}`);
63
+ }
64
+ // Extract confidence and rationale
65
+ const outputObj = output;
66
+ const confidence = typeof outputObj.confidence === 'number' ? outputObj.confidence : 0.5;
67
+ const rationale = typeof outputObj.rationale === 'string' ? outputObj.rationale : '';
68
+ return {
69
+ output,
70
+ confidence,
71
+ rationale,
72
+ raw: result.content,
73
+ };
74
+ }
75
+ function buildPrompt(module, inputData) {
76
+ let prompt = module.prompt;
77
+ // Substitute $ARGUMENTS
78
+ const argsValue = String(inputData.$ARGUMENTS || inputData.query || '');
79
+ prompt = prompt.replace(/\$ARGUMENTS/g, argsValue);
80
+ // Substitute $N placeholders
81
+ const argsList = argsValue.split(/\s+/);
82
+ argsList.forEach((arg, i) => {
83
+ prompt = prompt.replace(new RegExp(`\\$${i}`, 'g'), arg);
84
+ prompt = prompt.replace(new RegExp(`\\$ARGUMENTS\\[${i}\\]`, 'g'), arg);
85
+ });
86
+ // Substitute other input fields
87
+ for (const [key, value] of Object.entries(inputData)) {
88
+ if (key !== '$ARGUMENTS' && key !== 'query') {
89
+ prompt = prompt.replace(new RegExp(`\\$\\{${key}\\}`, 'g'), String(value));
90
+ }
91
+ }
92
+ return prompt;
93
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Anthropic Provider - Claude API
3
+ */
4
+ import { BaseProvider } from './base.js';
5
+ import type { InvokeParams, InvokeResult } from '../types.js';
6
+ export declare class AnthropicProvider extends BaseProvider {
7
+ name: string;
8
+ private apiKey;
9
+ private model;
10
+ private baseUrl;
11
+ constructor(apiKey?: string, model?: string);
12
+ isConfigured(): boolean;
13
+ invoke(params: InvokeParams): Promise<InvokeResult>;
14
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Anthropic Provider - Claude API
3
+ */
4
+ import { BaseProvider } from './base.js';
5
+ export class AnthropicProvider extends BaseProvider {
6
+ name = 'anthropic';
7
+ apiKey;
8
+ model;
9
+ baseUrl = 'https://api.anthropic.com/v1';
10
+ constructor(apiKey, model = 'claude-sonnet-4-20250514') {
11
+ super();
12
+ this.apiKey = apiKey || process.env.ANTHROPIC_API_KEY || '';
13
+ this.model = model;
14
+ }
15
+ isConfigured() {
16
+ return !!this.apiKey;
17
+ }
18
+ async invoke(params) {
19
+ if (!this.isConfigured()) {
20
+ throw new Error('Anthropic API key not configured. Set ANTHROPIC_API_KEY environment variable.');
21
+ }
22
+ const url = `${this.baseUrl}/messages`;
23
+ // Extract system message
24
+ const systemMessage = params.messages.find(m => m.role === 'system');
25
+ const otherMessages = params.messages.filter(m => m.role !== 'system');
26
+ // Add JSON schema instruction if provided
27
+ let messages = otherMessages;
28
+ if (params.jsonSchema) {
29
+ const lastUserIdx = messages.findLastIndex(m => m.role === 'user');
30
+ if (lastUserIdx >= 0) {
31
+ messages = [...messages];
32
+ messages[lastUserIdx] = {
33
+ ...messages[lastUserIdx],
34
+ content: messages[lastUserIdx].content + this.buildJsonPrompt(params.jsonSchema),
35
+ };
36
+ }
37
+ }
38
+ const body = {
39
+ model: this.model,
40
+ messages: messages.map(m => ({ role: m.role, content: m.content })),
41
+ max_tokens: params.maxTokens ?? 4096,
42
+ };
43
+ if (systemMessage) {
44
+ body.system = systemMessage.content;
45
+ }
46
+ const response = await fetch(url, {
47
+ method: 'POST',
48
+ headers: {
49
+ 'Content-Type': 'application/json',
50
+ 'x-api-key': this.apiKey,
51
+ 'anthropic-version': '2023-06-01',
52
+ },
53
+ body: JSON.stringify(body),
54
+ });
55
+ if (!response.ok) {
56
+ const error = await response.text();
57
+ throw new Error(`Anthropic API error: ${response.status} - ${error}`);
58
+ }
59
+ const data = await response.json();
60
+ const content = data.content?.[0]?.text || '';
61
+ return {
62
+ content,
63
+ usage: data.usage ? {
64
+ promptTokens: data.usage.input_tokens || 0,
65
+ completionTokens: data.usage.output_tokens || 0,
66
+ totalTokens: (data.usage.input_tokens || 0) + (data.usage.output_tokens || 0),
67
+ } : undefined,
68
+ };
69
+ }
70
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Base Provider - Abstract class for all LLM providers
3
+ */
4
+ import type { Provider, InvokeParams, InvokeResult } from '../types.js';
5
+ export declare abstract class BaseProvider implements Provider {
6
+ abstract name: string;
7
+ abstract invoke(params: InvokeParams): Promise<InvokeResult>;
8
+ abstract isConfigured(): boolean;
9
+ protected buildJsonPrompt(schema: object): string;
10
+ protected parseJsonResponse(content: string): unknown;
11
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Base Provider - Abstract class for all LLM providers
3
+ */
4
+ export class BaseProvider {
5
+ buildJsonPrompt(schema) {
6
+ return `\n\nYou MUST respond with valid JSON matching this schema:\n${JSON.stringify(schema, null, 2)}\n\nRespond with ONLY the JSON, no markdown code blocks.`;
7
+ }
8
+ parseJsonResponse(content) {
9
+ // Try to extract JSON from markdown code blocks
10
+ const jsonMatch = content.match(/```(?:json)?\s*([\s\S]*?)\s*```/);
11
+ const jsonStr = jsonMatch ? jsonMatch[1] : content;
12
+ try {
13
+ return JSON.parse(jsonStr.trim());
14
+ }
15
+ catch {
16
+ throw new Error(`Failed to parse JSON response: ${content.substring(0, 200)}`);
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Gemini Provider - Google Gemini API
3
+ */
4
+ import { BaseProvider } from './base.js';
5
+ import type { InvokeParams, InvokeResult } from '../types.js';
6
+ export declare class GeminiProvider extends BaseProvider {
7
+ name: string;
8
+ private apiKey;
9
+ private model;
10
+ private baseUrl;
11
+ constructor(apiKey?: string, model?: string);
12
+ isConfigured(): boolean;
13
+ /**
14
+ * Clean JSON Schema for Gemini API compatibility
15
+ * Removes unsupported fields like additionalProperties
16
+ */
17
+ private cleanSchemaForGemini;
18
+ invoke(params: InvokeParams): Promise<InvokeResult>;
19
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Gemini Provider - Google Gemini API
3
+ */
4
+ import { BaseProvider } from './base.js';
5
+ export class GeminiProvider extends BaseProvider {
6
+ name = 'gemini';
7
+ apiKey;
8
+ model;
9
+ baseUrl = 'https://generativelanguage.googleapis.com/v1beta';
10
+ constructor(apiKey, model = 'gemini-2.0-flash') {
11
+ super();
12
+ this.apiKey = apiKey || process.env.GEMINI_API_KEY || '';
13
+ this.model = model;
14
+ }
15
+ isConfigured() {
16
+ return !!this.apiKey;
17
+ }
18
+ /**
19
+ * Clean JSON Schema for Gemini API compatibility
20
+ * Removes unsupported fields like additionalProperties
21
+ */
22
+ cleanSchemaForGemini(schema) {
23
+ const unsupportedFields = ['additionalProperties', '$schema', 'default', 'examples'];
24
+ const clean = (obj) => {
25
+ if (Array.isArray(obj)) {
26
+ return obj.map(clean);
27
+ }
28
+ if (obj && typeof obj === 'object') {
29
+ const result = {};
30
+ for (const [key, value] of Object.entries(obj)) {
31
+ if (!unsupportedFields.includes(key)) {
32
+ result[key] = clean(value);
33
+ }
34
+ }
35
+ return result;
36
+ }
37
+ return obj;
38
+ };
39
+ return clean(schema);
40
+ }
41
+ async invoke(params) {
42
+ if (!this.isConfigured()) {
43
+ throw new Error('Gemini API key not configured. Set GEMINI_API_KEY environment variable.');
44
+ }
45
+ const url = `${this.baseUrl}/models/${this.model}:generateContent?key=${this.apiKey}`;
46
+ // Convert messages to Gemini format
47
+ const contents = params.messages
48
+ .filter(m => m.role !== 'system')
49
+ .map(m => ({
50
+ role: m.role === 'assistant' ? 'model' : 'user',
51
+ parts: [{ text: m.content }]
52
+ }));
53
+ // Add system instruction if present
54
+ const systemMessage = params.messages.find(m => m.role === 'system');
55
+ const body = {
56
+ contents,
57
+ generationConfig: {
58
+ temperature: params.temperature ?? 0.7,
59
+ maxOutputTokens: params.maxTokens ?? 8192,
60
+ }
61
+ };
62
+ if (systemMessage) {
63
+ body.systemInstruction = { parts: [{ text: systemMessage.content }] };
64
+ }
65
+ // Add JSON schema constraint if provided
66
+ if (params.jsonSchema) {
67
+ const cleanedSchema = this.cleanSchemaForGemini(params.jsonSchema);
68
+ body.generationConfig = {
69
+ ...body.generationConfig,
70
+ responseMimeType: 'application/json',
71
+ responseSchema: cleanedSchema,
72
+ };
73
+ }
74
+ const response = await fetch(url, {
75
+ method: 'POST',
76
+ headers: { 'Content-Type': 'application/json' },
77
+ body: JSON.stringify(body),
78
+ });
79
+ if (!response.ok) {
80
+ const error = await response.text();
81
+ throw new Error(`Gemini API error: ${response.status} - ${error}`);
82
+ }
83
+ const data = await response.json();
84
+ const content = data.candidates?.[0]?.content?.parts?.[0]?.text || '';
85
+ return {
86
+ content,
87
+ usage: data.usageMetadata ? {
88
+ promptTokens: data.usageMetadata.promptTokenCount || 0,
89
+ completionTokens: data.usageMetadata.candidatesTokenCount || 0,
90
+ totalTokens: data.usageMetadata.totalTokenCount || 0,
91
+ } : undefined,
92
+ };
93
+ }
94
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Provider Registry
3
+ */
4
+ import type { Provider } from '../types.js';
5
+ export { BaseProvider } from './base.js';
6
+ export { GeminiProvider } from './gemini.js';
7
+ export { OpenAIProvider } from './openai.js';
8
+ export { AnthropicProvider } from './anthropic.js';
9
+ export declare function getProvider(name?: string): Provider;
10
+ export declare function listProviders(): Array<{
11
+ name: string;
12
+ configured: boolean;
13
+ }>;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Provider Registry
3
+ */
4
+ import { GeminiProvider } from './gemini.js';
5
+ import { OpenAIProvider } from './openai.js';
6
+ import { AnthropicProvider } from './anthropic.js';
7
+ export { BaseProvider } from './base.js';
8
+ export { GeminiProvider } from './gemini.js';
9
+ export { OpenAIProvider } from './openai.js';
10
+ export { AnthropicProvider } from './anthropic.js';
11
+ const providers = {
12
+ gemini: () => new GeminiProvider(),
13
+ openai: () => new OpenAIProvider(),
14
+ anthropic: () => new AnthropicProvider(),
15
+ };
16
+ export function getProvider(name) {
17
+ // Auto-detect if not specified
18
+ if (!name) {
19
+ if (process.env.GEMINI_API_KEY)
20
+ return new GeminiProvider();
21
+ if (process.env.OPENAI_API_KEY)
22
+ return new OpenAIProvider();
23
+ if (process.env.ANTHROPIC_API_KEY)
24
+ return new AnthropicProvider();
25
+ throw new Error('No LLM provider configured. Set GEMINI_API_KEY, OPENAI_API_KEY, or ANTHROPIC_API_KEY.');
26
+ }
27
+ const factory = providers[name.toLowerCase()];
28
+ if (!factory) {
29
+ throw new Error(`Unknown provider: ${name}. Available: ${Object.keys(providers).join(', ')}`);
30
+ }
31
+ return factory();
32
+ }
33
+ export function listProviders() {
34
+ return Object.entries(providers).map(([name, factory]) => ({
35
+ name,
36
+ configured: factory().isConfigured(),
37
+ }));
38
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * OpenAI Provider - OpenAI API (and compatible APIs)
3
+ */
4
+ import { BaseProvider } from './base.js';
5
+ import type { InvokeParams, InvokeResult } from '../types.js';
6
+ export declare class OpenAIProvider extends BaseProvider {
7
+ name: string;
8
+ private apiKey;
9
+ private model;
10
+ private baseUrl;
11
+ constructor(apiKey?: string, model?: string, baseUrl?: string);
12
+ isConfigured(): boolean;
13
+ invoke(params: InvokeParams): Promise<InvokeResult>;
14
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * OpenAI Provider - OpenAI API (and compatible APIs)
3
+ */
4
+ import { BaseProvider } from './base.js';
5
+ export class OpenAIProvider extends BaseProvider {
6
+ name = 'openai';
7
+ apiKey;
8
+ model;
9
+ baseUrl;
10
+ constructor(apiKey, model = 'gpt-4o', baseUrl = 'https://api.openai.com/v1') {
11
+ super();
12
+ this.apiKey = apiKey || process.env.OPENAI_API_KEY || '';
13
+ this.model = model;
14
+ this.baseUrl = baseUrl;
15
+ }
16
+ isConfigured() {
17
+ return !!this.apiKey;
18
+ }
19
+ async invoke(params) {
20
+ if (!this.isConfigured()) {
21
+ throw new Error('OpenAI API key not configured. Set OPENAI_API_KEY environment variable.');
22
+ }
23
+ const url = `${this.baseUrl}/chat/completions`;
24
+ const body = {
25
+ model: this.model,
26
+ messages: params.messages,
27
+ temperature: params.temperature ?? 0.7,
28
+ max_tokens: params.maxTokens ?? 4096,
29
+ };
30
+ // Add JSON mode if schema provided
31
+ if (params.jsonSchema) {
32
+ body.response_format = { type: 'json_object' };
33
+ // Append schema instruction to last user message
34
+ const lastUserIdx = params.messages.findLastIndex(m => m.role === 'user');
35
+ if (lastUserIdx >= 0) {
36
+ const messages = [...params.messages];
37
+ messages[lastUserIdx] = {
38
+ ...messages[lastUserIdx],
39
+ content: messages[lastUserIdx].content + this.buildJsonPrompt(params.jsonSchema),
40
+ };
41
+ body.messages = messages;
42
+ }
43
+ }
44
+ const response = await fetch(url, {
45
+ method: 'POST',
46
+ headers: {
47
+ 'Content-Type': 'application/json',
48
+ 'Authorization': `Bearer ${this.apiKey}`,
49
+ },
50
+ body: JSON.stringify(body),
51
+ });
52
+ if (!response.ok) {
53
+ const error = await response.text();
54
+ throw new Error(`OpenAI API error: ${response.status} - ${error}`);
55
+ }
56
+ const data = await response.json();
57
+ const content = data.choices?.[0]?.message?.content || '';
58
+ return {
59
+ content,
60
+ usage: data.usage ? {
61
+ promptTokens: data.usage.prompt_tokens || 0,
62
+ completionTokens: data.usage.completion_tokens || 0,
63
+ totalTokens: data.usage.total_tokens || 0,
64
+ } : undefined,
65
+ };
66
+ }
67
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Cognitive Runtime - Core Types
3
+ */
4
+ export interface Provider {
5
+ name: string;
6
+ invoke(params: InvokeParams): Promise<InvokeResult>;
7
+ isConfigured(): boolean;
8
+ }
9
+ export interface InvokeParams {
10
+ messages: Message[];
11
+ jsonSchema?: object;
12
+ temperature?: number;
13
+ maxTokens?: number;
14
+ }
15
+ export interface Message {
16
+ role: 'system' | 'user' | 'assistant';
17
+ content: string;
18
+ }
19
+ export interface InvokeResult {
20
+ content: string;
21
+ usage?: {
22
+ promptTokens: number;
23
+ completionTokens: number;
24
+ totalTokens: number;
25
+ };
26
+ }
27
+ export interface CognitiveModule {
28
+ name: string;
29
+ version: string;
30
+ responsibility: string;
31
+ excludes: string[];
32
+ context?: 'fork' | 'main';
33
+ prompt: string;
34
+ inputSchema?: object;
35
+ outputSchema?: object;
36
+ location: string;
37
+ }
38
+ export interface ModuleResult {
39
+ output: unknown;
40
+ confidence: number;
41
+ rationale: string;
42
+ raw?: string;
43
+ }
44
+ export interface CommandContext {
45
+ cwd: string;
46
+ provider: Provider;
47
+ verbose?: boolean;
48
+ }
49
+ export interface CommandResult {
50
+ success: boolean;
51
+ data?: unknown;
52
+ error?: string;
53
+ }
package/dist/types.js ADDED
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Cognitive Runtime - Core Types
3
+ */
4
+ export {};
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "cognitive-runtime",
3
+ "version": "0.1.0",
4
+ "description": "Cognitive Runtime - Structured AI Task Execution",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "cog": "dist/cli.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "node dist/cli.js",
13
+ "dev": "tsx src/cli.ts"
14
+ },
15
+ "keywords": [
16
+ "cognitive",
17
+ "ai",
18
+ "llm",
19
+ "structured",
20
+ "modules"
21
+ ],
22
+ "license": "MIT",
23
+ "author": "",
24
+ "dependencies": {
25
+ "js-yaml": "^4.1.1",
26
+ "tsx": "^4.21.0",
27
+ "typescript": "^5.9.3"
28
+ },
29
+ "devDependencies": {
30
+ "@types/js-yaml": "^4.0.9",
31
+ "@types/node": "^25.1.0"
32
+ }
33
+ }