@johpaz/hive-sdk 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/CHANGELOG.md +97 -0
- package/README.md +78 -23
- package/bunfig.toml +4 -2
- package/docs/API-AGENTS.md +78 -27
- package/docs/API-CONTEXT-COMPILER.md +31 -34
- package/docs/API-TOOLS-SKILLS-CHANNELS.md +58 -22
- package/docs/HIVE-HARNESS.md +1 -1
- package/docs/INDEX.md +4 -4
- package/docs/TEMPLATE-HIVE-APP.md +10 -10
- package/package.json +9 -4
- package/packages/cli/package.json +2 -2
- package/packages/cli/src/commands/create-app.test.ts +36 -7
- package/packages/cli/src/commands/init.ts +3 -3
- package/packages/cli/src/commands/run.ts +1 -1
- package/packages/cli/src/commands/test.ts +37 -25
- package/packages/cli/src/commands/trace.ts +30 -28
- package/packages/cli/templates/hive-app/.env.example +10 -2
- package/packages/cli/templates/hive-app/README.md +103 -0
- package/packages/cli/templates/hive-app/hive.config.ts +9 -3
- package/packages/cli/templates/hive-app/src/agents/coordinator.ts +8 -1
- package/packages/cli/templates/hive-app/src/main.ts +12 -19
- package/packages/core/package.json +5 -4
- package/packages/core/src/agent/acceptance-checks.ts +166 -0
- package/packages/core/src/agent/agent-catalog.ts +348 -0
- package/packages/core/src/agent/agent-loop.ts +1373 -0
- package/packages/core/src/agent/capability-search.ts +186 -0
- package/packages/core/src/agent/catalog-selector.ts +103 -0
- package/packages/core/src/agent/{Compaction.ts → compaction.ts} +86 -63
- package/packages/core/src/agent/context-compiler.ts +689 -0
- package/packages/core/src/agent/conversation-store.ts +381 -0
- package/packages/core/src/agent/curator.ts +276 -0
- package/packages/core/src/agent/delegation-runtime.ts +241 -0
- package/packages/core/src/agent/goal-runner.ts +323 -0
- package/packages/core/src/agent/index.ts +17 -12
- package/packages/core/src/agent/llm-client.ts +266 -0
- package/packages/core/src/agent/llm-providers/anthropic.ts +264 -0
- package/packages/core/src/agent/llm-providers/deepseek.ts +8 -0
- package/packages/core/src/agent/{providers → llm-providers}/gemini.ts +98 -60
- package/packages/core/src/agent/llm-providers/groq.ts +5 -0
- package/packages/core/src/agent/llm-providers/hiveagents.ts +253 -0
- package/packages/core/src/agent/{providers → llm-providers}/interface.ts +73 -13
- package/packages/core/src/agent/llm-providers/kimi.ts +8 -0
- package/packages/core/src/agent/llm-providers/minimax.ts +13 -0
- package/packages/core/src/agent/llm-providers/mistral.ts +5 -0
- package/packages/core/src/agent/llm-providers/modelscope.ts +5 -0
- package/packages/core/src/agent/llm-providers/nvidia.ts +5 -0
- package/packages/core/src/agent/{providers → llm-providers}/ollama.ts +31 -5
- package/packages/core/src/agent/llm-providers/openai-compat-base.ts +418 -0
- package/packages/core/src/agent/llm-providers/openai.ts +5 -0
- package/packages/core/src/agent/llm-providers/opencode-go.ts +9 -0
- package/packages/core/src/agent/llm-providers/openrouter.ts +5 -0
- package/packages/core/src/agent/llm-providers/qwen.ts +5 -0
- package/packages/core/src/agent/llm-providers/z-ai.ts +5 -0
- package/packages/core/src/agent/minimal-loadout.ts +47 -0
- package/packages/core/src/agent/playbook-selector.ts +119 -0
- package/packages/core/src/agent/{PromptBuilder.ts → prompt-builder.ts} +21 -22
- package/packages/core/src/{harness → agent}/proof-packet.ts +16 -21
- package/packages/core/src/agent/providers/index.ts +35 -16
- package/packages/core/src/agent/reflector.ts +320 -0
- package/packages/core/src/agent/routing-intent.ts +22 -0
- package/packages/core/src/{harness → agent}/run-epoch.ts +4 -3
- package/packages/core/src/{harness → agent}/run-store.ts +142 -81
- package/packages/core/src/agent/{Service.ts → service.ts} +37 -26
- package/packages/core/src/agent/skill-selector.ts +374 -0
- package/packages/core/src/agent/stuck-loop.ts +209 -0
- package/packages/core/src/agent/{selectors/ToolSelector.ts → tool-selector.ts} +188 -178
- package/packages/core/src/{ace/Tracer.ts → agent/tracer.ts} +37 -27
- package/packages/core/src/api/createAgent.test.ts +139 -27
- package/packages/core/src/api/createAgent.ts +232 -44
- package/packages/core/src/artifacts/store.ts +162 -0
- package/packages/core/src/canvas/canvas-manager.ts +161 -0
- package/packages/core/src/canvas/canvas.test.ts +8 -4
- package/packages/core/src/canvas/emitter.ts +131 -80
- package/packages/core/src/canvas/index.ts +1 -3
- package/packages/core/src/channels/base.ts +9 -1
- package/packages/core/src/channels/discord.ts +5 -4
- package/packages/core/src/channels/manager.ts +122 -30
- package/packages/core/src/channels/slack.ts +5 -4
- package/packages/core/src/channels/telegram.ts +36 -6
- package/packages/core/src/channels/webchat.ts +11 -10
- package/packages/core/src/channels/whatsapp.ts +23 -7
- package/packages/core/src/config/index.ts +13 -2
- package/packages/core/src/config/loader.ts +71 -29
- package/packages/core/src/ethics/EthicsGuard.test.ts +90 -36
- package/packages/core/src/ethics/EthicsGuard.ts +51 -47
- package/packages/core/src/events/agent-bus.ts +44 -68
- package/packages/core/src/events/channel-narration.ts +150 -0
- package/packages/core/src/events/narration.ts +82 -0
- package/packages/core/src/events/tool-narration.ts +62 -0
- package/packages/core/src/gateway/delegation-groups.ts +258 -0
- package/packages/core/src/{harness → gateway}/durable-queue.ts +102 -42
- package/packages/core/src/{harness → gateway}/job-store.ts +85 -48
- package/packages/core/src/gateway/lane-queue.ts +173 -0
- package/packages/core/src/gateway/notification-inbox.ts +57 -0
- package/packages/core/src/gateway/server.ts +1 -1
- package/packages/core/src/harness/index.ts +46 -27
- package/packages/core/src/index.ts +33 -20
- package/packages/core/src/mcp/hot-reload.ts +32 -23
- package/packages/core/src/mcp/index.ts +6 -3
- package/packages/core/src/mcp/singleton.ts +1 -4
- package/packages/core/src/mcp/tool-sync.ts +138 -0
- package/packages/core/src/memory/Scratchpad.test.ts +39 -20
- package/packages/core/src/memory/Scratchpad.ts +27 -34
- package/packages/core/src/multimodal/vision-service.ts +44 -38
- package/packages/core/src/resilience/retry.ts +95 -0
- package/packages/core/src/scheduler/CronScheduler.ts +334 -287
- package/packages/core/src/scheduler/index.ts +9 -7
- package/packages/core/src/scheduler/integration.ts +46 -26
- package/packages/core/src/scheduler/scheduler.test.ts +9 -13
- package/packages/core/src/scheduler/types.ts +7 -2
- package/packages/core/src/security/Pairing.ts +1 -1
- package/packages/core/src/skills/bundled/a2ui/a2ui_dashboard/SKILL.md +176 -0
- package/packages/core/src/skills/bundled/a2ui/a2ui_form/SKILL.md +202 -0
- package/packages/core/src/skills/bundled/a2ui/a2ui_interactive/SKILL.md +206 -0
- package/packages/core/src/skills/bundled/agents/agent_spawner/SKILL.md +173 -0
- package/packages/core/src/skills/bundled/agents/memory_manager/SKILL.md +143 -0
- package/packages/core/src/skills/bundled/agents/research_and_remember/SKILL.md +139 -0
- package/packages/core/src/skills/bundled/agents/task_orchestrator/SKILL.md +98 -0
- package/packages/core/src/skills/bundled/api/api_client/SKILL.md +132 -0
- package/packages/core/src/skills/bundled/cli/cli_pipeline/SKILL.md +135 -0
- package/packages/core/src/skills/bundled/cli/cli_safe_exec/SKILL.md +125 -0
- package/packages/core/src/skills/bundled/cli/software_engineering/SKILL.md +23 -0
- package/packages/core/src/skills/bundled/cron_manager/SKILL.md +188 -0
- package/packages/core/src/skills/bundled/cron_reminder/SKILL.md +112 -0
- package/packages/core/src/skills/bundled/filesystem/file_manager/SKILL.md +118 -0
- package/packages/core/src/skills/bundled/filesystem/file_read_and_summarize/SKILL.md +109 -0
- package/packages/core/src/skills/bundled/filesystem/file_writer/SKILL.md +129 -0
- package/packages/core/src/skills/bundled/filesystem/workspace_file_operator/SKILL.md +22 -0
- package/packages/core/src/skills/bundled/office/office_document_manager/SKILL.md +262 -0
- package/packages/core/src/skills/bundled/search_knowledge/capability_discovery/SKILL.md +75 -0
- package/packages/core/src/skills/bundled/web/browser_automate/SKILL.md +120 -0
- package/packages/core/src/skills/bundled/web/browser_scrape/SKILL.md +109 -0
- package/packages/core/src/skills/bundled/web/web_monitor/SKILL.md +127 -0
- package/packages/core/src/skills/bundled/web/web_research/SKILL.md +119 -0
- package/packages/core/src/skills/bundled-data.generated.ts +731 -2678
- package/packages/core/src/skills/skills.test.ts +52 -11
- package/packages/core/src/{harness → storage}/boot-id.ts +5 -2
- package/packages/core/src/storage/bootstrap.ts +151 -0
- package/packages/core/src/storage/causal-events.ts +84 -0
- package/packages/core/src/storage/collections.ts +680 -0
- package/packages/core/src/storage/crypto.ts +205 -74
- package/packages/core/src/{harness/db-helpers.ts → storage/hive.ts} +63 -7
- package/packages/core/src/storage/hivedb.ts +61 -0
- package/packages/core/src/storage/index.ts +111 -17
- package/packages/core/src/storage/model-id.ts +53 -0
- package/packages/core/src/storage/onboarding.ts +540 -972
- package/packages/core/src/storage/reconcile.ts +238 -0
- package/packages/core/src/storage/seed.ts +572 -406
- package/packages/core/src/storage/usage.ts +285 -225
- package/packages/core/src/storage/user-email.ts +11 -0
- package/packages/core/src/swarm/AgentExecutor.ts +1 -1
- package/packages/core/src/swarm/EventBridge.ts +1 -1
- package/packages/core/src/swarm/index.ts +12 -9
- package/packages/core/src/tool-runtime/index.ts +146 -23
- package/packages/core/src/tool-runtime/tool-worker.ts +2 -2
- package/packages/core/src/tool-runtime/worker-tools.ts +27 -0
- package/packages/core/src/{canvas/a2ui-tools.ts → tools/a2ui/index.ts} +17 -8
- package/packages/core/src/tools/agents/get-available-models.ts +36 -54
- package/packages/core/src/tools/agents/index.ts +784 -292
- package/packages/core/src/tools/api/api-request.test.ts +164 -0
- package/packages/core/src/tools/api/api-request.ts +174 -0
- package/packages/core/src/tools/api/index.ts +16 -0
- package/packages/core/src/tools/cli/index.ts +4 -0
- package/packages/core/src/tools/core/index.ts +281 -112
- package/packages/core/src/tools/cron/index.ts +121 -124
- package/packages/core/src/tools/index.ts +63 -78
- package/packages/core/src/tools/office/office-escribir-xlsx.ts +3 -1
- package/packages/core/src/tools/types.ts +3 -1
- package/packages/core/src/tools/web/artifact-inspect.ts +23 -0
- package/packages/core/src/tools/web/browser-screenshot.ts +26 -5
- package/packages/core/src/tools/web/browser-service.ts +5 -0
- package/packages/core/src/tools/web/browser-type.ts +3 -8
- package/packages/core/src/tools/web/index.ts +4 -4
- package/packages/core/src/voice/index.ts +89 -63
- package/packages/core/src/workers/agent.worker.ts +2 -2
- package/packages/core/src/workers/workers.test.ts +3 -10
- package/scripts/bump-version.ts +248 -0
- package/scripts/generate-skill-bundle.ts +108 -0
- package/test/agent-loop-terminal-synthesis.test.ts +32 -0
- package/test/catalog-agents-stay-enabled.test.ts +117 -0
- package/test/causal-events.test.ts +117 -0
- package/test/compaction.test.ts +105 -0
- package/test/context-compiler.test.ts +269 -0
- package/test/curator.test.ts +130 -0
- package/test/durable-queue.test.ts +114 -0
- package/test/harness-barrel.test.ts +64 -0
- package/test/hive-helpers.test.ts +130 -0
- package/test/hivedb-search.test.ts +189 -0
- package/test/internal-turns.test.ts +166 -0
- package/test/job-idempotency.test.ts +68 -0
- package/test/job-retry-backoff.test.ts +184 -0
- package/test/job-store.test.ts +381 -0
- package/test/llm-retry.test.ts +97 -0
- package/test/memory-perf.test.ts +774 -0
- package/test/minimal-loadout.test.ts +78 -0
- package/test/model-catalog.test.ts +105 -0
- package/test/preload.ts +12 -0
- package/test/reflector.test.ts +320 -0
- package/test/retention-cap.test.ts +91 -0
- package/test/retired-capabilities-pruned.test.ts +192 -0
- package/test/run-store.test.ts +355 -0
- package/test/scratchpad.test.ts +74 -0
- package/test/secrets-durability.test.ts +119 -0
- package/test/seed-model-reseed.test.ts +155 -0
- package/test/setup-agent-seed.test.ts +264 -0
- package/test/tool-inventory.test.ts +65 -0
- package/test/tool-runtime.test.ts +258 -0
- package/test/toon.test.ts +429 -0
- package/tsconfig.json +2 -0
- package/packages/core/src/ace/Curator.ts +0 -158
- package/packages/core/src/ace/Reflector.ts +0 -200
- package/packages/core/src/ace/index.ts +0 -4
- package/packages/core/src/agent/AgentRunner.ts +0 -711
- package/packages/core/src/agent/ContextCompiler.ts +0 -567
- package/packages/core/src/agent/ContextGuard.ts +0 -91
- package/packages/core/src/agent/ConversationStore.ts +0 -254
- package/packages/core/src/agent/Hooks.ts +0 -166
- package/packages/core/src/agent/StuckLoop.ts +0 -133
- package/packages/core/src/agent/providers/LLMClient.ts +0 -149
- package/packages/core/src/agent/providers/anthropic.ts +0 -212
- package/packages/core/src/agent/providers/openai-compat.ts +0 -231
- package/packages/core/src/agent/selectors/PlaybookSelector.ts +0 -121
- package/packages/core/src/agent/selectors/SkillSelector.ts +0 -322
- package/packages/core/src/agent/selectors/index.ts +0 -6
- package/packages/core/src/auth/auth.ts +0 -121
- package/packages/core/src/auth/index.ts +0 -1
- package/packages/core/src/canvas/CanvasManager.ts +0 -390
- package/packages/core/src/canvas/canvas-tools.ts +0 -448
- package/packages/core/src/harness/collections.ts +0 -98
- package/packages/core/src/harness/goal-verifier.ts +0 -141
- package/packages/core/src/harness/harness.test.ts +0 -236
- package/packages/core/src/harness/reconcile.ts +0 -149
- package/packages/core/src/mcp/MCPToolAdapter.ts +0 -176
- package/packages/core/src/multimodal/VisionService.ts +0 -293
- package/packages/core/src/scheduler/dag/AgentExecutor.ts +0 -53
- package/packages/core/src/scheduler/dag/DAGScheduler.ts +0 -250
- package/packages/core/src/scheduler/dag/EventBridge.ts +0 -122
- package/packages/core/src/scheduler/dag/TaskGraph.ts +0 -192
- package/packages/core/src/scheduler/dag/TaskNode.ts +0 -97
- package/packages/core/src/scheduler/dag/TaskResult.ts +0 -22
- package/packages/core/src/scheduler/dag/errors.ts +0 -37
- package/packages/core/src/scheduler/dag/index.ts +0 -26
- package/packages/core/src/scheduler/dag/presets/ResearchPreset.ts +0 -97
- package/packages/core/src/scheduler/dag/strategies/ParallelStrategy.ts +0 -21
- package/packages/core/src/scheduler/dag/strategies/PriorityStrategy.ts +0 -46
- package/packages/core/src/storage/HiveDBStorage.ts +0 -64
- package/packages/core/src/storage/SQLiteStorage.ts +0 -414
- package/packages/core/src/storage/hiveSeed.ts +0 -308
- package/packages/core/src/storage/hiveStorage.test.ts +0 -38
- package/packages/core/src/storage/schema.ts +0 -689
- package/packages/core/src/storage/storage.test.ts +0 -37
- package/packages/core/src/swarm/AgentBus.ts +0 -460
- package/packages/core/src/swarm/EventBus.ts +0 -169
- package/packages/core/src/swarm/WorkerPool.ts +0 -236
- package/packages/core/src/tools/bridge-events.ts +0 -26
- package/packages/core/src/tools/canvas/index.ts +0 -375
- package/packages/core/src/tools/codebridge/index.ts +0 -342
- package/packages/core/src/tools/meeting/index.ts +0 -353
- package/packages/core/src/tools/projects/index.ts +0 -37
- package/packages/core/src/tools/projects/project-create.ts +0 -94
- package/packages/core/src/tools/projects/project-done.ts +0 -66
- package/packages/core/src/tools/projects/project-fail.ts +0 -66
- package/packages/core/src/tools/projects/project-list.ts +0 -96
- package/packages/core/src/tools/projects/project-update.ts +0 -72
- package/packages/core/src/tools/projects/task-create.ts +0 -68
- package/packages/core/src/tools/projects/task-evaluate.ts +0 -93
- package/packages/core/src/tools/projects/task-update.ts +0 -93
- package/packages/core/src/tools/voice/index.ts +0 -104
- package/packages/core/src/tools/web/api-request.test.ts +0 -170
- package/packages/core/src/tools/web/api-request.ts +0 -239
- package/test/setup-db.ts +0 -216
- /package/packages/core/src/agent/{NativeTools.ts → native-tools.ts} +0 -0
|
@@ -1,78 +1,137 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { logger } from "../utils/logger
|
|
1
|
+
import { col, nextId, bumpRollup } from "./hive";
|
|
2
|
+
import type { ModelDoc, UsageRecordDoc, UsageRollupDoc } from "./collections";
|
|
3
|
+
import { logger } from "../utils/logger";
|
|
4
4
|
|
|
5
5
|
const log = logger.child("usage");
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Costo de una llamada, en USD.
|
|
9
|
+
*
|
|
10
|
+
* El precio vive en la propia fila del modelo (`ModelDoc.input_per_1m` /
|
|
11
|
+
* `output_per_1m`), sembrada desde SEED_DATA.models. Antes había acá un mapa
|
|
12
|
+
* `MODEL_PRICING` hardcodeado en paralelo al catálogo: mantener dos listas en
|
|
13
|
+
* sincronía fallaba en silencio — un modelo sembrado sin entrada en el mapa
|
|
14
|
+
* costaba $0 sin avisar.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** Precio por id de modelo. Se llena bajo demanda y lo invalida el re-seed. */
|
|
18
|
+
let pricingCache: Map<string, { input: number; output: number } | null> | null = null;
|
|
19
|
+
|
|
20
|
+
/** Llamar cuando el catálogo cambie, para que el próximo costo relea de la BD. */
|
|
21
|
+
export function invalidateModelPricingCache(): void {
|
|
22
|
+
pricingCache = null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function loadPricing(): Promise<Map<string, { input: number; output: number } | null>> {
|
|
26
|
+
if (pricingCache) return pricingCache;
|
|
27
|
+
const cache = new Map<string, { input: number; output: number } | null>();
|
|
28
|
+
try {
|
|
29
|
+
const modelsCol = await col<ModelDoc>("models");
|
|
30
|
+
for (const row of await modelsCol.scan({})) {
|
|
31
|
+
const { input_per_1m: i, output_per_1m: o } = row.doc;
|
|
32
|
+
cache.set(row.id, i == null && o == null ? null : { input: i ?? 0, output: o ?? 0 });
|
|
33
|
+
}
|
|
34
|
+
pricingCache = cache;
|
|
35
|
+
} catch {
|
|
36
|
+
// La BD puede no estar lista todavía (arranque temprano): no cachear el
|
|
37
|
+
// resultado vacío o el costo quedaría en 0 para toda la vida del proceso.
|
|
38
|
+
return cache;
|
|
39
|
+
}
|
|
40
|
+
return cache;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Modelos ya avisados, para no repetir el warning en cada llamada. */
|
|
44
|
+
const unpricedModels = new Set<string>();
|
|
45
|
+
|
|
46
|
+
export async function calculateCost(
|
|
47
|
+
provider: string,
|
|
48
|
+
model: string,
|
|
49
|
+
inputTokens: number,
|
|
50
|
+
outputTokens: number
|
|
51
|
+
): Promise<number> {
|
|
52
|
+
const pricing = (await loadPricing()).get(model);
|
|
53
|
+
|
|
54
|
+
if (!pricing) {
|
|
55
|
+
// Sin esto un modelo sin tarifa aparece como $0.00 en el dashboard, que es
|
|
56
|
+
// indistinguible de un modelo realmente gratuito.
|
|
57
|
+
const key = `${provider}/${model}`;
|
|
58
|
+
if (!unpricedModels.has(key)) {
|
|
59
|
+
unpricedModels.add(key);
|
|
60
|
+
log.warn(`[usage] Sin tarifa para ${key} — su costo se contará como $0. Agregá inputPer1M/outputPer1M en SEED_DATA.models (storage/seed.ts).`);
|
|
61
|
+
}
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return (inputTokens / 1_000_000) * pricing.input + (outputTokens / 1_000_000) * pricing.output;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Hourly bucket key ("2026-07-09T14") — lexicographic order matches chronological order. */
|
|
69
|
+
export function hourBucket(ts: number): string {
|
|
70
|
+
return new Date(ts).toISOString().slice(0, 13);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function emptyRollup(): UsageRollupDoc {
|
|
74
|
+
return {
|
|
75
|
+
inputTokens: 0, outputTokens: 0, costUsd: 0,
|
|
76
|
+
toonSavedTokens: 0, toonSavedCost: 0, toonSavedBytes: 0,
|
|
77
|
+
toonJsonTokens: 0, toonToonTokens: 0, toonJsonBytes: 0,
|
|
78
|
+
byProvider: {}, byModel: {},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Applies the top-level token/cost delta exactly once, plus both the
|
|
84
|
+
* byProvider and byModel nested breakdowns, in a single read-modify-write.
|
|
85
|
+
* `bumpRollup`'s generic helper only supports one nested dimension per call —
|
|
86
|
+
* calling it twice here would double-apply the top-level delta.
|
|
87
|
+
*/
|
|
88
|
+
async function bumpUsageRollup(
|
|
89
|
+
hour: string,
|
|
90
|
+
delta: { inputTokens: number; outputTokens: number; costUsd: number },
|
|
91
|
+
provider: string,
|
|
92
|
+
model: string
|
|
93
|
+
): Promise<void> {
|
|
94
|
+
const rollupsCol = await col<UsageRollupDoc>("usageRollups");
|
|
95
|
+
const MAX_RETRIES = 5;
|
|
96
|
+
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
97
|
+
const existing = await rollupsCol.get(hour);
|
|
98
|
+
// Merge over emptyRollup() defaults, not just the raw existing doc — a rollup
|
|
99
|
+
// for this hour may have been created by recordToonSavings()'s generic
|
|
100
|
+
// bumpRollup() call, which never initializes byProvider/byModel.
|
|
101
|
+
const doc = existing ? { ...emptyRollup(), ...existing.doc } : emptyRollup();
|
|
102
|
+
|
|
103
|
+
doc.inputTokens += delta.inputTokens;
|
|
104
|
+
doc.outputTokens += delta.outputTokens;
|
|
105
|
+
doc.costUsd += delta.costUsd;
|
|
106
|
+
|
|
107
|
+
const curProvider = doc.byProvider[provider] ?? { inputTokens: 0, outputTokens: 0, costUsd: 0 };
|
|
108
|
+
doc.byProvider = {
|
|
109
|
+
...doc.byProvider,
|
|
110
|
+
[provider]: {
|
|
111
|
+
inputTokens: curProvider.inputTokens + delta.inputTokens,
|
|
112
|
+
outputTokens: curProvider.outputTokens + delta.outputTokens,
|
|
113
|
+
costUsd: curProvider.costUsd + delta.costUsd,
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const curModel = doc.byModel[model] ?? { inputTokens: 0, outputTokens: 0, costUsd: 0 };
|
|
118
|
+
doc.byModel = {
|
|
119
|
+
...doc.byModel,
|
|
120
|
+
[model]: {
|
|
121
|
+
inputTokens: curModel.inputTokens + delta.inputTokens,
|
|
122
|
+
outputTokens: curModel.outputTokens + delta.outputTokens,
|
|
123
|
+
costUsd: curModel.costUsd + delta.costUsd,
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
await rollupsCol.put(hour, doc, { expectedVersion: existing?.version ?? 0 });
|
|
129
|
+
return;
|
|
130
|
+
} catch {
|
|
131
|
+
// Version conflict — retry with a fresh read.
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
log.warn(`[USAGE] bumpUsageRollup: too much contention on usageRollups/${hour}`);
|
|
76
135
|
}
|
|
77
136
|
|
|
78
137
|
export interface UsageRecord {
|
|
@@ -112,163 +171,145 @@ export interface UsageSummary {
|
|
|
112
171
|
recentRecords: UsageRecord[];
|
|
113
172
|
}
|
|
114
173
|
|
|
115
|
-
export
|
|
174
|
+
export function recordUsage(options: {
|
|
116
175
|
provider: string;
|
|
117
176
|
model: string;
|
|
118
177
|
inputTokens: number;
|
|
119
178
|
outputTokens: number;
|
|
120
179
|
latencyMs?: number;
|
|
121
|
-
}):
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
id
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
180
|
+
}): void {
|
|
181
|
+
// Fire-and-forget to avoid blocking the LLM call path.
|
|
182
|
+
Promise.resolve().then(async () => {
|
|
183
|
+
try {
|
|
184
|
+
const costUsd = await calculateCost(options.provider, options.model, options.inputTokens, options.outputTokens);
|
|
185
|
+
const now = Date.now();
|
|
186
|
+
|
|
187
|
+
const id = await nextId("usageRecords");
|
|
188
|
+
const recordsCol = await col<UsageRecordDoc>("usageRecords");
|
|
189
|
+
await recordsCol.put(id, {
|
|
190
|
+
id,
|
|
191
|
+
provider: options.provider,
|
|
192
|
+
model: options.model,
|
|
193
|
+
input_tokens: options.inputTokens,
|
|
194
|
+
output_tokens: options.outputTokens,
|
|
195
|
+
cost_usd: costUsd,
|
|
196
|
+
latency_ms: options.latencyMs || null,
|
|
197
|
+
toon_saved_tokens: 0,
|
|
198
|
+
toon_saved_cost: 0,
|
|
199
|
+
toon_json_bytes: 0,
|
|
200
|
+
toon_toon_bytes: 0,
|
|
201
|
+
toon_saved_bytes: 0,
|
|
202
|
+
toon_saved_percent: 0,
|
|
203
|
+
toon_json_tokens: 0,
|
|
204
|
+
toon_toon_tokens: 0,
|
|
205
|
+
toon_saved_tokens_pct: 0,
|
|
206
|
+
created_at: now,
|
|
207
|
+
}, { expectedVersion: 0 });
|
|
208
|
+
|
|
209
|
+
const hour = hourBucket(now);
|
|
210
|
+
const delta = { inputTokens: options.inputTokens, outputTokens: options.outputTokens, costUsd };
|
|
211
|
+
await bumpUsageRollup(hour, delta, options.provider, options.model);
|
|
212
|
+
|
|
213
|
+
log.info(`[USAGE RECORDED] provider=${options.provider} model=${options.model} input=${options.inputTokens} output=${options.outputTokens} cost=$${costUsd.toFixed(4)}`);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
console.error("Failed to record usage:", error);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** Every hour bucket key from `hours` ago through now, oldest first. */
|
|
221
|
+
function hourBucketsSince(hours: number): string[] {
|
|
222
|
+
const now = Date.now();
|
|
223
|
+
const buckets: string[] = [];
|
|
224
|
+
for (let t = now - hours * 3600_000; t <= now; t += 3600_000) {
|
|
225
|
+
buckets.push(hourBucket(t));
|
|
150
226
|
}
|
|
227
|
+
return buckets;
|
|
151
228
|
}
|
|
152
229
|
|
|
153
230
|
export async function getUsageStats(hours: number = 24): Promise<UsageSummary> {
|
|
154
231
|
log.info(`[USAGE STATS] Fetching stats for last ${hours} hours`);
|
|
155
|
-
|
|
156
|
-
const
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const records = entries.map(e => e.doc).filter(r => r.created_at >= since);
|
|
161
|
-
|
|
162
|
-
const totals = records.reduce((acc, r) => ({
|
|
163
|
-
total_input: acc.total_input + r.input_tokens,
|
|
164
|
-
total_output: acc.total_output + r.output_tokens,
|
|
165
|
-
total_cost: acc.total_cost + r.cost_usd,
|
|
166
|
-
toon_saved_tokens: acc.toon_saved_tokens + r.toon_saved_tokens,
|
|
167
|
-
toon_saved_cost: acc.toon_saved_cost + r.toon_saved_cost,
|
|
168
|
-
toon_saved_bytes: acc.toon_saved_bytes + r.toon_saved_bytes,
|
|
169
|
-
toon_saved_percent: acc.toon_saved_percent + r.toon_saved_percent,
|
|
170
|
-
toon_json_tokens: acc.toon_json_tokens + r.toon_json_tokens,
|
|
171
|
-
toon_toon_tokens: acc.toon_toon_tokens + r.toon_toon_tokens,
|
|
172
|
-
}), {
|
|
173
|
-
total_input: 0,
|
|
174
|
-
total_output: 0,
|
|
175
|
-
total_cost: 0,
|
|
176
|
-
toon_saved_tokens: 0,
|
|
177
|
-
toon_saved_cost: 0,
|
|
178
|
-
toon_saved_bytes: 0,
|
|
179
|
-
toon_saved_percent: 0,
|
|
180
|
-
toon_json_tokens: 0,
|
|
181
|
-
toon_toon_tokens: 0,
|
|
182
|
-
});
|
|
232
|
+
|
|
233
|
+
const rollupsCol = await col<UsageRollupDoc>("usageRollups");
|
|
234
|
+
const buckets = hourBucketsSince(hours);
|
|
235
|
+
const rollups = (await Promise.all(buckets.map((id) => rollupsCol.get(id))))
|
|
236
|
+
.map((e) => e?.doc ?? emptyRollup());
|
|
183
237
|
|
|
184
238
|
const providerMap: UsageSummary["byProvider"] = {};
|
|
185
239
|
const modelMap: UsageSummary["byModel"] = {};
|
|
240
|
+
let totalInput = 0, totalOutput = 0, totalCost = 0;
|
|
241
|
+
let toonSavedTokens = 0, toonSavedCost = 0, toonSavedBytes = 0;
|
|
242
|
+
let toonJsonTokens = 0, toonToonTokens = 0, toonJsonBytes = 0;
|
|
186
243
|
|
|
187
|
-
for (const r of
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
244
|
+
for (const r of rollups) {
|
|
245
|
+
totalInput += r.inputTokens;
|
|
246
|
+
totalOutput += r.outputTokens;
|
|
247
|
+
totalCost += r.costUsd;
|
|
248
|
+
toonSavedTokens += r.toonSavedTokens;
|
|
249
|
+
toonSavedCost += r.toonSavedCost;
|
|
250
|
+
toonSavedBytes += r.toonSavedBytes;
|
|
251
|
+
toonJsonTokens += r.toonJsonTokens;
|
|
252
|
+
toonToonTokens += r.toonToonTokens;
|
|
253
|
+
toonJsonBytes += r.toonJsonBytes;
|
|
196
254
|
|
|
197
|
-
|
|
198
|
-
|
|
255
|
+
for (const [provider, p] of Object.entries(r.byProvider ?? {})) {
|
|
256
|
+
const cur = providerMap[provider] ?? { tokens: 0, costUsd: 0, inputTokens: 0, outputTokens: 0 };
|
|
257
|
+
cur.inputTokens += p.inputTokens;
|
|
258
|
+
cur.outputTokens += p.outputTokens;
|
|
259
|
+
cur.tokens += p.inputTokens + p.outputTokens;
|
|
260
|
+
cur.costUsd += p.costUsd;
|
|
261
|
+
providerMap[provider] = cur;
|
|
262
|
+
}
|
|
263
|
+
for (const [model, m] of Object.entries(r.byModel ?? {})) {
|
|
264
|
+
const cur = modelMap[model] ?? { provider: "unknown", tokens: 0, costUsd: 0, inputTokens: 0, outputTokens: 0 };
|
|
265
|
+
cur.inputTokens += m.inputTokens;
|
|
266
|
+
cur.outputTokens += m.outputTokens;
|
|
267
|
+
cur.tokens += m.inputTokens + m.outputTokens;
|
|
268
|
+
cur.costUsd += m.costUsd;
|
|
269
|
+
modelMap[model] = cur;
|
|
199
270
|
}
|
|
200
|
-
modelMap[r.model].inputTokens += r.input_tokens;
|
|
201
|
-
modelMap[r.model].outputTokens += r.output_tokens;
|
|
202
|
-
modelMap[r.model].tokens += r.input_tokens + r.output_tokens;
|
|
203
|
-
modelMap[r.model].costUsd += r.cost_usd;
|
|
204
271
|
}
|
|
205
272
|
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
.
|
|
273
|
+
const sinceMs = Date.now() - hours * 3600_000;
|
|
274
|
+
const recordsCol = await col<UsageRecordDoc>("usageRecords");
|
|
275
|
+
const recentRecords = (await recordsCol.scan({ reverse: true, limit: 20 }))
|
|
276
|
+
.map((e) => e.doc)
|
|
277
|
+
.filter((r) => r.created_at >= sinceMs);
|
|
210
278
|
|
|
211
|
-
const totalTokens =
|
|
212
|
-
const totalIncludingSaved = totalTokens +
|
|
279
|
+
const totalTokens = totalInput + totalOutput;
|
|
280
|
+
const totalIncludingSaved = totalTokens + toonSavedTokens;
|
|
213
281
|
const toonSavingsPercent = totalIncludingSaved > 0
|
|
214
|
-
? (
|
|
282
|
+
? (toonSavedTokens / totalIncludingSaved) * 100
|
|
215
283
|
: 0;
|
|
216
284
|
|
|
217
|
-
|
|
218
|
-
|
|
285
|
+
// Ratio-of-sums (not mean-of-per-record-percentages) — avoids bias from varying record sizes.
|
|
286
|
+
const toonSavedBytesPercent = toonJsonBytes > 0
|
|
287
|
+
? (toonSavedBytes / toonJsonBytes) * 100
|
|
219
288
|
: 0;
|
|
220
289
|
|
|
221
290
|
return {
|
|
222
291
|
totalTokens,
|
|
223
|
-
totalInputTokens:
|
|
224
|
-
totalOutputTokens:
|
|
225
|
-
totalCostUsd:
|
|
226
|
-
toonSavedTokens
|
|
227
|
-
toonSavedCost
|
|
228
|
-
toonSavedBytes
|
|
292
|
+
totalInputTokens: totalInput,
|
|
293
|
+
totalOutputTokens: totalOutput,
|
|
294
|
+
totalCostUsd: totalCost,
|
|
295
|
+
toonSavedTokens,
|
|
296
|
+
toonSavedCost,
|
|
297
|
+
toonSavedBytes,
|
|
229
298
|
toonSavedBytesPercent,
|
|
230
|
-
toonJsonTokens
|
|
231
|
-
toonToonTokens
|
|
299
|
+
toonJsonTokens,
|
|
300
|
+
toonToonTokens,
|
|
232
301
|
toonSavingsPercent,
|
|
233
302
|
byProvider: providerMap,
|
|
234
303
|
byModel: modelMap,
|
|
235
|
-
recentRecords
|
|
304
|
+
recentRecords
|
|
236
305
|
};
|
|
237
306
|
}
|
|
238
307
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
export function
|
|
244
|
-
const pricing = MODEL_PRICING[model] || { inputPer1M: 0, outputPer1M: 0 };
|
|
245
|
-
return (tokens / 1_000_000) * pricing.inputPer1M;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
export function getAverageTokenCost(model: string): number {
|
|
249
|
-
let pricing = MODEL_PRICING[model];
|
|
250
|
-
|
|
251
|
-
if (!pricing) {
|
|
252
|
-
const slashIdx = model.indexOf('/');
|
|
253
|
-
if (slashIdx !== -1) {
|
|
254
|
-
pricing = MODEL_PRICING[model.slice(slashIdx + 1)];
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
if (!pricing) {
|
|
259
|
-
for (const [key, p] of Object.entries(MODEL_PRICING)) {
|
|
260
|
-
if (model.includes(key) || key.includes(model)) {
|
|
261
|
-
pricing = p;
|
|
262
|
-
break;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if (!pricing) return 0;
|
|
268
|
-
return (pricing.inputPer1M + pricing.outputPer1M) / 2 / 1_000_000;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
export async function recordToonSavings(
|
|
308
|
+
/**
|
|
309
|
+
* Record TOON savings for metrics tracking
|
|
310
|
+
* This updates the usage_records table with complete TOON compression metrics
|
|
311
|
+
*/
|
|
312
|
+
export function recordToonSavings(
|
|
272
313
|
analysis: {
|
|
273
314
|
jsonBytes: number;
|
|
274
315
|
toonBytes: number;
|
|
@@ -281,33 +322,52 @@ export async function recordToonSavings(
|
|
|
281
322
|
},
|
|
282
323
|
costSaved: number,
|
|
283
324
|
category: string
|
|
284
|
-
):
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
325
|
+
): void {
|
|
326
|
+
// Fire-and-forget to avoid blocking
|
|
327
|
+
Promise.resolve().then(async () => {
|
|
328
|
+
try {
|
|
329
|
+
const now = Date.now();
|
|
330
|
+
const savedTokens = Math.max(0, analysis.savedTokens);
|
|
331
|
+
const savedPercent = Math.max(0, analysis.savedPercent);
|
|
332
|
+
const savedTokensPct = Math.max(0, analysis.savedTokensPercent);
|
|
333
|
+
|
|
334
|
+
// Insert TOON savings record with complete metrics
|
|
335
|
+
const id = await nextId("usageRecords");
|
|
336
|
+
const recordsCol = await col<UsageRecordDoc>("usageRecords");
|
|
337
|
+
await recordsCol.put(id, {
|
|
338
|
+
id,
|
|
339
|
+
provider: "toon",
|
|
340
|
+
model: category,
|
|
341
|
+
input_tokens: 0,
|
|
342
|
+
output_tokens: 0,
|
|
343
|
+
cost_usd: 0,
|
|
344
|
+
latency_ms: null,
|
|
345
|
+
toon_saved_tokens: savedTokens,
|
|
346
|
+
toon_saved_cost: costSaved,
|
|
347
|
+
toon_json_bytes: analysis.jsonBytes,
|
|
348
|
+
toon_toon_bytes: analysis.toonBytes,
|
|
349
|
+
toon_saved_bytes: analysis.savedBytes,
|
|
350
|
+
toon_saved_percent: savedPercent,
|
|
351
|
+
toon_json_tokens: analysis.jsonTokens,
|
|
352
|
+
toon_toon_tokens: analysis.toonTokens,
|
|
353
|
+
toon_saved_tokens_pct: savedTokensPct,
|
|
354
|
+
created_at: now,
|
|
355
|
+
}, { expectedVersion: 0 });
|
|
356
|
+
|
|
357
|
+
// Only the toon-specific fields go into the rollup — no byProvider/byModel
|
|
358
|
+
// breakdown for these (they carry no real token/cost data of their own).
|
|
359
|
+
await bumpRollup("usageRollups", hourBucket(now), {
|
|
360
|
+
toonSavedTokens: savedTokens,
|
|
361
|
+
toonSavedCost: costSaved,
|
|
362
|
+
toonSavedBytes: analysis.savedBytes,
|
|
363
|
+
toonJsonTokens: analysis.jsonTokens,
|
|
364
|
+
toonToonTokens: analysis.toonTokens,
|
|
365
|
+
toonJsonBytes: analysis.jsonBytes,
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
log.debug(`[TOON] Recorded ${analysis.savedTokens} tokens ($${costSaved.toFixed(6)}) saved for ${category}`)
|
|
369
|
+
} catch (error) {
|
|
370
|
+
log.warn(`[TOON] Failed to record savings:`, error)
|
|
371
|
+
}
|
|
372
|
+
})
|
|
313
373
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const SIMPLE_EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2
|
+
|
|
3
|
+
export function normalizeUserEmail(value: unknown): string {
|
|
4
|
+
if (typeof value !== "string") throw new Error("El correo electrónico es obligatorio.");
|
|
5
|
+
const email = value.trim().toLowerCase();
|
|
6
|
+
if (!email) throw new Error("El correo electrónico es obligatorio.");
|
|
7
|
+
if (email.length > 254 || !SIMPLE_EMAIL_PATTERN.test(email)) {
|
|
8
|
+
throw new Error("Ingresa un correo electrónico válido.");
|
|
9
|
+
}
|
|
10
|
+
return email;
|
|
11
|
+
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* concurrently without awaiting each one serially.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { runAgentIsolated } from "../agent/
|
|
13
|
+
import { runAgentIsolated } from "../agent/agent-loop.ts"
|
|
14
14
|
import { TaskNode } from "./TaskNode"
|
|
15
15
|
import { TaskTimeoutError } from "./errors"
|
|
16
16
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Also emits canvas:node_update events so the UI reflects task state in real time.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { agentBus } from "../
|
|
10
|
+
import { agentBus } from "../events/agent-bus.ts"
|
|
11
11
|
import { emitCanvas } from "../canvas/emitter.ts"
|
|
12
12
|
import { TaskNode } from "./TaskNode"
|
|
13
13
|
import { DAGResult } from "./TaskResult"
|
|
@@ -11,15 +11,18 @@ export { EventBridge } from "./EventBridge.ts";
|
|
|
11
11
|
|
|
12
12
|
export { CyclicDependencyError, TaskTimeoutError, TaskFailureError } from "./errors.ts";
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
export
|
|
19
|
-
|
|
20
|
-
export type { TypedEventBus } from "
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
// Los buses viven en events/. `swarm/AgentBus.ts` y `swarm/EventBus.ts` eran
|
|
15
|
+
// copias que escribían a SQLite; se re-exportan desde acá para no romper a quien
|
|
16
|
+
// los importaba por el subpath ./swarm.
|
|
17
|
+
export type { AgentBusEventMap, AgentBusEventKey, AgentBusEventHandler, AgentBusMessage, AgentBus } from "../events/agent-bus.ts";
|
|
18
|
+
export { getUnreadMessagesForWorker, agentBus } from "../events/agent-bus.ts";
|
|
19
|
+
|
|
20
|
+
export type { EventMap, EventKey, EventHandler, TypedEventBus } from "../events/event-bus.ts";
|
|
21
|
+
export { eventBus } from "../events/event-bus.ts";
|
|
22
|
+
|
|
23
|
+
// Ejecución de tareas agendadas: `swarm/WorkerPool.ts` era una copia rezagada de
|
|
24
|
+
// scheduler/integration.ts (mismo archivo, 18 líneas de deriva).
|
|
25
|
+
export { setSchedulerForCleanup, notifyTaskCompletion, createTaskHandler } from "../scheduler/integration.ts";
|
|
23
26
|
|
|
24
27
|
export type { ExecutionStrategy } from "./strategies/index.ts";
|
|
25
28
|
export { ParallelStrategy, PriorityStrategy } from "./strategies/index.ts";
|