@bolloon/bolloon-agent 0.2.12 → 0.2.13
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/README.md +495 -467
- package/bin/bolloon-cli.cjs +183 -183
- package/bin/bolloon-daemon.sh +207 -0
- package/bin/bolloon.cjs +0 -0
- package/bin/ipfs +0 -0
- package/dist/agents/agent-manifest-protocol.js +52 -0
- package/dist/agents/chat-segmenter.js +298 -0
- package/dist/agents/constraint-layer.js +19 -19
- package/dist/agents/judgment-protocol.js +479 -0
- package/dist/agents/parse-tool-call.js +304 -0
- package/dist/agents/peer-manifest-loader.js +210 -0
- package/dist/agents/pi-sdk-session-factory.js +110 -0
- package/dist/agents/pi-sdk-session-manager.js +297 -0
- package/dist/agents/pi-sdk-tools.js +1288 -0
- package/dist/agents/pi-sdk-types.js +13 -0
- package/dist/agents/pi-sdk.js +553 -1306
- package/dist/agents/react-loop.js +120 -0
- package/dist/agents/session-store.js +171 -0
- package/dist/agents/shell-guard.js +2 -2
- package/dist/agents/tool-registry.js +136 -0
- package/dist/agents/workflow-pivot-loop.js +200 -22
- package/dist/bollharness/src/scripts/context_router.js +7 -0
- package/dist/bollharness/src/scripts/deploy-guard.js +8 -8
- package/dist/bollharness-integration/context-router-judgment.js +4 -4
- package/dist/bollharness-integration/context-router.js +292 -292
- package/dist/bollharness-integration/gate-state-machine.js +26 -13
- package/dist/bollharness-integration/integration.js +71 -0
- package/dist/bollharness-integration/llm-judgment-engine.js +134 -134
- package/dist/bollharness-integration/skill-adapter.js +57 -127
- package/dist/bootstrap/chat-archiver.js +276 -0
- package/dist/bootstrap/context-collector.js +6 -3
- package/dist/bootstrap/event-log.js +160 -0
- package/dist/bootstrap/lifecycle-hooks.js +15 -1
- package/dist/bootstrap/memory-compressor.js +170 -0
- package/dist/bootstrap/persona-loader.js +94 -0
- package/dist/bootstrap/project-state.js +159 -0
- package/dist/bootstrap/remote-mirror.js +97 -0
- package/dist/bootstrap/session-window.js +121 -0
- package/dist/bootstrap/vector-index.js +248 -0
- package/dist/cli/loading-tui.js +40 -0
- package/dist/cli-entry.js +41 -37
- package/dist/context-compaction/auto-compact.js +7 -7
- package/dist/electron/config.js +21 -0
- package/dist/electron/config.js.map +1 -0
- package/dist/electron/dialogs.js +108 -0
- package/dist/electron/dialogs.js.map +1 -0
- package/dist/electron/first-run.js +170 -0
- package/dist/electron/first-run.js.map +1 -0
- package/dist/electron/ipc.js +20 -0
- package/dist/electron/ipc.js.map +1 -0
- package/dist/electron/logger.js +114 -0
- package/dist/electron/logger.js.map +1 -0
- package/dist/electron/main.js +63 -0
- package/dist/electron/main.js.map +1 -0
- package/dist/electron/menu.js +145 -0
- package/dist/electron/menu.js.map +1 -0
- package/dist/electron/paths.js +75 -0
- package/dist/electron/paths.js.map +1 -0
- package/dist/electron/server.js +119 -0
- package/dist/electron/server.js.map +1 -0
- package/dist/electron/tray.js +111 -0
- package/dist/electron/tray.js.map +1 -0
- package/dist/electron/window.js +111 -0
- package/dist/electron/window.js.map +1 -0
- package/dist/electron-preload.js +26 -6
- package/dist/electron-preload.js.map +1 -1
- package/dist/electron.js +6 -168
- package/dist/electron.js.map +1 -1
- package/dist/index.js +323 -266
- package/dist/llm/config-store.js +24 -8
- package/dist/llm/llm-judgment-client.js +102 -102
- package/dist/llm/pi-ai.js +137 -85
- package/dist/llm/system-prompt/layers/channel/local.md +14 -14
- package/dist/llm/system-prompt/layers/channel/p2p-agent.md +18 -18
- package/dist/llm/system-prompt/layers/channel/p2p-visitor.md +19 -19
- package/dist/llm/system-prompt/layers/core/artifacts_storage.md +89 -89
- package/dist/llm/system-prompt/layers/core/evenhandedness.md +21 -21
- package/dist/llm/system-prompt/layers/core/hibs_reminders.md +15 -15
- package/dist/llm/system-prompt/layers/core/identity.md +37 -37
- package/dist/llm/system-prompt/layers/core/knowledge.md +17 -17
- package/dist/llm/system-prompt/layers/core/memory_system.md +12 -12
- package/dist/llm/system-prompt/layers/core/network_filesystem.md +28 -28
- package/dist/llm/system-prompt/layers/core/refusal.md +37 -37
- package/dist/llm/system-prompt/layers/core/tone.md +31 -31
- package/dist/llm/system-prompt/layers/core/tools.thin.md +13 -13
- package/dist/llm/system-prompt/layers/core/wellbeing.md +41 -41
- package/dist/llm/system-prompt/layers/role/architect.md +20 -20
- package/dist/llm/system-prompt/layers/role/expert.md +19 -19
- package/dist/llm/system-prompt/layers/role/implementer.md +15 -15
- package/dist/llm/system-prompt/layers/role/security.md +15 -15
- package/dist/llm/system-prompt/layers/tool/artifacts.md +72 -72
- package/dist/llm/system-prompt/layers/tool/bash.md +25 -25
- package/dist/llm/system-prompt/layers/tool/hibs_api.md +171 -171
- package/dist/llm/system-prompt/layers/tool/image_search.md +70 -70
- package/dist/llm/system-prompt/layers/tool/manifest.md +89 -89
- package/dist/llm/system-prompt/layers/tool/mcp_apps.md +53 -53
- package/dist/llm/system-prompt/layers/tool/web_search.md +83 -83
- package/dist/llm/tool-manifest/ask_user_input.js +1 -1
- package/dist/llm/tool-manifest/bash.js +3 -3
- package/dist/llm/tool-manifest/create_file.js +4 -4
- package/dist/llm/tool-manifest/fetch_sports_data.js +3 -3
- package/dist/llm/tool-manifest/image_search.js +2 -2
- package/dist/llm/tool-manifest/mcp.js +2 -2
- package/dist/llm/tool-manifest/message_compose.js +3 -3
- package/dist/llm/tool-manifest/places.js +2 -2
- package/dist/llm/tool-manifest/present_files.js +1 -1
- package/dist/llm/tool-manifest/recipe.js +2 -2
- package/dist/llm/tool-manifest/str_replace.js +5 -5
- package/dist/llm/tool-manifest/view.js +3 -3
- package/dist/llm/tool-manifest/weather.js +4 -4
- package/dist/llm/tool-manifest/web.js +4 -4
- package/dist/network/local-inbox-bus.js +73 -0
- package/dist/network/p2p-outbox.js +161 -0
- package/dist/network/peer-fs.js +420 -0
- package/dist/network/peer-resource-bridge.js +216 -0
- package/dist/pi-ecosystem-judgment/causal-judge.js +51 -51
- package/dist/pi-ecosystem-judgment/cleanup.js +126 -0
- package/dist/pi-ecosystem-judgment/distill-prompt.js +42 -42
- package/dist/pi-ecosystem-judgment/distillation.js +14 -14
- package/dist/pi-ecosystem-judgment/human-value-store.js +45 -11
- package/dist/pi-ecosystem-judgment/monitor-gate.js +28 -28
- package/dist/pi-ecosystem-judgment/value-injection.js +102 -102
- package/dist/security/context-router-tool.js +15 -15
- package/dist/security/tool-gate.js +11 -0
- package/dist/web/api-config.html +520 -520
- package/dist/web/client-loop-status.js +220 -0
- package/dist/web/client.js +22 -5
- package/dist/web/client.js.map +7 -0
- package/dist/web/components/wallet-viem.mjs +118 -118
- package/dist/web/index.html +375 -375
- package/dist/web/input-validator.js +103 -0
- package/dist/web/manifest.json +20 -20
- package/dist/web/routes-judgments.js +738 -0
- package/dist/web/routes-llm-config.js +279 -0
- package/dist/web/routes-tasks.js +222 -0
- package/dist/web/server-sse.js +121 -0
- package/dist/web/server-storage.js +154 -0
- package/dist/web/server-types.js +15 -0
- package/dist/web/server-v3-p2p.js +224 -0
- package/dist/web/server.js +1070 -1307
- package/dist/web/style.css +4742 -4742
- package/dist/web/util/safe-name.js +32 -0
- package/package.json +162 -160
- package/scripts/build-cli.js +215 -215
- package/scripts/build-web.ts +130 -130
- package/scripts/postinstall.js +152 -152
- package/bin/bolloon.js +0 -157
- package/dist/constraint-runtime/src/_archive_helper.js +0 -9
- package/dist/constraint-runtime/src/agent/coordinator.js +0 -48
- package/dist/constraint-runtime/src/agent/index.js +0 -1
- package/dist/constraint-runtime/src/assistant/index.js +0 -12
- package/dist/constraint-runtime/src/bootstrap/index.js +0 -12
- package/dist/constraint-runtime/src/bootstrap_graph.js +0 -13
- package/dist/constraint-runtime/src/bridge/index.js +0 -12
- package/dist/constraint-runtime/src/buddy/index.js +0 -12
- package/dist/constraint-runtime/src/cli/index.js +0 -12
- package/dist/constraint-runtime/src/command_graph.js +0 -10
- package/dist/constraint-runtime/src/commands.js +0 -60
- package/dist/constraint-runtime/src/components/index.js +0 -12
- package/dist/constraint-runtime/src/constants/index.js +0 -12
- package/dist/constraint-runtime/src/constraint/budget.js +0 -22
- package/dist/constraint-runtime/src/constraint/index.js +0 -2
- package/dist/constraint-runtime/src/constraint/permission.js +0 -20
- package/dist/constraint-runtime/src/context.js +0 -30
- package/dist/constraint-runtime/src/coordinator/index.js +0 -12
- package/dist/constraint-runtime/src/cost_hook.js +0 -4
- package/dist/constraint-runtime/src/cost_tracker.js +0 -8
- package/dist/constraint-runtime/src/deferred_init.js +0 -10
- package/dist/constraint-runtime/src/direct_modes.js +0 -6
- package/dist/constraint-runtime/src/dynamic-tool-loader.js +0 -85
- package/dist/constraint-runtime/src/entrypoints/index.js +0 -12
- package/dist/constraint-runtime/src/execution_registry.js +0 -44
- package/dist/constraint-runtime/src/history.js +0 -9
- package/dist/constraint-runtime/src/hooks/index.js +0 -12
- package/dist/constraint-runtime/src/index.js +0 -26
- package/dist/constraint-runtime/src/ink.js +0 -4
- package/dist/constraint-runtime/src/keybindings/index.js +0 -12
- package/dist/constraint-runtime/src/memdir/index.js +0 -12
- package/dist/constraint-runtime/src/migrations/index.js +0 -12
- package/dist/constraint-runtime/src/models.js +0 -1
- package/dist/constraint-runtime/src/moreright/index.js +0 -12
- package/dist/constraint-runtime/src/native_ts/index.js +0 -12
- package/dist/constraint-runtime/src/output_styles/index.js +0 -12
- package/dist/constraint-runtime/src/parity_audit.js +0 -12
- package/dist/constraint-runtime/src/plugins/index.js +0 -12
- package/dist/constraint-runtime/src/port_manifest.js +0 -11
- package/dist/constraint-runtime/src/prefetch.js +0 -9
- package/dist/constraint-runtime/src/query.js +0 -1
- package/dist/constraint-runtime/src/remote/index.js +0 -12
- package/dist/constraint-runtime/src/remote_runtime.js +0 -9
- package/dist/constraint-runtime/src/runtime/index.js +0 -1
- package/dist/constraint-runtime/src/runtime/session.js +0 -35
- package/dist/constraint-runtime/src/schemas/index.js +0 -12
- package/dist/constraint-runtime/src/screens/index.js +0 -12
- package/dist/constraint-runtime/src/server/index.js +0 -12
- package/dist/constraint-runtime/src/services/index.js +0 -12
- package/dist/constraint-runtime/src/session_store.js +0 -22
- package/dist/constraint-runtime/src/setup.js +0 -30
- package/dist/constraint-runtime/src/skills/index.js +0 -1
- package/dist/constraint-runtime/src/skills/skill-registry.js +0 -28
- package/dist/constraint-runtime/src/state/index.js +0 -12
- package/dist/constraint-runtime/src/system_init.js +0 -20
- package/dist/constraint-runtime/src/thinking/engine.js +0 -42
- package/dist/constraint-runtime/src/thinking/index.js +0 -1
- package/dist/constraint-runtime/src/tool_pool.js +0 -8
- package/dist/constraint-runtime/src/tools/OpenCLI/execAdapter.js +0 -7
- package/dist/constraint-runtime/src/tools/OpenCLI/listAdapters.js +0 -7
- package/dist/constraint-runtime/src/tools/OpenCLI/runCommand.js +0 -7
- package/dist/constraint-runtime/src/tools/SafeSDK/confirmTransaction.js +0 -6
- package/dist/constraint-runtime/src/tools/SafeSDK/createTransaction.js +0 -8
- package/dist/constraint-runtime/src/tools/SafeSDK/executeTransaction.js +0 -6
- package/dist/constraint-runtime/src/tools/SafeSDK/getBalance.js +0 -6
- package/dist/constraint-runtime/src/tools/SafeSDK/getPendingTransactions.js +0 -6
- package/dist/constraint-runtime/src/tools/SafeSDK/proposeTransaction.js +0 -6
- package/dist/constraint-runtime/src/tools.js +0 -80
- package/dist/constraint-runtime/src/transcript.js +0 -19
- package/dist/constraint-runtime/src/types/index.js +0 -12
- package/dist/constraint-runtime/src/upstream_proxy/index.js +0 -12
- package/dist/constraint-runtime/src/utils/index.js +0 -12
- package/dist/constraint-runtime/src/vim/index.js +0 -12
- package/dist/constraint-runtime/src/voice/index.js +0 -12
- package/dist/constraint-runtime/tests/agent.test.js +0 -16
- package/dist/constraint-runtime/tests/constraint.test.js +0 -41
- package/dist/constraint-runtime/tests/skill.test.js +0 -19
- package/dist/constraint-runtime/tests/thinking.test.js +0 -22
- package/dist/pi-ecosystem-colony/index.js +0 -365
- package/dist/social/ant-colony/AdaptiveHeartbeat.js +0 -101
- package/dist/social/ant-colony/PheromoneEngine.js +0 -227
- package/dist/social/ant-colony/index.js +0 -6
- package/dist/social/ant-colony/types.js +0 -24
- package/dist/test/ai-judgment-test.js +0 -80
- package/dist/test/bollharness-integration.test.js +0 -318
- package/dist/test/channel-agent-multi-dialogue.js +0 -205
- package/dist/test/channel-heartbeat-agent-test.js +0 -201
- package/dist/test/constraint-layer.test.js +0 -164
- package/dist/test/diap-identity-test.js +0 -172
- package/dist/test/diap-quick-test.js +0 -62
- package/dist/test/global-shared-context.test.js +0 -315
- package/dist/test/harness-judgment-injection.test.js +0 -246
- package/dist/test/harness-workflow-integrator-test.js +0 -228
- package/dist/test/human-value-store.test.js +0 -243
- package/dist/test/hybrid-integration-test.js +0 -118
- package/dist/test/hybrid-messenger-verify.js +0 -55
- package/dist/test/iroh-bistream-debug.js +0 -38
- package/dist/test/iroh-communication.test.js +0 -66
- package/dist/test/iroh-debug-test.js +0 -57
- package/dist/test/iroh-diap-test.js +0 -71
- package/dist/test/iroh-direct-connect.js +0 -55
- package/dist/test/iroh-e2e-fixed.js +0 -89
- package/dist/test/iroh-e2e-same-process.js +0 -63
- package/dist/test/iroh-e2e.js +0 -66
- package/dist/test/iroh-final-e2e.js +0 -72
- package/dist/test/iroh-relay-test.js +0 -37
- package/dist/test/iroh-simple-test.js +0 -41
- package/dist/test/iroh-transport-verify.js +0 -54
- package/dist/test/iroh-transport.test.js +0 -37
- package/dist/test/iroh-two-nodes.js +0 -70
- package/dist/test/iroh-verify.js +0 -44
- package/dist/test/judgment-decision.test.js +0 -219
- package/dist/test/llm-judgment-integration.test.js +0 -220
- package/dist/test/p2p-agent-complex-dialogue.js +0 -385
- package/dist/test/p2p-agent-dialogue.js +0 -341
- package/dist/test/p2p-agent-full-bidirectional.js +0 -510
- package/dist/test/p2p-agent-harness-flow.js +0 -437
- package/dist/test/p2p-agent-harness-single.js +0 -143
- package/dist/test/p2p-ai-dialogue-test.js +0 -318
- package/dist/test/p2p-cid-connect-test.js +0 -195
- package/dist/test/p2p-connect-receiver.js +0 -69
- package/dist/test/p2p-doc-transfer.js +0 -110
- package/dist/test/p2p-identity-page-test.js +0 -77
- package/dist/test/p2p-iroh-test.js +0 -171
- package/dist/test/p2p-minimal-test.js +0 -241
- package/dist/test/p2p-node-1.js +0 -148
- package/dist/test/p2p-node-2.js +0 -148
- package/dist/test/p2p-server.js +0 -281
- package/dist/test/p2p-two-nodes-test.js +0 -438
- package/dist/test/pi-sdk.test.js +0 -44
- package/dist/test/set-persona.js +0 -40
- package/dist/test/simple.test.js +0 -9
- package/dist/test/storage-integration.test.js +0 -150
- package/dist/test/subagent-manager.test.js +0 -276
- package/dist/test/test-gate-flow.test.js +0 -81
- package/dist/test/workflow-engine.test.js +0 -87
- package/dist/test/workflow-pivot-loop.test.js +0 -246
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs';
|
|
2
|
-
import * as path from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
import { executeToolFromSnapshot } from './dynamic-tool-loader.js';
|
|
5
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
-
const __dirname = path.dirname(__filename);
|
|
7
|
-
const SNAPSHOT_PATH = path.join(__dirname, 'reference_data', 'tools_snapshot.json');
|
|
8
|
-
function loadToolSnapshot() {
|
|
9
|
-
try {
|
|
10
|
-
if (!fs.existsSync(SNAPSHOT_PATH)) {
|
|
11
|
-
console.warn(`[tools] Snapshot not found: ${SNAPSHOT_PATH}, using empty list`);
|
|
12
|
-
return [];
|
|
13
|
-
}
|
|
14
|
-
const raw = JSON.parse(fs.readFileSync(SNAPSHOT_PATH, 'utf-8'));
|
|
15
|
-
return raw.map((e) => ({
|
|
16
|
-
name: e.name,
|
|
17
|
-
responsibility: e.responsibility,
|
|
18
|
-
sourceHint: e.source_hint,
|
|
19
|
-
status: 'mirrored',
|
|
20
|
-
}));
|
|
21
|
-
}
|
|
22
|
-
catch (error) {
|
|
23
|
-
console.warn(`[tools] Failed to load snapshot: ${error}, using empty list`);
|
|
24
|
-
return [];
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
export const PORTED_TOOLS = loadToolSnapshot();
|
|
28
|
-
export function getTool(name) {
|
|
29
|
-
const needle = name.toLowerCase();
|
|
30
|
-
return PORTED_TOOLS.find(m => m.name.toLowerCase() === needle);
|
|
31
|
-
}
|
|
32
|
-
export function getTools(simpleMode = false) {
|
|
33
|
-
let tools = [...PORTED_TOOLS];
|
|
34
|
-
if (simpleMode) {
|
|
35
|
-
tools = tools.filter(m => ['BashTool', 'FileReadTool', 'FileEditTool'].includes(m.name));
|
|
36
|
-
}
|
|
37
|
-
return tools;
|
|
38
|
-
}
|
|
39
|
-
export function findTools(query, limit = 20) {
|
|
40
|
-
const needle = query.toLowerCase();
|
|
41
|
-
return PORTED_TOOLS.filter(m => m.name.toLowerCase().includes(needle) || m.sourceHint.toLowerCase().includes(needle)).slice(0, limit);
|
|
42
|
-
}
|
|
43
|
-
export async function executeTool(name, payload = '') {
|
|
44
|
-
const module = getTool(name);
|
|
45
|
-
if (!module) {
|
|
46
|
-
return { name, sourceHint: '', payload, handled: false, message: `Unknown mirrored tool: ${name}` };
|
|
47
|
-
}
|
|
48
|
-
let params = {};
|
|
49
|
-
try {
|
|
50
|
-
params = payload ? JSON.parse(payload) : {};
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
return {
|
|
54
|
-
name: module.name,
|
|
55
|
-
sourceHint: module.sourceHint,
|
|
56
|
-
payload,
|
|
57
|
-
handled: false,
|
|
58
|
-
message: `Invalid JSON payload for tool '${module.name}'`,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
const result = await executeToolFromSnapshot(module.sourceHint, params);
|
|
62
|
-
if (result.success) {
|
|
63
|
-
return {
|
|
64
|
-
name: module.name,
|
|
65
|
-
sourceHint: module.sourceHint,
|
|
66
|
-
payload: JSON.stringify(result.data),
|
|
67
|
-
handled: true,
|
|
68
|
-
message: `Tool '${module.name}' executed successfully`,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
return {
|
|
73
|
-
name: module.name,
|
|
74
|
-
sourceHint: module.sourceHint,
|
|
75
|
-
payload,
|
|
76
|
-
handled: false,
|
|
77
|
-
message: `Tool '${module.name}' failed: ${result.error}`,
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export class TranscriptStore {
|
|
2
|
-
entries = [];
|
|
3
|
-
flushed = false;
|
|
4
|
-
append(entry) {
|
|
5
|
-
this.entries.push(entry);
|
|
6
|
-
this.flushed = false;
|
|
7
|
-
}
|
|
8
|
-
compact(keepLast = 10) {
|
|
9
|
-
if (this.entries.length > keepLast) {
|
|
10
|
-
this.entries = this.entries.slice(-keepLast);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
replay() {
|
|
14
|
-
return [...this.entries];
|
|
15
|
-
}
|
|
16
|
-
flush() {
|
|
17
|
-
this.flushed = true;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { loadArchiveMetadata } from '../_archive_helper.js';
|
|
2
|
-
const SNAPSHOT = loadArchiveMetadata('types');
|
|
3
|
-
export const ARCHIVE_NAME = SNAPSHOT['archive_name'];
|
|
4
|
-
export const MODULE_COUNT = SNAPSHOT['module_count'];
|
|
5
|
-
export const SAMPLE_FILES = SNAPSHOT['sample_files'];
|
|
6
|
-
export const PORTING_NOTE = `Python placeholder package for '${ARCHIVE_NAME}' with ${MODULE_COUNT} archived module references.`;
|
|
7
|
-
export default {
|
|
8
|
-
ARCHIVE_NAME,
|
|
9
|
-
MODULE_COUNT,
|
|
10
|
-
PORTING_NOTE,
|
|
11
|
-
SAMPLE_FILES,
|
|
12
|
-
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { loadArchiveMetadata } from '../_archive_helper.js';
|
|
2
|
-
const SNAPSHOT = loadArchiveMetadata('upstream_proxy');
|
|
3
|
-
export const ARCHIVE_NAME = SNAPSHOT['archive_name'];
|
|
4
|
-
export const MODULE_COUNT = SNAPSHOT['module_count'];
|
|
5
|
-
export const SAMPLE_FILES = SNAPSHOT['sample_files'];
|
|
6
|
-
export const PORTING_NOTE = `Python placeholder package for '${ARCHIVE_NAME}' with ${MODULE_COUNT} archived module references.`;
|
|
7
|
-
export default {
|
|
8
|
-
ARCHIVE_NAME,
|
|
9
|
-
MODULE_COUNT,
|
|
10
|
-
PORTING_NOTE,
|
|
11
|
-
SAMPLE_FILES,
|
|
12
|
-
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { loadArchiveMetadata } from '../_archive_helper.js';
|
|
2
|
-
const SNAPSHOT = loadArchiveMetadata('utils');
|
|
3
|
-
export const ARCHIVE_NAME = SNAPSHOT['archive_name'];
|
|
4
|
-
export const MODULE_COUNT = SNAPSHOT['module_count'];
|
|
5
|
-
export const SAMPLE_FILES = SNAPSHOT['sample_files'];
|
|
6
|
-
export const PORTING_NOTE = `Python placeholder package for '${ARCHIVE_NAME}' with ${MODULE_COUNT} archived module references.`;
|
|
7
|
-
export default {
|
|
8
|
-
ARCHIVE_NAME,
|
|
9
|
-
MODULE_COUNT,
|
|
10
|
-
PORTING_NOTE,
|
|
11
|
-
SAMPLE_FILES,
|
|
12
|
-
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { loadArchiveMetadata } from '../_archive_helper.js';
|
|
2
|
-
const SNAPSHOT = loadArchiveMetadata('vim');
|
|
3
|
-
export const ARCHIVE_NAME = SNAPSHOT['archive_name'];
|
|
4
|
-
export const MODULE_COUNT = SNAPSHOT['module_count'];
|
|
5
|
-
export const SAMPLE_FILES = SNAPSHOT['sample_files'];
|
|
6
|
-
export const PORTING_NOTE = `Python placeholder package for '${ARCHIVE_NAME}' with ${MODULE_COUNT} archived module references.`;
|
|
7
|
-
export default {
|
|
8
|
-
ARCHIVE_NAME,
|
|
9
|
-
MODULE_COUNT,
|
|
10
|
-
PORTING_NOTE,
|
|
11
|
-
SAMPLE_FILES,
|
|
12
|
-
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { loadArchiveMetadata } from '../_archive_helper.js';
|
|
2
|
-
const SNAPSHOT = loadArchiveMetadata('voice');
|
|
3
|
-
export const ARCHIVE_NAME = SNAPSHOT['archive_name'];
|
|
4
|
-
export const MODULE_COUNT = SNAPSHOT['module_count'];
|
|
5
|
-
export const SAMPLE_FILES = SNAPSHOT['sample_files'];
|
|
6
|
-
export const PORTING_NOTE = `Python placeholder package for '${ARCHIVE_NAME}' with ${MODULE_COUNT} archived module references.`;
|
|
7
|
-
export default {
|
|
8
|
-
ARCHIVE_NAME,
|
|
9
|
-
MODULE_COUNT,
|
|
10
|
-
PORTING_NOTE,
|
|
11
|
-
SAMPLE_FILES,
|
|
12
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { AgentCoordinator } from '../src/agent/coordinator.js';
|
|
3
|
-
describe('AgentCoordinator', () => {
|
|
4
|
-
it('dispatches parallel tasks', async () => {
|
|
5
|
-
const coordinator = new AgentCoordinator(2);
|
|
6
|
-
const results = await coordinator.dispatch('one two three four', 2);
|
|
7
|
-
expect(results.length).toBe(2);
|
|
8
|
-
expect(results.every(r => r.success)).toBe(true);
|
|
9
|
-
});
|
|
10
|
-
it('aggregates results in order', async () => {
|
|
11
|
-
const coordinator = new AgentCoordinator(2);
|
|
12
|
-
const results = await coordinator.dispatch('a b c d', 3);
|
|
13
|
-
const ids = results.map(r => r.taskId);
|
|
14
|
-
expect(ids).toEqual(ids.sort());
|
|
15
|
-
});
|
|
16
|
-
});
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { ToolPermissionContext } from '../src/constraint/permission.js';
|
|
3
|
-
import { BudgetTracker } from '../src/constraint/budget.js';
|
|
4
|
-
describe('ToolPermissionContext', () => {
|
|
5
|
-
it('blocks denied tools by exact name', () => {
|
|
6
|
-
const ctx = ToolPermissionContext.fromIterables(['BashTool', 'FileEditTool'], []);
|
|
7
|
-
expect(ctx.blocks('BashTool')).toBe(true);
|
|
8
|
-
expect(ctx.blocks('FileEditTool')).toBe(true);
|
|
9
|
-
expect(ctx.blocks('FileReadTool')).toBe(false);
|
|
10
|
-
});
|
|
11
|
-
it('blocks tools by prefix', () => {
|
|
12
|
-
const ctx = ToolPermissionContext.fromIterables([], ['mcp_']);
|
|
13
|
-
expect(ctx.blocks('mcp_server')).toBe(true);
|
|
14
|
-
expect(ctx.blocks('mcp_client')).toBe(true);
|
|
15
|
-
expect(ctx.blocks('bash_tool')).toBe(false);
|
|
16
|
-
});
|
|
17
|
-
it('creates permission denial', () => {
|
|
18
|
-
const ctx = ToolPermissionContext.fromIterables(['BashTool'], []);
|
|
19
|
-
const denial = ctx.createDenial('BashTool', 'destructive shell execution');
|
|
20
|
-
expect(denial.toolName).toBe('BashTool');
|
|
21
|
-
expect(denial.reason).toBe('destructive shell execution');
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
describe('BudgetTracker', () => {
|
|
25
|
-
it('tracks token usage', () => {
|
|
26
|
-
const tracker = new BudgetTracker(1000, 8, 12);
|
|
27
|
-
const usage = tracker.addTurn(100, 50);
|
|
28
|
-
expect(usage.inputTokens).toBe(100);
|
|
29
|
-
expect(usage.outputTokens).toBe(50);
|
|
30
|
-
});
|
|
31
|
-
it('detects budget exceeded', () => {
|
|
32
|
-
const tracker = new BudgetTracker(100, 8, 12);
|
|
33
|
-
expect(tracker.isBudgetExceeded({ inputTokens: 60, outputTokens: 50 })).toBe(true);
|
|
34
|
-
expect(tracker.isBudgetExceeded({ inputTokens: 30, outputTokens: 30 })).toBe(false);
|
|
35
|
-
});
|
|
36
|
-
it('detects turn limit', () => {
|
|
37
|
-
const tracker = new BudgetTracker(1000, 5, 12);
|
|
38
|
-
expect(tracker.isTurnLimitExceeded(4)).toBe(false);
|
|
39
|
-
expect(tracker.isTurnLimitExceeded(5)).toBe(true);
|
|
40
|
-
});
|
|
41
|
-
});
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { SkillRegistry } from '../src/skills/skill-registry.js';
|
|
3
|
-
describe('SkillRegistry', () => {
|
|
4
|
-
it('registers and retrieves skills', async () => {
|
|
5
|
-
const registry = new SkillRegistry();
|
|
6
|
-
registry.register({
|
|
7
|
-
name: 'testSkill',
|
|
8
|
-
description: 'A test skill',
|
|
9
|
-
execute: async (params) => `executed with ${params.input}`
|
|
10
|
-
});
|
|
11
|
-
expect(registry.has('testSkill')).toBe(true);
|
|
12
|
-
const result = await registry.execute('testSkill', { input: 'hello' });
|
|
13
|
-
expect(result).toBe('executed with hello');
|
|
14
|
-
});
|
|
15
|
-
it('throws on unknown skill', async () => {
|
|
16
|
-
const registry = new SkillRegistry();
|
|
17
|
-
await expect(registry.execute('unknown', {})).rejects.toThrow('Skill not found');
|
|
18
|
-
});
|
|
19
|
-
});
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { DeepThinkingEngine } from '../src/thinking/engine.js';
|
|
3
|
-
describe('DeepThinkingEngine', () => {
|
|
4
|
-
it('performs thinking steps', async () => {
|
|
5
|
-
const engine = new DeepThinkingEngine(2);
|
|
6
|
-
const result = await engine.think('test prompt');
|
|
7
|
-
expect(result.originalPrompt).toBe('test prompt');
|
|
8
|
-
expect(result.steps.length).toBe(2);
|
|
9
|
-
expect(result.depth).toBe(2);
|
|
10
|
-
});
|
|
11
|
-
it('respects max depth', async () => {
|
|
12
|
-
const engine = new DeepThinkingEngine(5);
|
|
13
|
-
const result = await engine.think('deep thought');
|
|
14
|
-
expect(result.steps.length).toBe(5);
|
|
15
|
-
});
|
|
16
|
-
it('allows depth adjustment', async () => {
|
|
17
|
-
const engine = new DeepThinkingEngine(1);
|
|
18
|
-
engine.setDepth(3);
|
|
19
|
-
const result = await engine.think('adjustable');
|
|
20
|
-
expect(result.steps.length).toBe(3);
|
|
21
|
-
});
|
|
22
|
-
});
|
|
@@ -1,365 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pi Ant Colony Integration for Bolloon
|
|
3
|
-
*
|
|
4
|
-
* Multi-agent collaboration system with white-box signal protocol.
|
|
5
|
-
* Based on oh-pi's ant colony system: COLONY_SIGNAL protocol for agent coordination.
|
|
6
|
-
*
|
|
7
|
-
* Signal Protocol:
|
|
8
|
-
* COLONY_SIGNAL:LAUNCHED → SCOUTING → WORKING → REVIEWING → COMPLETE
|
|
9
|
-
*
|
|
10
|
-
* Key features:
|
|
11
|
-
* - Fully visible signal protocol (no black boxes)
|
|
12
|
-
* - Per-ant turn limits, cost tracking, concurrent scheduling
|
|
13
|
-
* - White-box design: no "what is it doing in the background" anxiety
|
|
14
|
-
*/
|
|
15
|
-
import { EventEmitter } from 'events';
|
|
16
|
-
import * as fs from 'fs/promises';
|
|
17
|
-
import * as path from 'path';
|
|
18
|
-
// Colony state
|
|
19
|
-
const ants = new Map();
|
|
20
|
-
const tasks = new Map();
|
|
21
|
-
const signalHistory = [];
|
|
22
|
-
const STATE_DIR = path.join(process.env.HOME || '/tmp', '.bolloon', 'colony');
|
|
23
|
-
// Event emitter
|
|
24
|
-
class ColonyEventEmitter extends EventEmitter {
|
|
25
|
-
}
|
|
26
|
-
const colonyEvents = new ColonyEventEmitter();
|
|
27
|
-
/**
|
|
28
|
-
* Generate a unique ant ID
|
|
29
|
-
*/
|
|
30
|
-
function generateAntId() {
|
|
31
|
-
return `ant-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Register a new ant in the colony
|
|
35
|
-
*/
|
|
36
|
-
export function registerAnt(name, role, maxTurns = 10, tokenBudget = 50000) {
|
|
37
|
-
const id = generateAntId();
|
|
38
|
-
const ant = {
|
|
39
|
-
id,
|
|
40
|
-
name,
|
|
41
|
-
role,
|
|
42
|
-
signal: 'LAUNCHED',
|
|
43
|
-
turnCount: 0,
|
|
44
|
-
maxTurns,
|
|
45
|
-
tokenBudget,
|
|
46
|
-
tokensUsed: 0,
|
|
47
|
-
createdAt: new Date().toISOString(),
|
|
48
|
-
updatedAt: new Date().toISOString(),
|
|
49
|
-
};
|
|
50
|
-
ants.set(id, ant);
|
|
51
|
-
emitSignal(id, 'LAUNCHED');
|
|
52
|
-
console.log(`[Colony] Registered ant: ${name} (${role})`);
|
|
53
|
-
return ant;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Emit a signal transition
|
|
57
|
-
*/
|
|
58
|
-
function emitSignal(antId, newSignal, details) {
|
|
59
|
-
const ant = ants.get(antId);
|
|
60
|
-
if (!ant)
|
|
61
|
-
return;
|
|
62
|
-
const event = {
|
|
63
|
-
antId,
|
|
64
|
-
antName: ant.name,
|
|
65
|
-
fromSignal: ant.signal,
|
|
66
|
-
toSignal: newSignal,
|
|
67
|
-
timestamp: new Date().toISOString(),
|
|
68
|
-
details,
|
|
69
|
-
};
|
|
70
|
-
signalHistory.push(event);
|
|
71
|
-
if (signalHistory.length > 100) {
|
|
72
|
-
signalHistory.shift();
|
|
73
|
-
}
|
|
74
|
-
ant.signal = newSignal;
|
|
75
|
-
ant.updatedAt = new Date().toISOString();
|
|
76
|
-
ants.set(antId, ant);
|
|
77
|
-
colonyEvents.emit('signal', event);
|
|
78
|
-
console.log(`[Colony] ${ant.name}: ${event.fromSignal} → ${event.toSignal}${details ? ` (${details})` : ''}`);
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Transition ant to SCOUTING
|
|
82
|
-
*/
|
|
83
|
-
export function antScouting(antId, task) {
|
|
84
|
-
const ant = ants.get(antId);
|
|
85
|
-
if (!ant)
|
|
86
|
-
return;
|
|
87
|
-
ant.task = task;
|
|
88
|
-
ants.set(antId, ant);
|
|
89
|
-
emitSignal(antId, 'SCOUTING', `Task: ${task.substring(0, 50)}...`);
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Transition ant to WORKING
|
|
93
|
-
*/
|
|
94
|
-
export function antWorking(antId) {
|
|
95
|
-
const ant = ants.get(antId);
|
|
96
|
-
if (!ant)
|
|
97
|
-
return;
|
|
98
|
-
emitSignal(antId, 'WORKING');
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Transition ant to REVIEWING
|
|
102
|
-
*/
|
|
103
|
-
export function antReviewing(antId) {
|
|
104
|
-
emitSignal(antId, 'REVIEWING');
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Complete ant work
|
|
108
|
-
*/
|
|
109
|
-
export function antComplete(antId, result) {
|
|
110
|
-
const ant = ants.get(antId);
|
|
111
|
-
if (!ant)
|
|
112
|
-
return;
|
|
113
|
-
ant.result = result;
|
|
114
|
-
ants.set(antId, ant);
|
|
115
|
-
emitSignal(antId, 'COMPLETE', `Result: ${result.substring(0, 50)}...`);
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Fail ant work
|
|
119
|
-
*/
|
|
120
|
-
export function antFail(antId, error) {
|
|
121
|
-
const ant = ants.get(antId);
|
|
122
|
-
if (!ant)
|
|
123
|
-
return;
|
|
124
|
-
ant.result = error;
|
|
125
|
-
ants.set(antId, ant);
|
|
126
|
-
emitSignal(antId, 'FAILED', error);
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Abort ant work
|
|
130
|
-
*/
|
|
131
|
-
export function antAbort(antId, reason) {
|
|
132
|
-
emitSignal(antId, 'ABORTED', reason);
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Increment turn count
|
|
136
|
-
*/
|
|
137
|
-
export function antTick(antId, tokensUsed = 0) {
|
|
138
|
-
const ant = ants.get(antId);
|
|
139
|
-
if (!ant)
|
|
140
|
-
return;
|
|
141
|
-
ant.turnCount++;
|
|
142
|
-
ant.tokensUsed += tokensUsed;
|
|
143
|
-
ant.updatedAt = new Date().toISOString();
|
|
144
|
-
ants.set(antId, ant);
|
|
145
|
-
// Check if exceeded limits
|
|
146
|
-
if (ant.turnCount >= ant.maxTurns) {
|
|
147
|
-
antAbort(antId, 'Max turns exceeded');
|
|
148
|
-
}
|
|
149
|
-
else if (ant.tokensUsed >= ant.tokenBudget) {
|
|
150
|
-
antAbort(antId, 'Token budget exceeded');
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Create a colony task
|
|
155
|
-
*/
|
|
156
|
-
export function createTask(description) {
|
|
157
|
-
const id = `task-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`;
|
|
158
|
-
const task = {
|
|
159
|
-
id,
|
|
160
|
-
description,
|
|
161
|
-
status: 'pending',
|
|
162
|
-
assignedAnts: [],
|
|
163
|
-
results: new Map(),
|
|
164
|
-
createdAt: new Date().toISOString(),
|
|
165
|
-
};
|
|
166
|
-
tasks.set(id, task);
|
|
167
|
-
console.log(`[Colony] Created task: ${id} - ${description.substring(0, 50)}...`);
|
|
168
|
-
return task;
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Dispatch task to ants
|
|
172
|
-
*/
|
|
173
|
-
export function dispatchTask(taskId, antIds) {
|
|
174
|
-
const task = tasks.get(taskId);
|
|
175
|
-
if (!task)
|
|
176
|
-
return;
|
|
177
|
-
task.status = 'dispatched';
|
|
178
|
-
task.assignedAnts = antIds;
|
|
179
|
-
tasks.set(taskId, task);
|
|
180
|
-
for (const antId of antIds) {
|
|
181
|
-
const ant = ants.get(antId);
|
|
182
|
-
if (ant) {
|
|
183
|
-
antScouting(antId, task.description);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
console.log(`[Colony] Dispatched task ${taskId} to ${antIds.length} ants`);
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Record ant result for a task
|
|
190
|
-
*/
|
|
191
|
-
export function recordResult(taskId, antId, result) {
|
|
192
|
-
const task = tasks.get(taskId);
|
|
193
|
-
if (!task)
|
|
194
|
-
return;
|
|
195
|
-
task.results.set(antId, result);
|
|
196
|
-
// Check if all ants completed
|
|
197
|
-
if (task.results.size === task.assignedAnts.length) {
|
|
198
|
-
task.status = 'completed';
|
|
199
|
-
task.completedAt = new Date().toISOString();
|
|
200
|
-
for (const id of task.assignedAnts) {
|
|
201
|
-
antReviewing(id);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
tasks.set(taskId, task);
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Get ant by ID
|
|
208
|
-
*/
|
|
209
|
-
export function getAnt(antId) {
|
|
210
|
-
return ants.get(antId);
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* List all ants
|
|
214
|
-
*/
|
|
215
|
-
export function listAnts() {
|
|
216
|
-
return Array.from(ants.values());
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* List ants by role
|
|
220
|
-
*/
|
|
221
|
-
export function listAntsByRole(role) {
|
|
222
|
-
return Array.from(ants.values()).filter((a) => a.role === role);
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Get ants by signal state
|
|
226
|
-
*/
|
|
227
|
-
export function listAntsBySignal(signal) {
|
|
228
|
-
return Array.from(ants.values()).filter((a) => a.signal === signal);
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Get active ants (not complete/failed/aborted)
|
|
232
|
-
*/
|
|
233
|
-
export function getActiveAnts() {
|
|
234
|
-
return Array.from(ants.values()).filter((a) => !['COMPLETE', 'FAILED', 'ABORTED'].includes(a.signal));
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Get task by ID
|
|
238
|
-
*/
|
|
239
|
-
export function getTask(taskId) {
|
|
240
|
-
return tasks.get(taskId);
|
|
241
|
-
}
|
|
242
|
-
/**
|
|
243
|
-
* List all tasks
|
|
244
|
-
*/
|
|
245
|
-
export function listTasks() {
|
|
246
|
-
return Array.from(tasks.values());
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Get signal history
|
|
250
|
-
*/
|
|
251
|
-
export function getSignalHistory() {
|
|
252
|
-
return [...signalHistory];
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Get colony status
|
|
256
|
-
*/
|
|
257
|
-
export function getColonyStatus() {
|
|
258
|
-
const antList = Array.from(ants.values());
|
|
259
|
-
const taskList = Array.from(tasks.values());
|
|
260
|
-
const signalDistribution = {
|
|
261
|
-
LAUNCHED: 0,
|
|
262
|
-
SCOUTING: 0,
|
|
263
|
-
WORKING: 0,
|
|
264
|
-
REVIEWING: 0,
|
|
265
|
-
COMPLETE: 0,
|
|
266
|
-
FAILED: 0,
|
|
267
|
-
ABORTED: 0,
|
|
268
|
-
};
|
|
269
|
-
for (const ant of antList) {
|
|
270
|
-
signalDistribution[ant.signal]++;
|
|
271
|
-
}
|
|
272
|
-
return {
|
|
273
|
-
antCount: antList.length,
|
|
274
|
-
activeAnts: antList.filter((a) => !['COMPLETE', 'FAILED', 'ABORTED'].includes(a.signal)).length,
|
|
275
|
-
taskCount: taskList.length,
|
|
276
|
-
activeTasks: taskList.filter((t) => t.status === 'in_progress' || t.status === 'dispatched').length,
|
|
277
|
-
signalDistribution,
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Subscribe to colony events
|
|
282
|
-
*/
|
|
283
|
-
export function onColonyEvent(event, callback) {
|
|
284
|
-
colonyEvents.on(event, callback);
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
|
-
* Unsubscribe from colony events
|
|
288
|
-
*/
|
|
289
|
-
export function offColonyEvent(event, callback) {
|
|
290
|
-
colonyEvents.off(event, callback);
|
|
291
|
-
}
|
|
292
|
-
/**
|
|
293
|
-
* Get formatted colony dump for debugging
|
|
294
|
-
*/
|
|
295
|
-
export function getColonyDump() {
|
|
296
|
-
const status = getColonyStatus();
|
|
297
|
-
const active = getActiveAnts();
|
|
298
|
-
let dump = '# Colony Status\n\n';
|
|
299
|
-
dump += `Ants: ${status.antCount} total, ${status.activeAnts} active\n`;
|
|
300
|
-
dump += `Tasks: ${status.taskCount} total, ${status.activeTasks} active\n\n`;
|
|
301
|
-
dump += '## Signal Distribution\n';
|
|
302
|
-
for (const [signal, count] of Object.entries(status.signalDistribution)) {
|
|
303
|
-
if (count > 0) {
|
|
304
|
-
dump += `- ${signal}: ${count}\n`;
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
dump += '\n## Active Ants\n';
|
|
308
|
-
for (const ant of active) {
|
|
309
|
-
dump += `- ${ant.name} (${ant.role}): ${ant.signal} [${ant.turnCount}/${ant.maxTurns} turns, ${ant.tokensUsed}/${ant.tokenBudget} tokens]\n`;
|
|
310
|
-
if (ant.task) {
|
|
311
|
-
dump += ` Task: ${ant.task.substring(0, 60)}...\n`;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
dump += '\n## Recent Signals\n';
|
|
315
|
-
const recent = signalHistory.slice(-10);
|
|
316
|
-
for (const event of recent.reverse()) {
|
|
317
|
-
dump += `- ${event.timestamp}: ${event.antName}: ${event.fromSignal} → ${event.toSignal}\n`;
|
|
318
|
-
}
|
|
319
|
-
return dump;
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* Persist colony state
|
|
323
|
-
*/
|
|
324
|
-
export async function persistColony() {
|
|
325
|
-
try {
|
|
326
|
-
await fs.mkdir(STATE_DIR, { recursive: true });
|
|
327
|
-
const state = {
|
|
328
|
-
ants: Array.from(ants.values()),
|
|
329
|
-
tasks: Array.from(tasks.entries()).map(([id, t]) => ({
|
|
330
|
-
...t,
|
|
331
|
-
results: Array.from(t.results.entries()),
|
|
332
|
-
})),
|
|
333
|
-
signalHistory: signalHistory.slice(-50),
|
|
334
|
-
persistedAt: new Date().toISOString(),
|
|
335
|
-
};
|
|
336
|
-
await fs.writeFile(path.join(STATE_DIR, 'colony.json'), JSON.stringify(state, null, 2));
|
|
337
|
-
console.log('[Colony] Persisted state');
|
|
338
|
-
}
|
|
339
|
-
catch (e) {
|
|
340
|
-
console.warn('[Colony] Failed to persist:', e);
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
/**
|
|
344
|
-
* Load colony state
|
|
345
|
-
*/
|
|
346
|
-
export async function loadColony() {
|
|
347
|
-
try {
|
|
348
|
-
const data = await fs.readFile(path.join(STATE_DIR, 'colony.json'), 'utf-8');
|
|
349
|
-
const state = JSON.parse(data);
|
|
350
|
-
ants.clear();
|
|
351
|
-
for (const a of state.ants) {
|
|
352
|
-
ants.set(a.id, a);
|
|
353
|
-
}
|
|
354
|
-
tasks.clear();
|
|
355
|
-
for (const t of state.tasks) {
|
|
356
|
-
tasks.set(t.id, { ...t, results: new Map(t.results) });
|
|
357
|
-
}
|
|
358
|
-
signalHistory.length = 0;
|
|
359
|
-
signalHistory.push(...state.signalHistory);
|
|
360
|
-
console.log(`[Colony] Loaded ${ants.size} ants, ${tasks.size} tasks`);
|
|
361
|
-
}
|
|
362
|
-
catch {
|
|
363
|
-
// No persisted state
|
|
364
|
-
}
|
|
365
|
-
}
|