50c 3.3.0 → 3.7.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/bin/50c.js +207 -2
- package/lib/invent-ui.js +717 -0
- package/lib/mcp-tv.js +1015 -0
- package/lib/team.js +47 -5
- package/package.json +1 -1
package/bin/50c.js
CHANGED
|
@@ -124,6 +124,8 @@ const TOOL_COMMANDS = {
|
|
|
124
124
|
'chat': { tool: 'ide_conversation', special: 'chat' },
|
|
125
125
|
'refocus': { tool: 'llm_refocus', special: 'refocus' },
|
|
126
126
|
'invent': { tool: 'auto_invent', special: 'invent', cost: '$2.00' },
|
|
127
|
+
'invent-ui': { tool: 'auto_invent', special: 'invent-ui', cost: '$2.00' },
|
|
128
|
+
'tv': { tool: null, special: 'mcp-tv', cost: 'FREE' },
|
|
127
129
|
};
|
|
128
130
|
|
|
129
131
|
// Route command
|
|
@@ -521,6 +523,62 @@ async function runToolCommand(cmd, args) {
|
|
|
521
523
|
return;
|
|
522
524
|
}
|
|
523
525
|
|
|
526
|
+
// INVENT-UI: Visual invention pipeline with browser UI
|
|
527
|
+
if (spec.special === 'invent-ui') {
|
|
528
|
+
let problem = '';
|
|
529
|
+
let rigor = 'deep';
|
|
530
|
+
let domain = 'code';
|
|
531
|
+
|
|
532
|
+
for (const arg of args) {
|
|
533
|
+
if (arg.startsWith('--rigor=')) rigor = arg.split('=')[1];
|
|
534
|
+
else if (arg.startsWith('--domain=')) domain = arg.split('=')[1];
|
|
535
|
+
else if (!arg.startsWith('--')) problem += (problem ? ' ' : '') + arg;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
if (!problem) {
|
|
539
|
+
console.error('Usage: 50c invent-ui "problem" [--rigor=deep] [--domain=math]');
|
|
540
|
+
console.error('Opens a browser window with real-time swarm visualization.');
|
|
541
|
+
process.exit(1);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
const { runInventWithUI } = require('../lib/invent-ui.js');
|
|
545
|
+
await runInventWithUI(problem, { domain, rigor });
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// MCP-TV: Universal MCP Visualization Platform (FREE)
|
|
550
|
+
if (spec.special === 'mcp-tv') {
|
|
551
|
+
let port = 50888;
|
|
552
|
+
let noOpen = false;
|
|
553
|
+
|
|
554
|
+
for (const arg of args) {
|
|
555
|
+
if (arg.startsWith('--port=')) port = parseInt(arg.split('=')[1]);
|
|
556
|
+
if (arg === '--no-open') noOpen = true;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
const { createServer } = require('../lib/mcp-tv.js');
|
|
560
|
+
const { spawn } = require('child_process');
|
|
561
|
+
|
|
562
|
+
createServer(port);
|
|
563
|
+
|
|
564
|
+
if (!noOpen) {
|
|
565
|
+
setTimeout(() => {
|
|
566
|
+
const url = `http://localhost:${port}`;
|
|
567
|
+
const platform = process.platform;
|
|
568
|
+
if (platform === 'win32') {
|
|
569
|
+
spawn('cmd', ['/c', 'start', url], { detached: true, stdio: 'ignore' }).unref();
|
|
570
|
+
} else if (platform === 'darwin') {
|
|
571
|
+
spawn('open', [url], { detached: true, stdio: 'ignore' }).unref();
|
|
572
|
+
} else {
|
|
573
|
+
spawn('xdg-open', [url], { detached: true, stdio: 'ignore' }).unref();
|
|
574
|
+
}
|
|
575
|
+
}, 500);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// Keep process alive
|
|
579
|
+
return new Promise(() => {});
|
|
580
|
+
}
|
|
581
|
+
|
|
524
582
|
// INVENT: Enterprise invention pipeline
|
|
525
583
|
if (spec.special === 'invent') {
|
|
526
584
|
// Parse args: 50c invent "problem" --rigor=deep --domain=math --constraint="must be fast"
|
|
@@ -769,8 +827,11 @@ const LOCAL_TOOLS = [
|
|
|
769
827
|
{ name: "team_chain", description: "50c Team: Chain multiple tools together. Output flows via $prev placeholder.", inputSchema: { type: "object", properties: { steps: { type: "array", description: "Array of {tool, args} - use $prev for previous result", items: { type: "object" } }, input: { type: "string", description: "Initial input (optional)" } }, required: ["steps"] } },
|
|
770
828
|
{ name: "pre_publish", description: "Pre-publish verification. Thorough checks before npm/github/arxiv/medical publish. Profiles: npm, github, arxiv, medical, science, math. Uses AI tools (bCalc, genius+, web_search) for academic verification. FREE.", inputSchema: { type: "object", properties: { profile: { type: "string", description: "Verification profile: npm, github, arxiv, medical, science, math", enum: ["npm", "github", "arxiv", "medical", "science", "math"] }, cwd: { type: "string", description: "Directory to check (default: current)" }, save_receipt: { type: "boolean", description: "Save receipt as markdown file" } } } },
|
|
771
829
|
|
|
772
|
-
// ENTERPRISE PRESET - Auto-Invent Swarm Pipeline
|
|
773
|
-
{ name: "auto_invent", description: "
|
|
830
|
+
// ENTERPRISE PRESET - Auto-Invent Swarm Pipeline ($2.00)
|
|
831
|
+
{ name: "auto_invent", description: "ENTERPRISE ($2.00): Full invention pipeline. Chains mind_opener → idea_fold → bcalc → genius_plus → compute → cvi_verify. Produces provable, verified solutions. Requires Enterprise tier.", inputSchema: { type: "object", properties: { problem: { type: "string", description: "Problem or hypothesis to solve/prove" }, constraints: { type: "array", items: { type: "string" }, description: "Hard constraints the solution must satisfy" }, domain: { type: "string", description: "Domain hint: math, physics, engineering, business, code", enum: ["math", "physics", "engineering", "business", "code"] }, rigor: { type: "string", description: "Rigor level: fast, standard, deep, exhaustive (all $2.00)", enum: ["fast", "standard", "deep", "exhaustive"], default: "deep" } }, required: ["problem"] } },
|
|
832
|
+
|
|
833
|
+
// PROGRAMMATIC INVENTION - JSON-defined executable pipeline (ENTERPRISE $2.00)
|
|
834
|
+
{ name: "invent_program", description: "ENTERPRISE ($2.00): Execute a JSON-defined invention program in one shot. Steps: generate/compute (Python), assert (verify), call (50c tool), return. All steps compile to single compute execution. Requires Enterprise tier.", inputSchema: { type: "object", properties: { program: { type: "object", description: "JSON program with 'problem' and 'steps' array", properties: { problem: { type: "string" }, steps: { type: "array", items: { type: "object", properties: { id: { type: "string" }, action: { type: "string", enum: ["generate", "compute", "assert", "call", "return"] }, code: { type: "string" }, tool: { type: "string" }, args: { type: "object" }, depends: { type: "array", items: { type: "string" } } }, required: ["id", "action"] } } }, required: ["problem", "steps"] } }, required: ["program"] } },
|
|
774
835
|
];
|
|
775
836
|
|
|
776
837
|
/**
|
|
@@ -794,6 +855,127 @@ const LOCAL_TOOLS = [
|
|
|
794
855
|
*
|
|
795
856
|
* Cost: $2.00 flat for full invention pipeline
|
|
796
857
|
*/
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* INVENT_PROGRAM: JSON-defined Executable Invention Pipeline
|
|
861
|
+
* Enterprise-only ($2.00/request) - programmatic multi-step invention
|
|
862
|
+
*
|
|
863
|
+
* Actions:
|
|
864
|
+
* - generate: Create data/variables (Python code in compute sandbox)
|
|
865
|
+
* - compute: Calculate/transform (Python code)
|
|
866
|
+
* - assert: Verify condition (must return truthy or throws)
|
|
867
|
+
* - call: Invoke a 50c tool (genius, bcalc, hints, etc.)
|
|
868
|
+
* - return: Final output
|
|
869
|
+
*
|
|
870
|
+
* GATED: Requires Enterprise tier + $2.00 balance
|
|
871
|
+
*/
|
|
872
|
+
async function inventProgram(args) {
|
|
873
|
+
const { program } = args;
|
|
874
|
+
const startTime = Date.now();
|
|
875
|
+
|
|
876
|
+
if (!program || !program.problem || !program.steps) {
|
|
877
|
+
return { ok: false, error: 'Invalid program: must have "problem" and "steps" array' };
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
const results = {
|
|
881
|
+
ok: true,
|
|
882
|
+
problem: program.problem,
|
|
883
|
+
steps_completed: 0,
|
|
884
|
+
steps_total: program.steps.length,
|
|
885
|
+
outputs: {},
|
|
886
|
+
assertions: [],
|
|
887
|
+
tool_calls: [],
|
|
888
|
+
final_result: null,
|
|
889
|
+
cost: '$2.00',
|
|
890
|
+
tier_required: 'enterprise'
|
|
891
|
+
};
|
|
892
|
+
|
|
893
|
+
// Build execution context for Python code
|
|
894
|
+
let pythonContext = `
|
|
895
|
+
import json, math, re, itertools, functools, collections
|
|
896
|
+
from decimal import Decimal, getcontext
|
|
897
|
+
getcontext().prec = 100
|
|
898
|
+
|
|
899
|
+
# Shared context between steps
|
|
900
|
+
_ctx = {}
|
|
901
|
+
_results = {}
|
|
902
|
+
|
|
903
|
+
`;
|
|
904
|
+
|
|
905
|
+
// Execute steps sequentially
|
|
906
|
+
for (const step of program.steps) {
|
|
907
|
+
const stepStart = Date.now();
|
|
908
|
+
|
|
909
|
+
try {
|
|
910
|
+
if (step.action === 'generate' || step.action === 'compute') {
|
|
911
|
+
// Execute Python code in compute sandbox
|
|
912
|
+
pythonContext += `\n# Step: ${step.id}\n${step.code}\n_results['${step.id}'] = locals().get('result', None)\n`;
|
|
913
|
+
|
|
914
|
+
} else if (step.action === 'assert') {
|
|
915
|
+
// Add assertion check
|
|
916
|
+
pythonContext += `\n# Assert: ${step.id}\n_assert_${step.id} = ${step.code}\nif not _assert_${step.id}: raise AssertionError('${step.id} failed')\n_results['${step.id}'] = True\n`;
|
|
917
|
+
results.assertions.push({ id: step.id, code: step.code });
|
|
918
|
+
|
|
919
|
+
} else if (step.action === 'call') {
|
|
920
|
+
// Call a 50c tool
|
|
921
|
+
const toolResult = await call50cTool(step.tool, step.args || {});
|
|
922
|
+
results.tool_calls.push({ id: step.id, tool: step.tool, result: toolResult });
|
|
923
|
+
results.outputs[step.id] = toolResult;
|
|
924
|
+
// Inject result into Python context
|
|
925
|
+
pythonContext += `\n# Tool result: ${step.id}\n_results['${step.id}'] = ${JSON.stringify(toolResult)}\n`;
|
|
926
|
+
|
|
927
|
+
} else if (step.action === 'return') {
|
|
928
|
+
// Final return - will be evaluated after all code runs
|
|
929
|
+
pythonContext += `\n# Final output\n_final = ${step.code}\nprint('__FINAL__:' + json.dumps(_final))\n`;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
results.steps_completed++;
|
|
933
|
+
|
|
934
|
+
} catch (err) {
|
|
935
|
+
results.ok = false;
|
|
936
|
+
results.error = `Step ${step.id} failed: ${err.message}`;
|
|
937
|
+
break;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
// Execute all Python code in one compute call
|
|
942
|
+
if (results.ok) {
|
|
943
|
+
pythonContext += `\n# Output all results\nprint('__RESULTS__:' + json.dumps(_results))\n`;
|
|
944
|
+
|
|
945
|
+
try {
|
|
946
|
+
const computeResult = await call50cTool('compute', { code: pythonContext });
|
|
947
|
+
|
|
948
|
+
// Parse outputs
|
|
949
|
+
if (computeResult && typeof computeResult === 'string') {
|
|
950
|
+
const finalMatch = computeResult.match(/__FINAL__:(.+)/);
|
|
951
|
+
if (finalMatch) {
|
|
952
|
+
try {
|
|
953
|
+
results.final_result = JSON.parse(finalMatch[1]);
|
|
954
|
+
} catch (e) {
|
|
955
|
+
results.final_result = finalMatch[1];
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
const resultsMatch = computeResult.match(/__RESULTS__:(.+)/);
|
|
960
|
+
if (resultsMatch) {
|
|
961
|
+
try {
|
|
962
|
+
results.outputs = { ...results.outputs, ...JSON.parse(resultsMatch[1]) };
|
|
963
|
+
} catch (e) {}
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
results.compute_output = computeResult;
|
|
968
|
+
|
|
969
|
+
} catch (err) {
|
|
970
|
+
results.ok = false;
|
|
971
|
+
results.error = `Compute execution failed: ${err.message}`;
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
results.duration_ms = Date.now() - startTime;
|
|
976
|
+
return results;
|
|
977
|
+
}
|
|
978
|
+
|
|
797
979
|
async function autoInvent(args) {
|
|
798
980
|
const { problem, constraints = [], domain = 'code', rigor = 'deep' } = args;
|
|
799
981
|
const startTime = Date.now();
|
|
@@ -1285,6 +1467,16 @@ async function handleLocalTools(request) {
|
|
|
1285
1467
|
return mcpResult(id, { ok: false, error: e.message, stage: 'auto_invent' });
|
|
1286
1468
|
}
|
|
1287
1469
|
}
|
|
1470
|
+
|
|
1471
|
+
// ENTERPRISE: Programmatic invention pipeline ($2.00, gated)
|
|
1472
|
+
if (name === 'invent_program') {
|
|
1473
|
+
try {
|
|
1474
|
+
const result = await inventProgram(args);
|
|
1475
|
+
return mcpResult(id, result);
|
|
1476
|
+
} catch (e) {
|
|
1477
|
+
return mcpResult(id, { ok: false, error: e.message, stage: 'invent_program' });
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1288
1480
|
}
|
|
1289
1481
|
|
|
1290
1482
|
return null; // Not a local tool, forward to remote
|
|
@@ -1554,6 +1746,16 @@ ENTERPRISE (auto_invent):
|
|
|
1554
1746
|
--rigor=fast|standard|deep|exhaustive (default: deep)
|
|
1555
1747
|
--domain=math|physics|code|business (default: code)
|
|
1556
1748
|
--constraint="text" Add constraint (repeatable)
|
|
1749
|
+
invent-ui "problem" [opts] Same as invent, but opens browser UI
|
|
1750
|
+
Real-time swarm visualization (MCP TV!)
|
|
1751
|
+
|
|
1752
|
+
MCP-TV (FREE):
|
|
1753
|
+
tv Start MCP-TV server - universal MCP visualizer
|
|
1754
|
+
tv --port=3000 Custom port (default: 50888)
|
|
1755
|
+
|
|
1756
|
+
Any MCP can stream events to MCP-TV:
|
|
1757
|
+
POST http://localhost:50888/stream
|
|
1758
|
+
{ "channel": "my-mcp", "event": "stage", "data": {...} }
|
|
1557
1759
|
|
|
1558
1760
|
TOOLS (beacon pack):
|
|
1559
1761
|
50c beacon.health Context health check (FREE)
|
|
@@ -1586,3 +1788,6 @@ MCP MODE:
|
|
|
1586
1788
|
|
|
1587
1789
|
process.on('SIGINT', () => process.exit(130));
|
|
1588
1790
|
process.on('SIGTERM', () => process.exit(143));
|
|
1791
|
+
|
|
1792
|
+
// Export enterprise functions for team.js integration
|
|
1793
|
+
module.exports = { autoInvent, inventProgram };
|