cognitive-modules-cli 2.2.1 → 2.2.7

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 (101) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +35 -29
  4. package/dist/cli.js +519 -23
  5. package/dist/commands/add.d.ts +33 -14
  6. package/dist/commands/add.js +383 -16
  7. package/dist/commands/compose.js +60 -23
  8. package/dist/commands/index.d.ts +4 -0
  9. package/dist/commands/index.js +4 -0
  10. package/dist/commands/init.js +23 -1
  11. package/dist/commands/migrate.d.ts +30 -0
  12. package/dist/commands/migrate.js +650 -0
  13. package/dist/commands/pipe.d.ts +1 -0
  14. package/dist/commands/pipe.js +31 -11
  15. package/dist/commands/remove.js +33 -2
  16. package/dist/commands/run.d.ts +2 -0
  17. package/dist/commands/run.js +61 -28
  18. package/dist/commands/search.d.ts +28 -0
  19. package/dist/commands/search.js +143 -0
  20. package/dist/commands/test.d.ts +65 -0
  21. package/dist/commands/test.js +454 -0
  22. package/dist/commands/update.d.ts +1 -0
  23. package/dist/commands/update.js +106 -14
  24. package/dist/commands/validate.d.ts +36 -0
  25. package/dist/commands/validate.js +97 -0
  26. package/dist/errors/index.d.ts +225 -0
  27. package/dist/errors/index.js +420 -0
  28. package/dist/mcp/server.js +84 -79
  29. package/dist/modules/composition.js +97 -32
  30. package/dist/modules/loader.js +4 -2
  31. package/dist/modules/runner.d.ts +72 -5
  32. package/dist/modules/runner.js +306 -59
  33. package/dist/modules/subagent.d.ts +6 -1
  34. package/dist/modules/subagent.js +18 -13
  35. package/dist/modules/validator.js +14 -6
  36. package/dist/providers/anthropic.d.ts +15 -0
  37. package/dist/providers/anthropic.js +147 -5
  38. package/dist/providers/base.d.ts +11 -0
  39. package/dist/providers/base.js +18 -0
  40. package/dist/providers/gemini.d.ts +15 -0
  41. package/dist/providers/gemini.js +122 -5
  42. package/dist/providers/ollama.d.ts +15 -0
  43. package/dist/providers/ollama.js +111 -3
  44. package/dist/providers/openai.d.ts +11 -0
  45. package/dist/providers/openai.js +133 -0
  46. package/dist/registry/client.d.ts +212 -0
  47. package/dist/registry/client.js +359 -0
  48. package/dist/registry/index.d.ts +4 -0
  49. package/dist/registry/index.js +4 -0
  50. package/dist/registry/tar.d.ts +8 -0
  51. package/dist/registry/tar.js +353 -0
  52. package/dist/server/http.js +301 -45
  53. package/dist/server/index.d.ts +2 -0
  54. package/dist/server/index.js +1 -0
  55. package/dist/server/sse.d.ts +13 -0
  56. package/dist/server/sse.js +22 -0
  57. package/dist/types.d.ts +32 -1
  58. package/dist/types.js +4 -1
  59. package/dist/version.d.ts +1 -0
  60. package/dist/version.js +4 -0
  61. package/package.json +31 -7
  62. package/dist/modules/composition.test.d.ts +0 -11
  63. package/dist/modules/composition.test.js +0 -450
  64. package/dist/modules/policy.test.d.ts +0 -10
  65. package/dist/modules/policy.test.js +0 -369
  66. package/src/cli.ts +0 -471
  67. package/src/commands/add.ts +0 -315
  68. package/src/commands/compose.ts +0 -185
  69. package/src/commands/index.ts +0 -13
  70. package/src/commands/init.ts +0 -94
  71. package/src/commands/list.ts +0 -33
  72. package/src/commands/pipe.ts +0 -76
  73. package/src/commands/remove.ts +0 -57
  74. package/src/commands/run.ts +0 -80
  75. package/src/commands/update.ts +0 -130
  76. package/src/commands/versions.ts +0 -79
  77. package/src/index.ts +0 -90
  78. package/src/mcp/index.ts +0 -5
  79. package/src/mcp/server.ts +0 -403
  80. package/src/modules/composition.test.ts +0 -558
  81. package/src/modules/composition.ts +0 -1674
  82. package/src/modules/index.ts +0 -9
  83. package/src/modules/loader.ts +0 -508
  84. package/src/modules/policy.test.ts +0 -455
  85. package/src/modules/runner.ts +0 -1983
  86. package/src/modules/subagent.ts +0 -277
  87. package/src/modules/validator.ts +0 -700
  88. package/src/providers/anthropic.ts +0 -89
  89. package/src/providers/base.ts +0 -29
  90. package/src/providers/deepseek.ts +0 -83
  91. package/src/providers/gemini.ts +0 -117
  92. package/src/providers/index.ts +0 -78
  93. package/src/providers/minimax.ts +0 -81
  94. package/src/providers/moonshot.ts +0 -82
  95. package/src/providers/ollama.ts +0 -83
  96. package/src/providers/openai.ts +0 -84
  97. package/src/providers/qwen.ts +0 -82
  98. package/src/server/http.ts +0 -316
  99. package/src/server/index.ts +0 -6
  100. package/src/types.ts +0 -599
  101. package/tsconfig.json +0 -17
