societyai 0.1.3 → 0.1.5
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/inspect.js +0 -0
- package/bin/societyai.js +407 -64
- package/package.json +3 -2
package/bin/inspect.js
CHANGED
|
File without changes
|
package/bin/societyai.js
CHANGED
|
@@ -160,7 +160,7 @@ async function validateCommand(filePath) {
|
|
|
160
160
|
const ext = path.extname(fullPath);
|
|
161
161
|
if (ext === '.ts') {
|
|
162
162
|
console.log(colorize('dim', ' Compiling TypeScript...'));
|
|
163
|
-
execSync(`npx tsc --noEmit "${fullPath}"`, { stdio: 'pipe' });
|
|
163
|
+
execSync(`npx tsc --noEmit "${fullPath}"`, { stdio: 'pipe', cwd: path.dirname(fullPath) });
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
// Try to load and validate the module
|
|
@@ -171,7 +171,16 @@ async function validateCommand(filePath) {
|
|
|
171
171
|
|
|
172
172
|
// For TypeScript, we need to use ts-node/register
|
|
173
173
|
if (ext === '.ts') {
|
|
174
|
-
|
|
174
|
+
const projectDir = path.dirname(fullPath);
|
|
175
|
+
const originalCwd = process.cwd();
|
|
176
|
+
process.chdir(projectDir);
|
|
177
|
+
const localTsNode = path.join(projectDir, 'node_modules', 'ts-node', 'register');
|
|
178
|
+
try {
|
|
179
|
+
require(localTsNode);
|
|
180
|
+
} catch (e) {
|
|
181
|
+
require('ts-node/register');
|
|
182
|
+
}
|
|
183
|
+
process.chdir(originalCwd);
|
|
175
184
|
}
|
|
176
185
|
|
|
177
186
|
const module = require(fullPath);
|
|
@@ -188,8 +197,12 @@ async function validateCommand(filePath) {
|
|
|
188
197
|
console.warn(colorize('yellow', '⚠️ Warning: Society does not have an execute method'));
|
|
189
198
|
}
|
|
190
199
|
|
|
191
|
-
|
|
192
|
-
|
|
200
|
+
// Use build() to get the SocietyConfig for structure validation
|
|
201
|
+
if (typeof society.build === 'function') {
|
|
202
|
+
const config = society.build();
|
|
203
|
+
if (!config.agents || config.agents.length === 0) {
|
|
204
|
+
console.warn(colorize('yellow', '⚠️ Warning: Society has no agents'));
|
|
205
|
+
}
|
|
193
206
|
}
|
|
194
207
|
}
|
|
195
208
|
|
|
@@ -236,23 +249,36 @@ async function visualizeCommand(filePath, options) {
|
|
|
236
249
|
// Load the module
|
|
237
250
|
const ext = path.extname(fullPath);
|
|
238
251
|
if (ext === '.ts') {
|
|
239
|
-
|
|
252
|
+
const projectDir = path.dirname(fullPath);
|
|
253
|
+
const originalCwd = process.cwd();
|
|
254
|
+
process.chdir(projectDir);
|
|
255
|
+
const localTsNode = path.join(projectDir, 'node_modules', 'ts-node', 'register');
|
|
256
|
+
try {
|
|
257
|
+
require(localTsNode);
|
|
258
|
+
} catch (e) {
|
|
259
|
+
require('ts-node/register');
|
|
260
|
+
}
|
|
261
|
+
process.chdir(originalCwd);
|
|
240
262
|
}
|
|
241
263
|
|
|
242
264
|
const module = require(fullPath);
|
|
243
265
|
const society = module.default || module.society;
|
|
244
266
|
|
|
245
|
-
if (!society ||
|
|
246
|
-
console.error(colorize('red', '❌ Error: Could not find Society
|
|
267
|
+
if (!society || typeof society.build !== 'function') {
|
|
268
|
+
console.error(colorize('red', '❌ Error: Could not find Society builder in file'));
|
|
247
269
|
process.exit(1);
|
|
248
270
|
}
|
|
249
271
|
|
|
272
|
+
const { SocietyExecutor } = require('../dist/agents/society-executor');
|
|
273
|
+
const config = society.build();
|
|
274
|
+
const engine = new SocietyExecutor().buildExecutionGraph(config);
|
|
275
|
+
|
|
250
276
|
let result = '';
|
|
251
277
|
|
|
252
278
|
switch (format.toLowerCase()) {
|
|
253
279
|
case 'mermaid':
|
|
254
280
|
const { GraphVisualizer } = require('../dist/execution/graph-visualizer');
|
|
255
|
-
result = GraphVisualizer.toMermaid(
|
|
281
|
+
result = GraphVisualizer.toMermaid(engine, {
|
|
256
282
|
direction,
|
|
257
283
|
theme,
|
|
258
284
|
highlightPath: highlight,
|
|
@@ -262,27 +288,27 @@ async function visualizeCommand(filePath, options) {
|
|
|
262
288
|
case 'dot':
|
|
263
289
|
case 'graphviz':
|
|
264
290
|
const { GraphVisualizer: GV2 } = require('../dist/execution/graph-visualizer');
|
|
265
|
-
result = GV2.toDOT(
|
|
291
|
+
result = GV2.toDOT(engine, { rankdir: direction });
|
|
266
292
|
break;
|
|
267
293
|
|
|
268
294
|
case 'json':
|
|
269
295
|
const { GraphVisualizer: GV3 } = require('../dist/execution/graph-visualizer');
|
|
270
|
-
result = JSON.stringify(GV3.toJSON(
|
|
296
|
+
result = JSON.stringify(GV3.toJSON(engine), null, 2);
|
|
271
297
|
break;
|
|
272
298
|
|
|
273
299
|
case 'html':
|
|
274
300
|
const { GraphVisualizer: GV4 } = require('../dist/execution/graph-visualizer');
|
|
275
|
-
result = GV4.toHTML(
|
|
301
|
+
result = GV4.toHTML(engine, { direction, theme, highlightPath: highlight });
|
|
276
302
|
break;
|
|
277
303
|
|
|
278
304
|
case 'ascii':
|
|
279
305
|
const { GraphVisualizer: GV5 } = require('../dist/execution/graph-visualizer');
|
|
280
|
-
result = GV5.toASCII(
|
|
306
|
+
result = GV5.toASCII(engine);
|
|
281
307
|
break;
|
|
282
308
|
|
|
283
309
|
case 'plantuml':
|
|
284
310
|
const { GraphVisualizer: GV6 } = require('../dist/execution/graph-visualizer');
|
|
285
|
-
result = GV6.toPlantUML(
|
|
311
|
+
result = GV6.toPlantUML(engine, direction);
|
|
286
312
|
break;
|
|
287
313
|
|
|
288
314
|
default:
|
|
@@ -334,8 +360,19 @@ async function runCommand(filePath, options) {
|
|
|
334
360
|
try {
|
|
335
361
|
// Load the module
|
|
336
362
|
const ext = path.extname(fullPath);
|
|
363
|
+
const projectDir = path.dirname(fullPath);
|
|
337
364
|
if (ext === '.ts') {
|
|
338
|
-
|
|
365
|
+
// Change to project directory so ts-node picks up the local tsconfig.json
|
|
366
|
+
const originalCwd = process.cwd();
|
|
367
|
+
process.chdir(projectDir);
|
|
368
|
+
// Use ts-node from the project's own node_modules if available
|
|
369
|
+
const localTsNode = path.join(projectDir, 'node_modules', 'ts-node', 'register');
|
|
370
|
+
try {
|
|
371
|
+
require(localTsNode);
|
|
372
|
+
} catch (e) {
|
|
373
|
+
require('ts-node/register');
|
|
374
|
+
}
|
|
375
|
+
process.chdir(originalCwd);
|
|
339
376
|
}
|
|
340
377
|
|
|
341
378
|
const module = require(fullPath);
|
|
@@ -347,23 +384,29 @@ async function runCommand(filePath, options) {
|
|
|
347
384
|
}
|
|
348
385
|
|
|
349
386
|
// Setup observer for verbose mode
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
387
|
+
if (verbose) {
|
|
388
|
+
society.withObserver({
|
|
389
|
+
onNodeStart: (nodeId, type, input) => {
|
|
390
|
+
console.log(colorize('dim', ` ▶️ Node ${nodeId} (${type}) starting...`));
|
|
391
|
+
},
|
|
392
|
+
onNodeEnd: (nodeId, output, duration) => {
|
|
393
|
+
console.log(colorize('dim', ` ✅ Node ${nodeId} completed in ${duration}ms`));
|
|
394
|
+
},
|
|
395
|
+
onAgentStart: (agentId, modelName, input) => {
|
|
396
|
+
console.log(colorize('blue', ` 🤖 Agent ${agentId} (${modelName}) processing...`));
|
|
397
|
+
},
|
|
398
|
+
onAgentComplete: (agentId, modelName, output) => {
|
|
399
|
+
console.log(colorize('green', ` ✅ Agent ${agentId} completed`));
|
|
400
|
+
},
|
|
401
|
+
onAgentError: (agentId, modelName, error) => {
|
|
402
|
+
console.log(colorize('red', ` ❌ Agent ${agentId} error: ${error.message}`));
|
|
403
|
+
},
|
|
404
|
+
onPhaseStart: () => {},
|
|
405
|
+
onPhaseComplete: () => {},
|
|
406
|
+
onSocietyStart: () => {},
|
|
407
|
+
onSocietyComplete: () => {},
|
|
408
|
+
});
|
|
409
|
+
}
|
|
367
410
|
|
|
368
411
|
// Execute with timeout
|
|
369
412
|
const timeoutPromise = new Promise((_, reject) => {
|
|
@@ -371,7 +414,7 @@ async function runCommand(filePath, options) {
|
|
|
371
414
|
});
|
|
372
415
|
|
|
373
416
|
const result = await Promise.race([
|
|
374
|
-
society.execute(
|
|
417
|
+
society.execute(input),
|
|
375
418
|
timeoutPromise,
|
|
376
419
|
]);
|
|
377
420
|
|
|
@@ -408,6 +451,8 @@ async function runCommand(filePath, options) {
|
|
|
408
451
|
console.log(colorize('green', `\n💾 State saved to: ${saveState}`));
|
|
409
452
|
}
|
|
410
453
|
|
|
454
|
+
process.exit(0);
|
|
455
|
+
|
|
411
456
|
} catch (error) {
|
|
412
457
|
const duration = Date.now() - startTime;
|
|
413
458
|
console.error(colorize('red', `\n❌ Execution failed after ${duration}ms: ${error.message}`));
|
|
@@ -420,7 +465,7 @@ async function runCommand(filePath, options) {
|
|
|
420
465
|
|
|
421
466
|
// Init command
|
|
422
467
|
async function initCommand(template, options) {
|
|
423
|
-
const templateName =
|
|
468
|
+
const templateName = options.template || options.t || template || 'basic';
|
|
424
469
|
const outputDir = options.output || options.o || '.';
|
|
425
470
|
const projectName = options.name || 'my-society';
|
|
426
471
|
|
|
@@ -430,10 +475,9 @@ async function initCommand(template, options) {
|
|
|
430
475
|
|
|
431
476
|
const templates = {
|
|
432
477
|
basic: {
|
|
433
|
-
'society.ts': `import { Society } from 'societyai';
|
|
434
|
-
import { MockModel } from 'societyai/adapters';
|
|
478
|
+
'society.ts': `import { Society, StandardModelBase } from 'societyai';
|
|
435
479
|
|
|
436
|
-
const model = new
|
|
480
|
+
const model = new StandardModelBase({}, async () => 'Hello from mock model!').withName('mock');
|
|
437
481
|
|
|
438
482
|
export const society = Society.create()
|
|
439
483
|
.withName('${projectName}')
|
|
@@ -449,9 +493,9 @@ export const society = Society.create()
|
|
|
449
493
|
.sequential()
|
|
450
494
|
);
|
|
451
495
|
|
|
452
|
-
// Execute
|
|
496
|
+
// Execute (only when run directly, not when imported by CLI tools)
|
|
453
497
|
if (require.main === module) {
|
|
454
|
-
society.execute(
|
|
498
|
+
society.execute('Hello World')
|
|
455
499
|
.then(result => console.log(result.output))
|
|
456
500
|
.catch(console.error);
|
|
457
501
|
}
|
|
@@ -495,13 +539,26 @@ npm start
|
|
|
495
539
|
|
|
496
540
|
- \`society.ts\` - Main society configuration
|
|
497
541
|
`,
|
|
542
|
+
'tsconfig.json': JSON.stringify({
|
|
543
|
+
compilerOptions: {
|
|
544
|
+
target: 'ES2020',
|
|
545
|
+
module: 'commonjs',
|
|
546
|
+
moduleResolution: 'node',
|
|
547
|
+
esModuleInterop: true,
|
|
548
|
+
strict: false,
|
|
549
|
+
skipLibCheck: true,
|
|
550
|
+
outDir: 'dist',
|
|
551
|
+
},
|
|
552
|
+
'ts-node': {
|
|
553
|
+
transpileOnly: true,
|
|
554
|
+
},
|
|
555
|
+
}, null, 2),
|
|
498
556
|
},
|
|
499
557
|
|
|
500
558
|
advanced: {
|
|
501
|
-
'society.ts': `import { Society } from 'societyai';
|
|
502
|
-
import { MockModel } from 'societyai/adapters';
|
|
559
|
+
'society.ts': `import { Society, StandardModelBase, MiddlewareChain, Middlewares } from 'societyai';
|
|
503
560
|
|
|
504
|
-
const model = new
|
|
561
|
+
const model = new StandardModelBase({}, async () => 'Hello from mock model!').withName('mock');
|
|
505
562
|
|
|
506
563
|
export const society = Society.create()
|
|
507
564
|
.withName('${projectName}')
|
|
@@ -509,7 +566,6 @@ export const society = Society.create()
|
|
|
509
566
|
.withId('analyzer')
|
|
510
567
|
.withRole(role => role.withSystemPrompt('Analyze the input and extract key insights'))
|
|
511
568
|
.withModel(model)
|
|
512
|
-
.withExecutionMode('isolated')
|
|
513
569
|
)
|
|
514
570
|
.addAgent(agent => agent
|
|
515
571
|
.withId('validator')
|
|
@@ -522,23 +578,34 @@ export const society = Society.create()
|
|
|
522
578
|
.withModel(model)
|
|
523
579
|
)
|
|
524
580
|
.addTask(task => task
|
|
525
|
-
.withId('
|
|
526
|
-
.withAgents(['analyzer'
|
|
527
|
-
.withInstructions('
|
|
528
|
-
.withDependencies({
|
|
529
|
-
validator: ['analyzer'],
|
|
530
|
-
formatter: ['validator'],
|
|
531
|
-
})
|
|
581
|
+
.withId('analyze')
|
|
582
|
+
.withAgents(['analyzer'])
|
|
583
|
+
.withInstructions('Analyze the input')
|
|
532
584
|
.sequential()
|
|
533
585
|
)
|
|
534
|
-
.
|
|
535
|
-
.
|
|
536
|
-
.
|
|
586
|
+
.addTask(task => task
|
|
587
|
+
.withId('validate')
|
|
588
|
+
.withAgents(['validator'])
|
|
589
|
+
.withInstructions('Validate the analysis')
|
|
590
|
+
.dependsOn('analyze')
|
|
591
|
+
.sequential()
|
|
592
|
+
)
|
|
593
|
+
.addTask(task => task
|
|
594
|
+
.withId('format')
|
|
595
|
+
.withAgents(['formatter'])
|
|
596
|
+
.withInstructions('Format the final output')
|
|
597
|
+
.dependsOn('validate')
|
|
598
|
+
.sequential()
|
|
599
|
+
)
|
|
600
|
+
.addMiddleware(
|
|
601
|
+
MiddlewareChain.create()
|
|
602
|
+
.use(Middlewares.logging())
|
|
603
|
+
.use(Middlewares.timing())
|
|
537
604
|
);
|
|
538
605
|
|
|
539
|
-
// Execute
|
|
606
|
+
// Execute (only when run directly, not when imported by CLI tools)
|
|
540
607
|
if (require.main === module) {
|
|
541
|
-
society.execute(
|
|
608
|
+
society.execute('Hello World')
|
|
542
609
|
.then(result => console.log(result.output))
|
|
543
610
|
.catch(console.error);
|
|
544
611
|
}
|
|
@@ -586,6 +653,209 @@ npm start
|
|
|
586
653
|
- Agents: analyzer, validator, formatter
|
|
587
654
|
- Pipeline: analyzer → validator → formatter
|
|
588
655
|
`,
|
|
656
|
+
'tsconfig.json': JSON.stringify({
|
|
657
|
+
compilerOptions: {
|
|
658
|
+
target: 'ES2020',
|
|
659
|
+
module: 'commonjs',
|
|
660
|
+
moduleResolution: 'node',
|
|
661
|
+
esModuleInterop: true,
|
|
662
|
+
strict: false,
|
|
663
|
+
skipLibCheck: true,
|
|
664
|
+
outDir: 'dist',
|
|
665
|
+
},
|
|
666
|
+
'ts-node': {
|
|
667
|
+
transpileOnly: true,
|
|
668
|
+
},
|
|
669
|
+
}, null, 2),
|
|
670
|
+
},
|
|
671
|
+
|
|
672
|
+
mcp: {
|
|
673
|
+
'society.ts': `import { Society, StandardModelBase, MCPServers } from 'societyai';
|
|
674
|
+
|
|
675
|
+
const model = new StandardModelBase({}, async (input) => \`Processed: \${input}\`).withName('mock');
|
|
676
|
+
|
|
677
|
+
async function main() {
|
|
678
|
+
// Connect to an MCP filesystem server (adjust the path as needed)
|
|
679
|
+
const fsTools = await MCPServers.filesystem(process.cwd());
|
|
680
|
+
|
|
681
|
+
const society = Society.create()
|
|
682
|
+
.withName('${projectName}')
|
|
683
|
+
.addAgent(agent => agent
|
|
684
|
+
.withId('assistant')
|
|
685
|
+
.withRole(role => role
|
|
686
|
+
.withSystemPrompt('You are a helpful assistant with access to filesystem tools.')
|
|
687
|
+
.withTools(fsTools.getTools())
|
|
688
|
+
)
|
|
689
|
+
.withModel(model)
|
|
690
|
+
)
|
|
691
|
+
.addTask(task => task
|
|
692
|
+
.withId('main')
|
|
693
|
+
.withAgents(['assistant'])
|
|
694
|
+
.withInstructions('Process the input using available tools')
|
|
695
|
+
.sequential()
|
|
696
|
+
);
|
|
697
|
+
|
|
698
|
+
try {
|
|
699
|
+
const result = await society.execute('Hello World');
|
|
700
|
+
console.log(result.output);
|
|
701
|
+
} finally {
|
|
702
|
+
await fsTools.disconnect();
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
main().catch(console.error);
|
|
707
|
+
`,
|
|
708
|
+
'package.json': JSON.stringify({
|
|
709
|
+
name: projectName,
|
|
710
|
+
version: '1.0.0',
|
|
711
|
+
description: `A SocietyAI project with MCP tool integration`,
|
|
712
|
+
main: 'society.ts',
|
|
713
|
+
scripts: {
|
|
714
|
+
start: 'ts-node society.ts',
|
|
715
|
+
validate: 'societyai validate society.ts',
|
|
716
|
+
visualize: 'societyai visualize society.ts --format html --output graph.html',
|
|
717
|
+
},
|
|
718
|
+
dependencies: {
|
|
719
|
+
'societyai': '^0.1.0',
|
|
720
|
+
},
|
|
721
|
+
devDependencies: {
|
|
722
|
+
'ts-node': '^10.9.0',
|
|
723
|
+
'typescript': '^5.7.0',
|
|
724
|
+
},
|
|
725
|
+
}, null, 2),
|
|
726
|
+
'README.md': `# ${projectName}
|
|
727
|
+
|
|
728
|
+
A SocietyAI project with Model Context Protocol (MCP) tool integration.
|
|
729
|
+
|
|
730
|
+
## Getting Started
|
|
731
|
+
|
|
732
|
+
\`\`\`bash
|
|
733
|
+
npm install
|
|
734
|
+
npm start
|
|
735
|
+
\`\`\`
|
|
736
|
+
|
|
737
|
+
## Structure
|
|
738
|
+
|
|
739
|
+
- \`society.ts\` - Main society configuration with MCP tool support
|
|
740
|
+
- Uses MCPServers.filesystem to give agents access to filesystem tools
|
|
741
|
+
`,
|
|
742
|
+
'tsconfig.json': JSON.stringify({
|
|
743
|
+
compilerOptions: {
|
|
744
|
+
target: 'ES2020',
|
|
745
|
+
module: 'commonjs',
|
|
746
|
+
moduleResolution: 'node',
|
|
747
|
+
esModuleInterop: true,
|
|
748
|
+
strict: false,
|
|
749
|
+
skipLibCheck: true,
|
|
750
|
+
outDir: 'dist',
|
|
751
|
+
},
|
|
752
|
+
'ts-node': {
|
|
753
|
+
transpileOnly: true,
|
|
754
|
+
},
|
|
755
|
+
}, null, 2),
|
|
756
|
+
},
|
|
757
|
+
|
|
758
|
+
'multi-tenant': {
|
|
759
|
+
'society.ts': `import { Society, StandardModelBase } from 'societyai';
|
|
760
|
+
|
|
761
|
+
const model = new StandardModelBase({}, async (input) => \`Tenant response: \${input}\`).withName('mock');
|
|
762
|
+
|
|
763
|
+
// Factory function to create a society for a specific tenant
|
|
764
|
+
function createTenantSociety(tenantId: string, tenantConfig: { name: string; instructions: string }) {
|
|
765
|
+
return Society.create(\`society-\${tenantId}\`)
|
|
766
|
+
.withName(\`\${tenantConfig.name} Society\`)
|
|
767
|
+
.withGlobalContext({ tenantId, tenantName: tenantConfig.name })
|
|
768
|
+
.addAgent(agent => agent
|
|
769
|
+
.withId(\`agent-\${tenantId}\`)
|
|
770
|
+
.withRole(role => role.withSystemPrompt(tenantConfig.instructions))
|
|
771
|
+
.withModel(model)
|
|
772
|
+
)
|
|
773
|
+
.addTask(task => task
|
|
774
|
+
.withId('main')
|
|
775
|
+
.withAgents([\`agent-\${tenantId}\`])
|
|
776
|
+
.withInstructions('Process the input for this tenant')
|
|
777
|
+
.sequential()
|
|
778
|
+
);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
// Define tenants
|
|
782
|
+
const tenants = [
|
|
783
|
+
{ id: 'tenant-a', name: 'Tenant A', instructions: 'You handle support tickets for Tenant A. Be formal.' },
|
|
784
|
+
{ id: 'tenant-b', name: 'Tenant B', instructions: 'You handle support tickets for Tenant B. Be friendly.' },
|
|
785
|
+
];
|
|
786
|
+
|
|
787
|
+
// Export the multi-tenant runner
|
|
788
|
+
export async function runForTenant(tenantId: string, input: string) {
|
|
789
|
+
const tenant = tenants.find(t => t.id === tenantId);
|
|
790
|
+
if (!tenant) throw new Error(\`Unknown tenant: \${tenantId}\`);
|
|
791
|
+
|
|
792
|
+
const society = createTenantSociety(tenant.id, { name: tenant.name, instructions: tenant.instructions });
|
|
793
|
+
return society.execute(input);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
// Run example with all tenants
|
|
797
|
+
async function main() {
|
|
798
|
+
const input = 'Hello, I need help with my account';
|
|
799
|
+
for (const tenant of tenants) {
|
|
800
|
+
const society = createTenantSociety(tenant.id, { name: tenant.name, instructions: tenant.instructions });
|
|
801
|
+
const result = await society.execute(input);
|
|
802
|
+
console.log(\`[\${tenant.name}]: \${result.output}\`);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
if (require.main === module) {
|
|
807
|
+
main().catch(console.error);
|
|
808
|
+
}
|
|
809
|
+
`,
|
|
810
|
+
'package.json': JSON.stringify({
|
|
811
|
+
name: projectName,
|
|
812
|
+
version: '1.0.0',
|
|
813
|
+
description: `A multi-tenant SocietyAI project`,
|
|
814
|
+
main: 'society.ts',
|
|
815
|
+
scripts: {
|
|
816
|
+
start: 'ts-node society.ts',
|
|
817
|
+
validate: 'societyai validate society.ts',
|
|
818
|
+
visualize: 'societyai visualize society.ts --format html --output graph.html',
|
|
819
|
+
},
|
|
820
|
+
dependencies: {
|
|
821
|
+
'societyai': '^0.1.0',
|
|
822
|
+
},
|
|
823
|
+
devDependencies: {
|
|
824
|
+
'ts-node': '^10.9.0',
|
|
825
|
+
'typescript': '^5.7.0',
|
|
826
|
+
},
|
|
827
|
+
}, null, 2),
|
|
828
|
+
'README.md': `# ${projectName}
|
|
829
|
+
|
|
830
|
+
A multi-tenant SocietyAI project where each tenant gets an isolated society instance.
|
|
831
|
+
|
|
832
|
+
## Getting Started
|
|
833
|
+
|
|
834
|
+
\`\`\`bash
|
|
835
|
+
npm install
|
|
836
|
+
npm start
|
|
837
|
+
\`\`\`
|
|
838
|
+
|
|
839
|
+
## Structure
|
|
840
|
+
|
|
841
|
+
- \`society.ts\` - Multi-tenant society factory and runner
|
|
842
|
+
- Each tenant gets its own isolated society with custom instructions
|
|
843
|
+
- Use \`runForTenant(tenantId, input)\` to execute for a specific tenant
|
|
844
|
+
`,
|
|
845
|
+
'tsconfig.json': JSON.stringify({
|
|
846
|
+
compilerOptions: {
|
|
847
|
+
target: 'ES2020',
|
|
848
|
+
module: 'commonjs',
|
|
849
|
+
moduleResolution: 'node',
|
|
850
|
+
esModuleInterop: true,
|
|
851
|
+
strict: false,
|
|
852
|
+
skipLibCheck: true,
|
|
853
|
+
outDir: 'dist',
|
|
854
|
+
},
|
|
855
|
+
'ts-node': {
|
|
856
|
+
transpileOnly: true,
|
|
857
|
+
},
|
|
858
|
+
}, null, 2),
|
|
589
859
|
},
|
|
590
860
|
};
|
|
591
861
|
|
|
@@ -593,7 +863,7 @@ npm start
|
|
|
593
863
|
|
|
594
864
|
if (!selectedTemplate) {
|
|
595
865
|
console.error(colorize('red', `❌ Unknown template: ${templateName}`));
|
|
596
|
-
console.error(colorize('dim', 'Available templates: basic, advanced'));
|
|
866
|
+
console.error(colorize('dim', 'Available templates: basic, advanced, mcp, multi-tenant'));
|
|
597
867
|
process.exit(1);
|
|
598
868
|
}
|
|
599
869
|
|
|
@@ -618,6 +888,68 @@ npm start
|
|
|
618
888
|
}
|
|
619
889
|
|
|
620
890
|
// Diff command
|
|
891
|
+
async function inspectCommand(filePath) {
|
|
892
|
+
if (!filePath) {
|
|
893
|
+
console.error(colorize('red', '❌ Error: No file specified'));
|
|
894
|
+
console.error(colorize('dim', 'Usage: societyai inspect <path-to-state.json>'));
|
|
895
|
+
process.exit(1);
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
const fullPath = path.resolve(filePath);
|
|
899
|
+
if (!fs.existsSync(fullPath)) {
|
|
900
|
+
console.error(colorize('red', `❌ File not found: ${fullPath}`));
|
|
901
|
+
process.exit(1);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
try {
|
|
905
|
+
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
906
|
+
const state = JSON.parse(content);
|
|
907
|
+
|
|
908
|
+
console.log('\n🔍 SocietyAI Execution State Inspector\n');
|
|
909
|
+
console.log(`🆔 Execution ID: ${colorize('cyan', state.executionId || 'N/A')}`);
|
|
910
|
+
console.log(`📅 Timestamp: ${state.timestamp ? new Date(state.timestamp).toLocaleString() : 'N/A'}`);
|
|
911
|
+
console.log(`🚦 Status: ${formatInspectStatus(state.status)}`);
|
|
912
|
+
|
|
913
|
+
if (state.executionPath && state.executionPath.length > 0) {
|
|
914
|
+
console.log(`🛣️ Path Length: ${state.executionPath.length} steps`);
|
|
915
|
+
console.log(` Start: ${state.executionPath[0] || 'N/A'}`);
|
|
916
|
+
console.log(` Current: ${state.executionPath[state.executionPath.length - 1] || 'N/A'}`);
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
console.log('\n📋 Queue (Next Nodes):');
|
|
920
|
+
if (!state.queue || state.queue.length === 0) {
|
|
921
|
+
console.log(' (Empty)');
|
|
922
|
+
} else {
|
|
923
|
+
state.queue.forEach((nodeId, idx) => {
|
|
924
|
+
console.log(` ${idx + 1}. ${nodeId}`);
|
|
925
|
+
});
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
if (state.status === 'paused' && state.waitingForNodeId) {
|
|
929
|
+
console.log(`\n⏸️ Waiting For: ${colorize('yellow', state.waitingForNodeId)} (Human Input)`);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
if (state.deadLetterQueue && state.deadLetterQueue.length > 0) {
|
|
933
|
+
console.log(`\n💀 Dead Letter Queue: ${colorize('red', state.deadLetterQueue.join(', '))}`);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
console.log(`\n🧠 Memory/Results Captured: ${state.results ? state.results.length : 0} nodes`);
|
|
937
|
+
} catch (error) {
|
|
938
|
+
console.error(colorize('red', `❌ Error reading state file: ${error.message}`));
|
|
939
|
+
process.exit(1);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
function formatInspectStatus(status) {
|
|
944
|
+
switch (status) {
|
|
945
|
+
case 'active': return colorize('green', 'Active');
|
|
946
|
+
case 'completed': return colorize('cyan', 'Completed');
|
|
947
|
+
case 'failed': return colorize('red', 'Failed');
|
|
948
|
+
case 'paused': return colorize('yellow', 'Paused');
|
|
949
|
+
default: return status || 'Unknown';
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
|
|
621
953
|
async function diffCommand(file1, file2) {
|
|
622
954
|
console.log(colorize('cyan', '🔍 Comparing Society configurations...'));
|
|
623
955
|
|
|
@@ -645,7 +977,16 @@ async function diffCommand(file1, file2) {
|
|
|
645
977
|
const ext2 = path.extname(path2);
|
|
646
978
|
|
|
647
979
|
if (ext1 === '.ts' || ext2 === '.ts') {
|
|
648
|
-
|
|
980
|
+
const projectDir = path.dirname(path1);
|
|
981
|
+
const originalCwd = process.cwd();
|
|
982
|
+
process.chdir(projectDir);
|
|
983
|
+
const localTsNode = path.join(projectDir, 'node_modules', 'ts-node', 'register');
|
|
984
|
+
try {
|
|
985
|
+
require(localTsNode);
|
|
986
|
+
} catch (e) {
|
|
987
|
+
require('ts-node/register');
|
|
988
|
+
}
|
|
989
|
+
process.chdir(originalCwd);
|
|
649
990
|
}
|
|
650
991
|
|
|
651
992
|
const module1 = require(path1);
|
|
@@ -654,16 +995,19 @@ async function diffCommand(file1, file2) {
|
|
|
654
995
|
const society1 = module1.default || module1.society;
|
|
655
996
|
const society2 = module2.default || module2.society;
|
|
656
997
|
|
|
657
|
-
if (!society1 || !society2) {
|
|
658
|
-
console.error(colorize('red', '❌ Error: Could not find Society in one or both files'));
|
|
998
|
+
if (!society1 || typeof society1.build !== 'function' || !society2 || typeof society2.build !== 'function') {
|
|
999
|
+
console.error(colorize('red', '❌ Error: Could not find Society builder in one or both files'));
|
|
659
1000
|
process.exit(1);
|
|
660
1001
|
}
|
|
661
1002
|
|
|
1003
|
+
const config1 = society1.build();
|
|
1004
|
+
const config2 = society2.build();
|
|
1005
|
+
|
|
662
1006
|
console.log(colorize('cyan', '\n📊 Comparison Results:'));
|
|
663
1007
|
|
|
664
1008
|
// Compare agents
|
|
665
|
-
const agents1 =
|
|
666
|
-
const agents2 =
|
|
1009
|
+
const agents1 = config1.agents || [];
|
|
1010
|
+
const agents2 = config2.agents || [];
|
|
667
1011
|
|
|
668
1012
|
console.log(colorize('blue', '\nAgents:'));
|
|
669
1013
|
console.log(colorize('dim', ` File 1: ${agents1.length} agents`));
|
|
@@ -688,8 +1032,8 @@ async function diffCommand(file1, file2) {
|
|
|
688
1032
|
}
|
|
689
1033
|
|
|
690
1034
|
// Compare tasks
|
|
691
|
-
const tasks1 =
|
|
692
|
-
const tasks2 =
|
|
1035
|
+
const tasks1 = config1.tasks || [];
|
|
1036
|
+
const tasks2 = config2.tasks || [];
|
|
693
1037
|
|
|
694
1038
|
console.log(colorize('blue', '\nTasks:'));
|
|
695
1039
|
console.log(colorize('dim', ` File 1: ${tasks1.length} tasks`));
|
|
@@ -783,8 +1127,7 @@ async function main() {
|
|
|
783
1127
|
break;
|
|
784
1128
|
|
|
785
1129
|
case 'inspect':
|
|
786
|
-
|
|
787
|
-
require('./inspect');
|
|
1130
|
+
await inspectCommand(args[0]);
|
|
788
1131
|
break;
|
|
789
1132
|
|
|
790
1133
|
case 'diff':
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "societyai",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "A powerful TypeScript library for creating collaborative multi-agent AI systems with DAG-based orchestration. Build sophisticated workflows where AI agents work together through dependency graphs, conditional routing, and pluggable execution strategies. Features thread-safe parallel execution, memory management, and circuit breaker patterns for production-grade reliability.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -108,7 +108,8 @@
|
|
|
108
108
|
"prettier": "^3.1.1",
|
|
109
109
|
"ts-jest": "^29.1.1",
|
|
110
110
|
"ts-node": "^10.9.2",
|
|
111
|
-
"typescript": "^5.7.3"
|
|
111
|
+
"typescript": "^5.7.3",
|
|
112
|
+
"vitest": "^4.1.0"
|
|
112
113
|
},
|
|
113
114
|
"peerDependencies": {
|
|
114
115
|
"@modelcontextprotocol/sdk": "^0.5.0",
|