omnibiofex 4.1.0 → 4.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnibiofex",
3
- "version": "4.1.0",
3
+ "version": "4.2.0",
4
4
  "description": "OmniBioFex X - The Autonomous Research Operating System",
5
5
  "main": "bin/obx",
6
6
  "bin": {
@@ -13,54 +13,34 @@ if (!fs.existsSync(DIAGRAMS_DIR)) {
13
13
  fs.mkdirSync(DIAGRAMS_DIR, { recursive: true });
14
14
  }
15
15
 
16
- // Diagram styles
16
+ // Diagram styles with costs
17
17
  const STYLES = {
18
- minimal: {
19
- name: 'Minimal',
20
- cost: 40,
21
- description: 'Clean, simple flowchart'
22
- },
23
- detailed: {
24
- name: 'Detailed',
25
- cost: 80,
26
- description: 'Comprehensive ecosystem with all components'
27
- },
28
- flowchart: {
29
- name: 'Flowchart',
30
- cost: 60,
31
- description: 'Step-by-step process flow'
32
- },
33
- network: {
34
- name: 'Network',
35
- cost: 70,
36
- description: 'Interconnected nodes and relationships'
37
- }
18
+ minimal: { name: 'Minimal', cost: 50, description: 'Clean, simple flowchart' },
19
+ detailed: { name: 'Detailed', cost: 80, description: 'Comprehensive ecosystem' },
20
+ flowchart: { name: 'Flowchart', cost: 60, description: 'Step-by-step process' },
21
+ network: { name: 'Network', cost: 70, description: 'Interconnected nodes' }
38
22
  };
39
23
 
40
- // Generate ASCII box
41
- function box(text, width = 60) {
42
- const padding = Math.max(0, width - text.length - 2);
43
- const leftPad = Math.floor(padding / 2);
44
- const rightPad = padding - leftPad;
45
- return `║ ${' '.repeat(leftPad)}${text}${' '.repeat(rightPad)} ║`;
46
- }
47
-
48
24
  // Generate ASCII banner
49
25
  function banner(title, width = 80) {
50
26
  const top = `╔${'═'.repeat(width)}╗`;
51
27
  const bottom = `╚${'═'.repeat(width)}╝`;
52
- const content = box(title, width);
28
+ const padding = Math.max(0, width - title.length - 2);
29
+ const leftPad = Math.floor(padding / 2);
30
+ const rightPad = padding - leftPad;
31
+ const content = `║ ${' '.repeat(leftPad)}${title}${' '.repeat(rightPad)} ║`;
53
32
  return `${top}\n${content}\n${bottom}`;
54
33
  }
55
34
 
56
35
  // Generate node box
57
36
  function node(text, width = 20) {
58
- const top = `┌${'─'.repeat(width)}┐`;
59
- const bottom = `└${'─'.repeat(width)}┘`;
60
- const padding = Math.max(0, width - text.length - 2);
37
+ const safeText = text.substring(0, width - 2);
38
+ const padding = Math.max(0, width - safeText.length - 2);
61
39
  const leftPad = Math.floor(padding / 2);
62
40
  const rightPad = padding - leftPad;
63
- const content = `│ ${' '.repeat(leftPad)}${text}${' '.repeat(rightPad)} │`;
41
+ const top = `┌${''.repeat(width)}┐`;
42
+ const bottom = `└${'─'.repeat(width)}┘`;
43
+ const content = `│ ${' '.repeat(leftPad)}${safeText}${' '.repeat(rightPad)} │`;
64
44
  return `${top}\n${content}\n${bottom}`;
65
45
  }
66
46
 
@@ -75,27 +55,8 @@ function arrow(direction = 'down') {
75
55
  }
76
56
  }
77
57
 