@@ -1,84 +0,0 @@
1
- /**
2
- * OpenAI Provider - OpenAI API (and compatible APIs)
3
- */
4
-
5
- import { BaseProvider } from './base.js';
6
- import type { InvokeParams, InvokeResult } from '../types.js';
7
-
8
- export class OpenAIProvider extends BaseProvider {
9
- name = 'openai';
10
- private apiKey: string;
11
- private model: string;
12
- private baseUrl: string;
13
-
14
- constructor(apiKey?: string, model = 'gpt-5.2', baseUrl = 'https://api.openai.com/v1') {
15
- super();
16
- this.apiKey = apiKey || process.env.OPENAI_API_KEY || '';
17
- this.model = model;
18
- this.baseUrl = baseUrl;
19
- }
20
-
21
- isConfigured(): boolean {
22
- return !!this.apiKey;
23
- }
24
-
25
- async invoke(params: InvokeParams): Promise<InvokeResult> {
26
- if (!this.isConfigured()) {
27
- throw new Error('OpenAI API key not configured. Set OPENAI_API_KEY environment variable.');
28
- }
29
-
30
- const url = `${this.baseUrl}/chat/completions`;
31
-
32
- const body: Record<string, unknown> = {
33
- model: this.model,
34
- messages: params.messages,
35
- temperature: params.temperature ?? 0.7,
36
- max_tokens: params.maxTokens ?? 4096,
37
- };
38
-
39
- // Add JSON mode if schema provided
40
- if (params.jsonSchema) {
41
- body.response_format = { type: 'json_object' };
42
- // Append schema instruction to last user message
43
- const lastUserIdx = params.messages.findLastIndex(m => m.role === 'user');
44
- if (lastUserIdx >= 0) {
45
- const messages = [...params.messages];
46
- messages[lastUserIdx] = {
47
- ...messages[lastUserIdx],
48
- content: messages[lastUserIdx].content + this.buildJsonPrompt(params.jsonSchema),
49
- };
50
- body.messages = messages;
51
- }
52
- }
53
-
54
- const response = await fetch(url, {
55
- method: 'POST',
56
- headers: {
57
- 'Content-Type': 'application/json',
58
- 'Authorization': `Bearer ${this.apiKey}`,
59
- },
60
- body: JSON.stringify(body),
61
- });
62
-
63
- if (!response.ok) {
64
- const error = await response.text();
65
- throw new Error(`OpenAI API error: ${response.status} - ${error}`);
66
- }
67
-
68
- const data = await response.json() as {
69
- choices?: Array<{ message?: { content?: string } }>;
70
- usage?: { prompt_tokens?: number; completion_tokens?: number; total_tokens?: number };
71
- };
72
-
73
- const content = data.choices?.[0]?.message?.content || '';
74
-
75
- return {
76
- content,
77
- usage: data.usage ? {
78
- promptTokens: data.usage.prompt_tokens || 0,
79
- completionTokens: data.usage.completion_tokens || 0,
80
- totalTokens: data.usage.total_tokens || 0,
81
- } : undefined,
82
- };
83
- }
84
- }
@@ -1,82 +0,0 @@
1
- /**
2
- * Qwen Provider - Alibaba Tongyi Qianwen (通义千问) via DashScope API
3
- */
4
-
5
- import { BaseProvider } from './base.js';
6
- import type { InvokeParams, InvokeResult } from '../types.js';
7
-
8
- export class QwenProvider extends BaseProvider {
9
- name = 'qwen';
10
- private apiKey: string;
11
- private model: string;
12
- private baseUrl = 'https://dashscope.aliyuncs.com/compatible-mode/v1';
13
-
14
- constructor(apiKey?: string, model = 'qwen3-max') {
15
- super();
16
- this.apiKey = apiKey || process.env.DASHSCOPE_API_KEY || process.env.QWEN_API_KEY || '';
17
- this.model = model;
18
- }
19
-
20
- isConfigured(): boolean {
21
- return !!this.apiKey;
22
- }
23
-
24
- async invoke(params: InvokeParams): Promise<InvokeResult> {
25
- if (!this.isConfigured()) {
26
- throw new Error('Qwen API key not configured. Set DASHSCOPE_API_KEY or QWEN_API_KEY environment variable.');
27
- }
28
-
29
- const url = `${this.baseUrl}/chat/completions`;
30
-
31
- const body: Record<string, unknown> = {
32
- model: this.model,
33
- messages: params.messages.map(m => ({ role: m.role, content: m.content })),
34
- temperature: params.temperature ?? 0.7,
35
- max_tokens: params.maxTokens ?? 4096,
36
- };
37
-
38
- // Add JSON mode if schema provided
39
- if (params.jsonSchema) {
40
- body.response_format = { type: 'json_object' };
41
- const lastUserIdx = params.messages.findLastIndex(m => m.role === 'user');
42
- if (lastUserIdx >= 0) {
43
- const messages = [...params.messages];
44
- messages[lastUserIdx] = {
45
- ...messages[lastUserIdx],
46
- content: messages[lastUserIdx].content + this.buildJsonPrompt(params.jsonSchema),
47
- };
48
- body.messages = messages.map(m => ({ role: m.role, content: m.content }));
49
- }
50
- }
51
-
52
- const response = await fetch(url, {
53
- method: 'POST',
54
- headers: {
55
- 'Content-Type': 'application/json',
56
- 'Authorization': `Bearer ${this.apiKey}`,
57
- },
58
- body: JSON.stringify(body),
59
- });
60
-
61
- if (!response.ok) {
62
- const error = await response.text();
63
- throw new Error(`Qwen API error: ${response.status} - ${error}`);
64
- }
65
-
66
- const data = await response.json() as {
67
- choices?: Array<{ message?: { content?: string } }>;
68
- usage?: { prompt_tokens?: number; completion_tokens?: number; total_tokens?: number };
69
- };
70
-
71
- const content = data.choices?.[0]?.message?.content || '';
72
-
73
- return {
74
- content,
75
- usage: data.usage ? {
76
- promptTokens: data.usage.prompt_tokens || 0,
77
- completionTokens: data.usage.completion_tokens || 0,
78
- totalTokens: data.usage.total_tokens || 0,
79
- } : undefined,
80
- };
81
- }
82
- }
@@ -1,316 +0,0 @@
1
- /**
2
- * Cognitive Modules HTTP API Server
3
- *
4
- * Provides RESTful API interface for workflow platform integration.
5
- *
6
- * Start with:
7
- * cog serve --port 8000
8
- *
9
- * Environment variables:
10
- * COGNITIVE_API_KEY - API Key authentication (optional)
11
- * OPENAI_API_KEY, ANTHROPIC_API_KEY, etc. - LLM provider keys
12
- */
13
-
14
- import http from 'node:http';
15
- import { URL } from 'node:url';
16
- import { loadModule, findModule, listModules, getDefaultSearchPaths } from '../modules/loader.js';
17
- import { runModule } from '../modules/runner.js';
18
- import { getProvider } from '../providers/index.js';
19
- import type { CognitiveModule, Provider } from '../types.js';
20
-
21
- // =============================================================================
22
- // Types
23
- // =============================================================================
24
-
25
- interface RunRequest {
26
- module: string;
27
- args: string;
28
- provider?: string;
29
- model?: string;
30
- }
31
-
32
- interface RunResponse {
33
- ok: boolean;
34
- data?: unknown;
35
- meta?: unknown;
36
- error?: string;
37
- module: string;
38
- provider?: string;
39
- }
40
-
41
- interface ModuleInfo {
42
- name: string;
43
- version?: string;
44
- description?: string;
45
- format: string;
46
- path: string;
47
- responsibility?: string;
48
- tier?: string;
49
- }
50
-
51
- // =============================================================================
52
- // Helpers
53
- // =============================================================================
54
-
55
- function jsonResponse(res: http.ServerResponse, status: number, data: unknown): void {
56
- res.writeHead(status, {
57
- 'Content-Type': 'application/json',
58
- 'Access-Control-Allow-Origin': '*',
59
- 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
60
- 'Access-Control-Allow-Headers': 'Content-Type, Authorization',
61
- });
62
- res.end(JSON.stringify(data, null, 2));
63
- }
64
-
65
- function parseBody(req: http.IncomingMessage): Promise<string> {
66
- return new Promise((resolve, reject) => {
67
- let body = '';
68
- req.on('data', (chunk) => (body += chunk));
69
- req.on('end', () => resolve(body));
70
- req.on('error', reject);
71
- });
72
- }
73
-
74
- function verifyApiKey(req: http.IncomingMessage): boolean {
75
- const expectedKey = process.env.COGNITIVE_API_KEY;
76
- if (!expectedKey) return true; // No auth required
77
-
78
- const authHeader = req.headers.authorization;
79
- if (!authHeader) return false;
80
-
81
- const token = authHeader.startsWith('Bearer ') ? authHeader.slice(7) : authHeader;
82
- return token === expectedKey;
83
- }
84
-
85
- // =============================================================================
86
- // Request Handlers
87
- // =============================================================================
88
-
89
- async function handleRoot(res: http.ServerResponse): Promise<void> {
90
- jsonResponse(res, 200, {
91
- name: 'Cognitive Modules API',
92
- version: '1.3.0',
93
- docs: '/docs',
94
- endpoints: {
95
- run: 'POST /run',
96
- modules: 'GET /modules',
97
- module_info: 'GET /modules/{name}',
98
- health: 'GET /health',
99
- },
100
- });
101
- }
102
-
103
- async function handleHealth(res: http.ServerResponse): Promise<void> {
104
- const providers = {
105
- openai: Boolean(process.env.OPENAI_API_KEY),
106
- anthropic: Boolean(process.env.ANTHROPIC_API_KEY),
107
- minimax: Boolean(process.env.MINIMAX_API_KEY),
108
- deepseek: Boolean(process.env.DEEPSEEK_API_KEY),
109
- gemini: Boolean(process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY),
110
- qwen: Boolean(process.env.QWEN_API_KEY || process.env.DASHSCOPE_API_KEY),
111
- };
112
-
113
- jsonResponse(res, 200, {
114
- status: 'healthy',
115
- version: '1.3.0',
116
- providers,
117
- });
118
- }
119
-
120
- async function handleModules(
121
- res: http.ServerResponse,
122
- searchPaths: string[]
123
- ): Promise<void> {
124
- const modules = await listModules(searchPaths);
125
-
126
- const moduleInfos: ModuleInfo[] = modules.map((m) => ({
127
- name: m.name,
128
- version: m.version,
129
- description: m.responsibility,
130
- format: m.format,
131
- path: m.location,
132
- responsibility: m.responsibility,
133
- tier: m.tier,
134
- }));
135
-
136
- jsonResponse(res, 200, {
137
- modules: moduleInfos,
138
- count: moduleInfos.length,
139
- });
140
- }
141
-
142
- async function handleModuleInfo(
143
- res: http.ServerResponse,
144
- moduleName: string,
145
- searchPaths: string[]
146
- ): Promise<void> {
147
- const moduleData = await findModule(moduleName, searchPaths);
148
-
149
- if (!moduleData) {
150
- jsonResponse(res, 404, { error: `Module '${moduleName}' not found` });
151
- return;
152
- }
153
-
154
- jsonResponse(res, 200, {
155
- name: moduleData.name,
156
- version: moduleData.version,
157
- description: moduleData.responsibility,
158
- format: moduleData.format,
159
- path: moduleData.location,
160
- responsibility: moduleData.responsibility,
161
- tier: moduleData.tier,
162
- inputSchema: moduleData.inputSchema,
163
- outputSchema: moduleData.outputSchema,
164
- });
165
- }
166
-
167
- async function handleRun(
168
- req: http.IncomingMessage,
169
- res: http.ServerResponse,
170
- searchPaths: string[]
171
- ): Promise<void> {
172
- // Verify API key
173
- if (!verifyApiKey(req)) {
174
- jsonResponse(res, 401, {
175
- error: 'Missing or invalid API Key. Use header: Authorization: Bearer <your-api-key>',
176
- });
177
- return;
178
- }
179
-
180
- // Parse request body
181
- let request: RunRequest;
182
- try {
183
- const body = await parseBody(req);
184
- request = JSON.parse(body);
185
- } catch {
186
- jsonResponse(res, 400, { error: 'Invalid JSON body' });
187
- return;
188
- }
189
-
190
- // Validate request
191
- if (!request.module || !request.args) {
192
- jsonResponse(res, 400, { error: 'Missing required fields: module, args' });
193
- return;
194
- }
195
-
196
- // Find module
197
- const moduleData = await findModule(request.module, searchPaths);
198
- if (!moduleData) {
199
- jsonResponse(res, 404, { error: `Module '${request.module}' not found` });
200
- return;
201
- }
202
-
203
- try {
204
- // Create provider
205
- const provider = getProvider(request.provider, request.model);
206
-
207
- // Run module
208
- const result = await runModule(moduleData, provider, {
209
- input: { query: request.args, code: request.args },
210
- useV22: true,
211
- });
212
-
213
- const response: RunResponse = {
214
- ok: result.ok,
215
- module: request.module,
216
- provider: request.provider || process.env.LLM_PROVIDER || 'openai',
217
- };
218
-
219
- if (result.ok) {
220
- if ('meta' in result) response.meta = result.meta;
221
- if ('data' in result) response.data = result.data;
222
- } else {
223
- if ('error' in result) response.error = result.error?.message;
224
- }
225
-
226
- jsonResponse(res, 200, response);
227
- } catch (error) {
228
- jsonResponse(res, 500, {
229
- ok: false,
230
- error: error instanceof Error ? error.message : String(error),
231
- module: request.module,
232
- });
233
- }
234
- }
235
-
236
- // =============================================================================
237
- // Server
238
- // =============================================================================
239
-
240
- export interface ServeOptions {
241
- host?: string;
242
- port?: number;
243
- cwd?: string;
244
- }
245
-
246
- export function createServer(options: ServeOptions = {}): http.Server {
247
- const { cwd = process.cwd() } = options;
248
- const searchPaths = getDefaultSearchPaths(cwd);
249
-
250
- const server = http.createServer(async (req, res) => {
251
- const url = new URL(req.url || '/', `http://${req.headers.host}`);
252
- const path = url.pathname;
253
- const method = req.method?.toUpperCase();
254
-
255
- // Handle CORS preflight
256
- if (method === 'OPTIONS') {
257
- res.writeHead(204, {
258
- 'Access-Control-Allow-Origin': '*',
259
- 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
260
- 'Access-Control-Allow-Headers': 'Content-Type, Authorization',
261
- });
262
- res.end();
263
- return;
264
- }
265
-
266
- try {
267
- // Route requests
268
- if (path === '/' && method === 'GET') {
269
- await handleRoot(res);
270
- } else if (path === '/health' && method === 'GET') {
271
- await handleHealth(res);
272
- } else if (path === '/modules' && method === 'GET') {
273
- await handleModules(res, searchPaths);
274
- } else if (path.startsWith('/modules/') && method === 'GET') {
275
- const moduleName = path.slice('/modules/'.length);
276
- await handleModuleInfo(res, moduleName, searchPaths);
277
- } else if (path === '/run' && method === 'POST') {
278
- await handleRun(req, res, searchPaths);
279
- } else {
280
- jsonResponse(res, 404, { error: 'Not found' });
281
- }
282
- } catch (error) {
283
- console.error('Server error:', error);
284
- jsonResponse(res, 500, {
285
- error: error instanceof Error ? error.message : 'Internal server error',
286
- });
287
- }
288
- });
289
-
290
- return server;
291
- }
292
-
293
- export async function serve(options: ServeOptions = {}): Promise<void> {
294
- const { host = '0.0.0.0', port = 8000 } = options;
295
-
296
- const server = createServer(options);
297
-
298
- return new Promise((resolve, reject) => {
299
- server.on('error', reject);
300
- server.listen(port, host, () => {
301
- console.log(`Cognitive Modules HTTP Server running at http://${host}:${port}`);
302
- console.log('Endpoints:');
303
- console.log(' GET / - API info');
304
- console.log(' GET /health - Health check');
305
- console.log(' GET /modules - List modules');
306
- console.log(' GET /modules/:name - Module info');
307
- console.log(' POST /run - Run module');
308
- resolve();
309
- });
310
- });
311
- }
312
-
313
- // Allow running directly
314
- if (import.meta.url === `file://${process.argv[1]}`) {
315
- serve().catch(console.error);
316
- }
@@ -1,6 +0,0 @@
1
- /**
2
- * Server - Re-export all server functionality
3
- */
4
-
5
- export { serve, createServer } from './http.js';
6
- export type { ServeOptions } from './http.js';