78
- // Generate minimal diagram
79
- function generateMinimalDiagram(topic, components) {
80
- const width = 60;
81
- let diagram = banner(topic.toUpperCase(), width) + '\n\n';
82
-
83
- // Problem box
84
- diagram += `${' '.repeat(20)}${node('Problem', 20)}\n`;
85
- diagram += `${' '.repeat(29)}${arrow('down')}\n`;
86
-
87
- // Three branches
88
- diagram += `${' '.repeat(10)}${node('Research', 20)}\n`;
89
- diagram += `${' '.repeat(19)}${arrow('down')}\n`;
90
- diagram += `${' '.repeat(10)}${node('Analysis', 20)}\n`;
91
- diagram += `${' '.repeat(19)}${arrow('down')}\n`;
92
- diagram += `${' '.repeat(10)}${node('Solution', 20)}\n`;
93
-
94
- return diagram;
95
- }
96
-
97
58
  // Generate detailed diagram
98
- function generateDetailedDiagram(topic, components) {
59
+ function generateDetailedDiagram(topic, data) {
99
60
  const width = 80;
100
61
  let diagram = banner(`${topic.toUpperCase()} RESEARCH ECOSYSTEM`, width) + '\n\n';
101
62
 
@@ -104,7 +65,8 @@ function generateDetailedDiagram(topic, components) {
104
65
  diagram += `${' '.repeat(37)}${arrow('down')}\n\n`;
105
66
 
106
67
  // Three input sources
107
- diagram += `${' '.repeat(5)}${node('Literature', 18)} ${node('Data', 18)} ${node('Theory', 18)}\n`;
68
+ const sources = data.components?.slice(0, 3) || ['Literature', 'Data', 'Theory'];
69
+ diagram += `${' '.repeat(5)}${node(sources[0] || 'Literature', 18)} ${node(sources[1] || 'Data', 18)} ${node(sources[2] || 'Theory', 18)}\n`;
108
70
  diagram += `${' '.repeat(14)}\\ | /\n`;
109
71
  diagram += `${' '.repeat(15)}\\ | /\n`;
110
72
  diagram += `${' '.repeat(16)}\\ | /\n`;
@@ -117,7 +79,8 @@ function generateDetailedDiagram(topic, components) {
117
79
  diagram += `${' '.repeat(32)}${arrow('down')}\n\n`;
118
80
 
119
81
  // Four analysis types
120
- diagram += `${node('Statistical', 14)} ${node('Qualitative', 14)} ${node('Comparative', 14)} ${node('Predictive', 14)}\n`;
82
+ const methods = data.methods?.slice(0, 4) || ['Statistical', 'Qualitative', 'Comparative', 'Predictive'];
83
+ diagram += `${node(methods[0], 14)} ${node(methods[1], 14)} ${node(methods[2], 14)} ${node(methods[3], 14)}\n`;
121
84
  diagram += `${' '.repeat(7)}\\ | | /\n`;
122
85
  diagram += `${' '.repeat(8)}\\ | | /\n`;
123
86
  diagram += `${' '.repeat(9)}\\ | | /\n`;
@@ -130,45 +93,58 @@ function generateDetailedDiagram(topic, components) {
130
93
  diagram += `${' '.repeat(32)}${arrow('down')}\n\n`;
131
94
 
132
95
  // Three outputs
133
- diagram += `${node('Publication', 18)} ${node('Implementation', 18)} ${node('Future Work', 18)}\n`;
96
+ const outputs = data.outputs?.slice(0, 3) || ['Publication', 'Implementation', 'Future Work'];
97
+ diagram += `${node(outputs[0], 18)} ${node(outputs[1], 18)} ${node(outputs[2], 18)}\n`;
98
+
99
+ return diagram;
100
+ }
101
+
102
+ // Generate minimal diagram
103
+ function generateMinimalDiagram(topic, data) {
104
+ const width = 60;
105
+ let diagram = banner(topic.toUpperCase(), width) + '\n\n';
106
+
107
+ diagram += `${' '.repeat(20)}${node('Problem', 20)}\n`;
108
+ diagram += `${' '.repeat(29)}${arrow('down')}\n`;
109
+ diagram += `${' '.repeat(10)}${node('Research', 20)}\n`;
110
+ diagram += `${' '.repeat(19)}${arrow('down')}\n`;
111
+ diagram += `${' '.repeat(10)}${node('Analysis', 20)}\n`;
112
+ diagram += `${' '.repeat(19)}${arrow('down')}\n`;
113
+ diagram += `${' '.repeat(10)}${node('Solution', 20)}\n`;
134
114
 
135
115
  return diagram;
136
116
  }
137
117
 
138
118
  // Generate flowchart diagram
139
- function generateFlowchartDiagram(topic, steps) {
119
+ function generateFlowchartDiagram(topic, data) {
140
120
  const width = 60;
121
+ const steps = data.steps?.length > 0 ? data.steps : ['Research', 'Analysis', 'Implementation'];
141
122
  let diagram = banner(`${topic.toUpperCase()} WORKFLOW`, width) + '\n\n';
142
123
 
143
- let currentStep = 1;
144
- for (const step of steps) {
145
- const stepText = `Step ${currentStep}: ${step}`;
124
+ steps.forEach((step, i) => {
125
+ const stepText = `Step ${i + 1}: ${step}`;
146
126
  diagram += `${' '.repeat(15)}${node(stepText, 45)}\n`;
147
- if (currentStep < steps.length) {
127
+ if (i < steps.length - 1) {
148
128
  diagram += `${' '.repeat(37)}${arrow('down')}\n`;
149
129
  }
150
- currentStep++;
151
- }
130
+ });
152
131
 
153
132
  diagram += `\n${' '.repeat(25)}${node('✓ Complete', 20)}\n`;
154
-
155
133
  return diagram;
156
134
  }
157
135
 
158
136
  // Generate network diagram
159
- function generateNetworkDiagram(topic, nodes) {
137
+ function generateNetworkDiagram(topic, data) {
160
138
  const width = 70;
139
+ const nodes = data.nodes?.slice(0, 3) || ['Component A', 'Component B', 'Component C'];
161
140
  let diagram = banner(`${topic.toUpperCase()} NETWORK`, width) + '\n\n';
162
141
 
163
- // Central node
164
142
  diagram += `${' '.repeat(25)}${node(topic, 25)}\n`;
165
143
  diagram += `${' '.repeat(37)}|\n`;
166
144
  diagram += `${' '.repeat(20)}┌────────┼────────┐\n`;
167
145
  diagram += `${' '.repeat(20)}│ │ │\n`;
168
146
  diagram += `${' '.repeat(20)}▼ ▼ ▼\n`;
169
-
170
- // Three connected nodes
171
- diagram += `${node(nodes[0] || 'Node A', 18)} ${node(nodes[1] || 'Node B', 18)} ${node(nodes[2] || 'Node C', 18)}\n`;
147
+ diagram += `${node(nodes[0], 18)} ${node(nodes[1], 18)} ${node(nodes[2], 18)}\n`;
172
148
  diagram += `${' '.repeat(9)}│ │ │\n`;
173
149
  diagram += `${' '.repeat(9)}└────────┼────────┘\n`;
174
150
  diagram += `${' '.repeat(18)}▼\n`;
@@ -177,24 +153,6 @@ function generateNetworkDiagram(topic, nodes) {
177
153
  return diagram;
178
154
  }
179
155
 
180
- // Generate Mermaid diagram for markdown
181
- function generateMermaidDiagram(topic, components, style) {
182
- let mermaid = '```mermaid\n';
183
- mermaid += 'graph TD\n';
184
- mermaid += ` A[${topic}] --> B[Research Phase]\n`;
185
- mermaid += ` B --> C[Analysis Phase]\n`;
186
- mermaid += ` C --> D[Output Phase]\n`;
187
-
188
- if (components && components.length > 0) {
189
- components.forEach((comp, i) => {
190
- mermaid += ` B --> E${i}[${comp}]\n`;
191
- });
192
- }
193
-
194
- mermaid += '```';
195
- return mermaid;
196
- }
197
-
198
156
  // Main diagram command
199
157
  async function diagram(topic, options = {}) {
200
158
  if (!isAuthenticated()) {
@@ -205,14 +163,13 @@ async function diagram(topic, options = {}) {
205
163
 
206
164
  if (!topic) {
207
165
  console.error(chalk.red('✗ Please provide a topic'));
208
- console.log(chalk.gray('Usage: obx diagram "topic" [--style minimal|detailed|flowchart|network] [--save] [--publish]'));
166
+ console.log(chalk.gray('Usage: obx diagram "topic" [--style minimal|detailed|flowchart|network] [--save]'));
209
167
  process.exit(1);
210
168
  return;
211
169
  }
212
170
 
213
171
  const style = options.style || 'detailed';
214
172
  const save = options.save || false;
215
- const publish = options.publish || false;
216
173
  const cost = STYLES[style]?.cost || 80;
217
174
 
218
175
  console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════'));
@@ -229,10 +186,10 @@ async function diagram(topic, options = {}) {
229
186
  try {
230
187
  const token = await getAuthToken();
231
188
 
232
- // Call AI backend to get components/structure
233
189
  spinner.update('Analyzing topic with AI');
234
190
  await sleep(500);
235
191
 
192
+ // ✅ FIX: Use DEEP_RESEARCH task type (already supported by backend)
236
193
  const response = await fetch(BACKEND_URL, {
237
194
  method: 'POST',
238
195
  headers: {
@@ -240,22 +197,27 @@ async function diagram(topic, options = {}) {
240
197
  'Authorization': `Bearer ${token}`
241
198
  },
242
199
  body: JSON.stringify({
243
- taskType: 'RESEARCH_DIAGRAM',
244
- message: `Generate a structured breakdown of "${topic}" for an ASCII diagram. Return a JSON object with:
245
- {
246
- "components": ["component1", "component2", ...],
247
- "steps": ["step1", "step2", ...],
248
- "nodes": ["node1", "node2", "node3"],
249
- "description": "brief description"
250
- }
251
-
252
- Only return valid JSON, no other text.`,
200
+ taskType: 'DEEP_RESEARCH', // ← Use existing task type
201
+ message: `Generate a structured breakdown of "${topic}" for an ASCII diagram.
202
+
203
+ Return ONLY a valid JSON object with this exact structure (no other text):
204
+ {
205
+ "components": ["component1", "component2", "component3", "component4"],
206
+ "methods": ["method1", "method2", "method3", "method4"],
207
+ "steps": ["step1", "step2", "step3", "step4", "step5"],
208
+ "nodes": ["node1", "node2", "node3"],
209
+ "outputs": ["output1", "output2", "output3"]
210
+ }
211
+
212
+ Make the components, methods, steps, nodes, and outputs specific to "${topic}".
213
+ Return ONLY the JSON object, nothing else.`,
253
214
  model: 'deep'
254
215
  })
255
216
  });
256
217
 
257
218
  if (!response.ok) {
258
- throw new Error(`Backend returned ${response.status}`);
219
+ const errorText = await response.text();
220
+ throw new Error(`Backend returned ${response.status}: ${errorText.substring(0, 100)}`);
259
221
  }
260
222
 
261
223
  spinner.update('Rendering ASCII art');
@@ -263,11 +225,20 @@ async function diagram(topic, options = {}) {
263
225
 
264
226
  const data = await response.json();
265
227
 
266
- // Parse AI response
267
- let aiData = { components: [], steps: [], nodes: [] };
228
+ // Parse AI response - extract JSON from the response
229
+ let aiData = {
230
+ components: [],
231
+ methods: [],
232
+ steps: [],
233
+ nodes: [],
234
+ outputs: []
235
+ };
236
+
268
237
  try {
269
- // Try to extract JSON from response
270
- const jsonMatch = data.response.match(/\{[\s\S]*\}/);
238
+ // Try to find JSON in the response
239
+ const responseText = data.response || '';
240
+ const jsonMatch = responseText.match(/\{[\s\S]*\}/);
241
+
271
242
  if (jsonMatch) {
272
243
  aiData = JSON.parse(jsonMatch[0]);
273
244
  }
@@ -279,30 +250,27 @@ async function diagram(topic, options = {}) {
279
250
  let asciiDiagram;
280
251
  switch (style) {
281
252
  case 'minimal':
282
- asciiDiagram = generateMinimalDiagram(topic, aiData.components);
253
+ asciiDiagram = generateMinimalDiagram(topic, aiData);
283
254
  break;
284
255
  case 'flowchart':
285
- asciiDiagram = generateFlowchartDiagram(topic, aiData.steps.length > 0 ? aiData.steps : ['Research', 'Analysis', 'Implementation']);
256
+ asciiDiagram = generateFlowchartDiagram(topic, aiData);
286
257
  break;
287
258
  case 'network':
288
- asciiDiagram = generateNetworkDiagram(topic, aiData.nodes);
259
+ asciiDiagram = generateNetworkDiagram(topic, aiData);
289
260
  break;
290
261
  case 'detailed':
291
262
  default:
292
- asciiDiagram = generateDetailedDiagram(topic, aiData.components);
263
+ asciiDiagram = generateDetailedDiagram(topic, aiData);
293
264
  break;
294
265
  }
295
266
 
296
- // Generate Mermaid version
297
- const mermaidDiagram = generateMermaidDiagram(topic, aiData.components, style);
298
-
299
267
  spinner.succeed('✓ Diagram generated');
300
268
 
301
269
  // Display diagram
302
270
  console.log('\n' + chalk.cyan(asciiDiagram) + '\n');
303
271
 
304
272
  // Save if requested
305
- if (save || publish) {
273
+ if (save) {
306
274
  const timestamp = Date.now();
307
275
  const safeTopic = topic.toLowerCase().replace(/[^a-z0-9]+/g, '-').substring(0, 50);
308
276
 
@@ -310,22 +278,14 @@ async function diagram(topic, options = {}) {
310
278
  const txtFilename = `${safeTopic}-${timestamp}.txt`;
311
279
  const txtPath = path.join(DIAGRAMS_DIR, txtFilename);
312
280
  fs.writeFileSync(txtPath, asciiDiagram, 'utf8');
313
- console.log(chalk.green(` 💾 Saved ASCII: ${txtPath}`));
281
+ console.log(chalk.green(` 💾 Saved: ${txtPath}`));
314
282
 
315
- // Save Markdown version with Mermaid
283
+ // Save Markdown version
316
284
  const mdFilename = `${safeTopic}-${timestamp}.md`;
317
285
  const mdPath = path.join(DIAGRAMS_DIR, mdFilename);
318
- const mdContent = `# ${topic} Research Diagram\n\n**Style:** ${STYLES[style].name}\n**Generated:** ${new Date().toLocaleString()}\n\n## ASCII Diagram\n\n\`\`\`\n${asciiDiagram}\n\`\`\`\n\n## Mermaid Version\n\n${mermaidDiagram}\n`;
286
+ const mdContent = `# ${topic} Research Diagram\n\n**Style:** ${STYLES[style].name}\n**Generated:** ${new Date().toLocaleString()}\n\n\`\`\`\n${asciiDiagram}\n\`\`\`\n`;
319
287
  fs.writeFileSync(mdPath, mdContent, 'utf8');
320
- console.log(chalk.green(` 💾 Saved Markdown: ${mdPath}`));
321
- }
322
-
323
- // Publish if requested
324
- if (publish) {
325
- console.log(chalk.yellow('\n 📤 To publish this diagram as research:'));
326
- console.log(chalk.gray(' 1. Review the saved markdown file'));
327
- console.log(chalk.gray(' 2. Run: obx publish'));
328
- console.log(chalk.gray(' 3. Select the diagram from your missions'));
288
+ console.log(chalk.green(` 💾 Saved: ${mdPath}`));
329
289
  }
330
290
 
331
291
  console.log(chalk.hex('#F24E1E')('\n═══════════════════════════════════════════════════════════\n'));
@@ -333,6 +293,11 @@ async function diagram(topic, options = {}) {
333
293
  } catch (error) {
334
294
  spinner.fail('Failed to generate diagram');
335
295
  console.error(chalk.red(error.message));
296
+
297
+ if (error.message.includes('402') || error.message.includes('Insufficient')) {
298
+ console.log(chalk.yellow('\n 💡 You need more RCC credits. Run: obx buy'));
299
+ }
300
+
336
301
  process.exit(1);
337
302
  }
338
303
  }