@johpaz/hive-sdk 0.1.4 → 0.1.6
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 +129 -0
- package/README.md +78 -23
- package/bun.lock +55 -29
- 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 +17 -12
- 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 +13 -12
- package/packages/core/src/agent/acceptance-checks.ts +172 -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 +76 -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 -27
- 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 -18
- 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-backend.ts +129 -0
- package/packages/core/src/tools/web/browser-screenshot.ts +26 -5
- package/packages/core/src/tools/web/browser-service.ts +80 -35
- 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/tools/web/webview-backend.ts +412 -0
- 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/acceptance-checks.test.ts +403 -0
- package/test/agent-loop-terminal-synthesis.test.ts +32 -0
- package/test/browser-backend.test.ts +308 -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/tool-selector-runtime-tools.test.ts +117 -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,236 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hive Scheduler - Pipeline Integration
|
|
3
|
-
*
|
|
4
|
-
* Integrates cron jobs with the Hive agent pipeline.
|
|
5
|
-
* Converts cron jobs into system messages that flow through the agent system.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { CronJob, CronJobExecutionResult } from "./types";
|
|
9
|
-
import { logger } from "../utils/logger.ts";
|
|
10
|
-
import { getDb } from "../storage/SQLiteStorage.ts";
|
|
11
|
-
import { buildAgentLoop } from "../agent/AgentRunner.ts";
|
|
12
|
-
import { resolveAgentId } from "../storage/onboarding.ts";
|
|
13
|
-
import { sendToUserChannel } from "../gateway/channel-notify.ts";
|
|
14
|
-
import { addMessage } from "../agent/ConversationStore.ts";
|
|
15
|
-
import { resolveBestChannel } from "../tools/cron/index.ts";
|
|
16
|
-
|
|
17
|
-
const log = logger.child("SchedulerIntegration");
|
|
18
|
-
|
|
19
|
-
let _scheduler: { runCleanup(): void } | null = null;
|
|
20
|
-
|
|
21
|
-
export function setSchedulerForCleanup(scheduler: { runCleanup(): void }): void {
|
|
22
|
-
_scheduler = scheduler;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Execute a cron job through the agent pipeline
|
|
27
|
-
*
|
|
28
|
-
* This handler:
|
|
29
|
-
* 1. Parses the job payload
|
|
30
|
-
* 2. Builds a system message with metadata including the `task` field as instruction
|
|
31
|
-
* 3. Routes to the target agent (or Coordinator if none specified)
|
|
32
|
-
* 4. Executes the tool if tool_name is specified
|
|
33
|
-
* 5. Returns the agent response
|
|
34
|
-
*/
|
|
35
|
-
export async function executeScheduledTask(job: CronJob): Promise<CronJobExecutionResult> {
|
|
36
|
-
log.info(`[execute] Processing job "${job.name}" (${job.id})`);
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
let payload: Record<string, unknown>;
|
|
40
|
-
try {
|
|
41
|
-
payload = JSON.parse(job.payload);
|
|
42
|
-
} catch (err) {
|
|
43
|
-
log.error(`[execute] Invalid payload JSON for job "${job.id}": ${(err as Error).message}`);
|
|
44
|
-
return { success: false, error: "Invalid payload JSON" };
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const prompt = (payload.prompt || payload.message) as string | undefined;
|
|
48
|
-
if (!prompt && !payload._internal && !job.task) {
|
|
49
|
-
log.error(`[execute] Job "${job.id}" has no prompt, message, or task instruction`);
|
|
50
|
-
return { success: false, error: "Missing prompt, message, or task instruction" };
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (payload._internal === true && (payload as any).action === "cleanup") {
|
|
54
|
-
if (_scheduler) {
|
|
55
|
-
_scheduler.runCleanup();
|
|
56
|
-
} else {
|
|
57
|
-
log.warn("[execute] Cleanup job fired but scheduler instance not available");
|
|
58
|
-
}
|
|
59
|
-
log.info("[execute] Cleanup job executed");
|
|
60
|
-
return { success: true, response: "Cleanup completed" };
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Build message metadata
|
|
64
|
-
const metadata = {
|
|
65
|
-
source: "scheduler" as const,
|
|
66
|
-
task_id: job.id,
|
|
67
|
-
task_name: job.name,
|
|
68
|
-
channel: job.channel,
|
|
69
|
-
scheduled: true,
|
|
70
|
-
tool_name: job.tool_name || undefined,
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
let targetAgentId: string | null = job.agent_id || null;
|
|
74
|
-
|
|
75
|
-
if (!targetAgentId) {
|
|
76
|
-
targetAgentId = resolveAgentId(null);
|
|
77
|
-
log.debug(`[execute] No agent specified, routing to Coordinator: ${targetAgentId}`);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const db = getDb();
|
|
81
|
-
const user = db.query("SELECT id, timezone, language FROM users LIMIT 1").get() as {
|
|
82
|
-
id: string;
|
|
83
|
-
timezone: string;
|
|
84
|
-
language: string | null;
|
|
85
|
-
} | undefined;
|
|
86
|
-
|
|
87
|
-
const userTimezone = user?.timezone || "UTC";
|
|
88
|
-
const userLanguage = user?.language || "en";
|
|
89
|
-
|
|
90
|
-
const now = new Date();
|
|
91
|
-
const dateOptions: Intl.DateTimeFormatOptions = {
|
|
92
|
-
timeZone: userTimezone,
|
|
93
|
-
year: "numeric",
|
|
94
|
-
month: "long",
|
|
95
|
-
day: "numeric",
|
|
96
|
-
weekday: "long",
|
|
97
|
-
};
|
|
98
|
-
const timeOptions: Intl.DateTimeFormatOptions = {
|
|
99
|
-
timeZone: userTimezone,
|
|
100
|
-
hour: "2-digit",
|
|
101
|
-
minute: "2-digit",
|
|
102
|
-
second: "2-digit",
|
|
103
|
-
hour12: false,
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
const fecha_usuario = new Intl.DateTimeFormat(userLanguage === "es" ? "es-ES" : "en-US", dateOptions).format(now);
|
|
107
|
-
const hora_usuario = new Intl.DateTimeFormat(userLanguage === "es" ? "es-ES" : "en-US", timeOptions).format(now);
|
|
108
|
-
|
|
109
|
-
// Build the full prompt with the `task` field as the primary instruction
|
|
110
|
-
const contextPrompt = `[SCHEDULED TASK]
|
|
111
|
-
Name: ${job.name}
|
|
112
|
-
Instruction: ${job.task}
|
|
113
|
-
Type: ${job.task_type}
|
|
114
|
-
Triggered at: ${hora_usuario} on ${fecha_usuario} (${userTimezone})
|
|
115
|
-
|
|
116
|
-
${prompt || `Execute tool: ${job.tool_name}`}`;
|
|
117
|
-
|
|
118
|
-
log.debug(`[execute] Sending to agent ${targetAgentId}: "${contextPrompt.slice(0, 100)}..."`);
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
const agentLoop = buildAgentLoop({ mcpManager: undefined });
|
|
122
|
-
|
|
123
|
-
const sessionId = `sched_${job.id}_${Date.now()}`;
|
|
124
|
-
|
|
125
|
-
const agentChannel = (job.channel && job.channel !== "system")
|
|
126
|
-
? job.channel
|
|
127
|
-
: resolveBestChannel(user?.id || "");
|
|
128
|
-
|
|
129
|
-
const messages = [{ role: "user", content: contextPrompt }];
|
|
130
|
-
const stream = agentLoop.stream({ messages }, {
|
|
131
|
-
configurable: {
|
|
132
|
-
thread_id: sessionId,
|
|
133
|
-
agent_id: targetAgentId || undefined,
|
|
134
|
-
channel: agentChannel,
|
|
135
|
-
user_id: user?.id || "",
|
|
136
|
-
system_prompt: undefined,
|
|
137
|
-
raw_user_message: contextPrompt,
|
|
138
|
-
},
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
let response = "";
|
|
142
|
-
let hasError = false;
|
|
143
|
-
|
|
144
|
-
for await (const chunk of stream) {
|
|
145
|
-
if (chunk.agent?.messages) {
|
|
146
|
-
const lastMsg = chunk.agent.messages[chunk.agent.messages.length - 1];
|
|
147
|
-
if (lastMsg?.content) {
|
|
148
|
-
response += lastMsg.content;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
if (chunk.tools?.messages) {
|
|
152
|
-
for (const msg of chunk.tools.messages) {
|
|
153
|
-
if (msg.content?.error) {
|
|
154
|
-
hasError = true;
|
|
155
|
-
response += ` [Tool error: ${JSON.stringify(msg.content)}]`;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (hasError && !response) {
|
|
162
|
-
throw new Error("Agent execution returned errors");
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
log.info(`[execute] Agent response received for job "${job.name}"`);
|
|
166
|
-
|
|
167
|
-
return {
|
|
168
|
-
success: true,
|
|
169
|
-
response: response || "Task executed successfully",
|
|
170
|
-
};
|
|
171
|
-
} catch (agentErr) {
|
|
172
|
-
log.error(`[execute] Agent execution failed: ${(agentErr as Error).message}`);
|
|
173
|
-
return {
|
|
174
|
-
success: false,
|
|
175
|
-
error: `Agent execution failed: ${(agentErr as Error).message}`,
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
} catch (err) {
|
|
179
|
-
log.error(`[execute] Job execution failed: ${(err as Error).message}`);
|
|
180
|
-
return {
|
|
181
|
-
success: false,
|
|
182
|
-
error: (err as Error).message,
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Send notification to user's channel after job execution
|
|
189
|
-
*/
|
|
190
|
-
export async function notifyTaskCompletion(
|
|
191
|
-
taskId: string,
|
|
192
|
-
taskName: string,
|
|
193
|
-
success: boolean,
|
|
194
|
-
response?: string,
|
|
195
|
-
error?: string
|
|
196
|
-
): Promise<void> {
|
|
197
|
-
const db = getDb();
|
|
198
|
-
|
|
199
|
-
const task = db.query(
|
|
200
|
-
"SELECT channel, agent_id FROM cron_jobs WHERE id = ?"
|
|
201
|
-
).get(taskId) as { channel: string; agent_id: string | null } | undefined;
|
|
202
|
-
|
|
203
|
-
if (!task) {
|
|
204
|
-
log.warn(`[notify] Job "${taskId}" not found`);
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const userRow = db.query("SELECT id FROM users LIMIT 1").get() as { id: string } | undefined;
|
|
209
|
-
const userId = userRow?.id || "";
|
|
210
|
-
|
|
211
|
-
const explicitChannel = task.channel && task.channel !== "system" ? task.channel : undefined;
|
|
212
|
-
const notifyChannel = resolveBestChannel(userId, explicitChannel) || "webchat";
|
|
213
|
-
|
|
214
|
-
const status = success ? "✅" : "❌";
|
|
215
|
-
const message = success
|
|
216
|
-
? `${status} Scheduled task "${taskName}" completed\n${response || ""}`
|
|
217
|
-
: `${status} Scheduled task "${taskName}" failed\n${error || ""}`;
|
|
218
|
-
|
|
219
|
-
log.info(`[notify] Sending notification to ${notifyChannel}: "${message.slice(0, 50)}..."`);
|
|
220
|
-
|
|
221
|
-
try {
|
|
222
|
-
addMessage(userId, "assistant", message, { channel: notifyChannel });
|
|
223
|
-
} catch (e) {
|
|
224
|
-
log.warn(`[notify] Failed to persist notification to DB: ${(e as Error).message}`);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
await sendToUserChannel(notifyChannel, userId, message);
|
|
228
|
-
log.info(`[notify] Notification sent to ${notifyChannel}`);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Create the job execution handler for CronScheduler
|
|
233
|
-
*/
|
|
234
|
-
export function createTaskHandler() {
|
|
235
|
-
return executeScheduledTask;
|
|
236
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bridge Events - WebSocket event subscription for CodeBridge
|
|
3
|
-
*
|
|
4
|
-
* Manages WebSocket subscriptions for real-time CodeBridge events
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const bridgeSubscribers = new Set<{ send: (data: string) => void }>()
|
|
8
|
-
|
|
9
|
-
export function subscribeBridge(ws: { send: (data: string) => void }) {
|
|
10
|
-
bridgeSubscribers.add(ws)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function unsubscribeBridge(ws: { send: (data: string) => void }) {
|
|
14
|
-
bridgeSubscribers.delete(ws)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function emitBridgeEvent(event: { type: string; data: any }) {
|
|
18
|
-
const payload = JSON.stringify(event)
|
|
19
|
-
for (const ws of bridgeSubscribers) {
|
|
20
|
-
try {
|
|
21
|
-
ws.send(payload)
|
|
22
|
-
} catch {
|
|
23
|
-
bridgeSubscribers.delete(ws)
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1,375 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Canvas Tools - 7 tools + A2UI v0.9 tools
|
|
3
|
-
*
|
|
4
|
-
* @category canvas
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { Tool, ToolResult } from "../types.ts";
|
|
8
|
-
import { emitCanvas, removeCanvasComponent, type CanvasEventType } from "../../canvas/emitter.ts";
|
|
9
|
-
import { logger } from "../../utils/logger.ts";
|
|
10
|
-
import { canvasManager } from "../../canvas/CanvasManager.ts";
|
|
11
|
-
import { createA2UISurfaceTool, createA2UIUpdateComponentsTool, createA2UIUpdateDataModelTool, createA2UIDeleteSurfaceTool } from "../../canvas/a2ui-tools.ts";
|
|
12
|
-
import type { Config } from "../../config/loader.ts";
|
|
13
|
-
|
|
14
|
-
const log = logger.child("canvas");
|
|
15
|
-
|
|
16
|
-
// ─── Pending canvas interactions ─────────────────────────────────────────────
|
|
17
|
-
// Simple map indexed by componentId — no session ID required.
|
|
18
|
-
// Server calls resolveCanvasInteraction() when it receives canvas:interact.
|
|
19
|
-
|
|
20
|
-
interface PendingInteraction {
|
|
21
|
-
resolve: (data: unknown) => void;
|
|
22
|
-
reject: (err: Error) => void;
|
|
23
|
-
timeout: ReturnType<typeof setTimeout>;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const pendingInteractions = new Map<string, PendingInteraction>();
|
|
27
|
-
|
|
28
|
-
export function resolveCanvasInteraction(componentId: string, data: unknown): boolean {
|
|
29
|
-
const pending = pendingInteractions.get(componentId);
|
|
30
|
-
if (!pending) return false;
|
|
31
|
-
clearTimeout(pending.timeout);
|
|
32
|
-
pendingInteractions.delete(componentId);
|
|
33
|
-
pending.resolve(data);
|
|
34
|
-
return true;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function waitForCanvasInteraction(componentId: string, timeoutMs = 300000): Promise<unknown> {
|
|
38
|
-
return new Promise((resolve, reject) => {
|
|
39
|
-
const timeout = setTimeout(() => {
|
|
40
|
-
pendingInteractions.delete(componentId);
|
|
41
|
-
reject(new Error(`Interaction timeout for ${componentId}`));
|
|
42
|
-
}, timeoutMs);
|
|
43
|
-
pendingInteractions.set(componentId, { resolve, reject, timeout });
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// ─── canvas_render ───────────────────────────────────────────────────────────
|
|
48
|
-
|
|
49
|
-
export const canvasRenderTool: Tool = {
|
|
50
|
-
name: "canvas_render",
|
|
51
|
-
description: "Render a component or visualization on the canvas. Use specific types instead of always using card+markdown. Key types: chart (bar/line/area/pie graphs), table (tabular data), markdown (rich text), form (interactive form - waits for submit), button (interactive button), alert-dialog (confirm/cancel dialog), progress (progress bars), accordion, tabs, badge, card, bee-loader. Spanish: renderizar, visualizar, gráfico, diagrama, tabla, formulario",
|
|
52
|
-
parameters: {
|
|
53
|
-
type: "object",
|
|
54
|
-
properties: {
|
|
55
|
-
component: { type: "string", description: "Component type. Visualization: chart, table, markdown, card, progress, accordion, tabs, badge, separator, bee-loader. Interactive: form, button, alert-dialog. Layout: carousel, collapsible, resizable, scroll-area, tabs. Other: alert, avatar, breadcrumb, calendar, checkbox, dialog, drawer, dropdown-menu, hover-card, input, input-otp, label, menubar, navigation-menu, pagination, popover, radio-group, select, sheet, skeleton, slider, switch, textarea, toggle, toggle-group, tooltip, aspect-ratio, command, context-menu, custom" },
|
|
56
|
-
data: { type: "object", description: "Props for the component. chart: {type:'bar'|'line'|'area'|'pie', data:[{name,...}], xKey:'name', keys:['value'], title}. table: {title, columns:[{header,key}], data:[{}]}. form: {title, fields:[{name,label,type:'text'|'email'|'number'|'textarea'|'select'|'checkbox',placeholder,options:[{value,label}]}], submitLabel}. alert-dialog: {title, description, confirmLabel, cancelLabel}. button: {label, variant:'default'|'outline'|'secondary'|'destructive'}. markdown: {content}. progress: {value:0-100}." },
|
|
57
|
-
},
|
|
58
|
-
required: ["component", "data"],
|
|
59
|
-
},
|
|
60
|
-
execute: async (params: Record<string, unknown>) => {
|
|
61
|
-
const componentType = params.component as string;
|
|
62
|
-
const data = params.data as Record<string, unknown>;
|
|
63
|
-
|
|
64
|
-
try {
|
|
65
|
-
const id = `render_${componentType}_${Date.now()}`;
|
|
66
|
-
emitCanvas("canvas:render", {
|
|
67
|
-
component: {
|
|
68
|
-
id,
|
|
69
|
-
type: componentType,
|
|
70
|
-
props: data ?? {},
|
|
71
|
-
position: { x: 0, y: 0 },
|
|
72
|
-
size: { width: 400, height: 300 },
|
|
73
|
-
agentId: "agent",
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
|
-
return { ok: true, message: `Rendered ${componentType}.` };
|
|
77
|
-
} catch (error) {
|
|
78
|
-
return { ok: false, error: `Failed to render: ${(error as Error).message }` };
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
// ─── canvas_ask ──────────────────────────────────────────────────────────────
|
|
84
|
-
|
|
85
|
-
export const canvasAskTool: Tool = {
|
|
86
|
-
name: "canvas_ask",
|
|
87
|
-
description: "Show interactive form and wait for user input. Spanish: formulario interactivo, preguntar usuario, input",
|
|
88
|
-
parameters: {
|
|
89
|
-
type: "object",
|
|
90
|
-
properties: {
|
|
91
|
-
questions: {
|
|
92
|
-
type: "array",
|
|
93
|
-
description: "List of questions to ask",
|
|
94
|
-
items: {
|
|
95
|
-
type: "object",
|
|
96
|
-
properties: {
|
|
97
|
-
question: { type: "string" },
|
|
98
|
-
type: { type: "string", enum: ["text", "select", "confirm"] },
|
|
99
|
-
options: { type: "array", items: { type: "string" } },
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
},
|
|
104
|
-
required: ["questions"],
|
|
105
|
-
},
|
|
106
|
-
execute: async (params: Record<string, unknown>, config?: any) => {
|
|
107
|
-
const questions = params.questions as any[];
|
|
108
|
-
const userId = config?.configurable?.user_id;
|
|
109
|
-
const threadId = config?.configurable?.thread_id;
|
|
110
|
-
// Use threadId (session) if available, then userId, then default
|
|
111
|
-
// This must match the WebSocket sessionId used by the frontend
|
|
112
|
-
const sessionId = threadId ? `canvas:${threadId}` : userId ? `canvas:${userId}` : "canvas:default";
|
|
113
|
-
|
|
114
|
-
// Convert questions to form fields
|
|
115
|
-
const fields = questions.map((q, idx) => ({
|
|
116
|
-
name: `field_${idx}`,
|
|
117
|
-
label: q.question,
|
|
118
|
-
type: q.type === "select" ? "select" : q.type === "confirm" ? "text" : "text",
|
|
119
|
-
required: true,
|
|
120
|
-
options: q.options?.map((opt: string) => ({ label: opt, value: opt })),
|
|
121
|
-
}));
|
|
122
|
-
|
|
123
|
-
const formId = `form-${Date.now()}`;
|
|
124
|
-
|
|
125
|
-
try {
|
|
126
|
-
// Render form via canvasManager
|
|
127
|
-
await canvasManager.render(sessionId, {
|
|
128
|
-
id: formId,
|
|
129
|
-
type: "form",
|
|
130
|
-
props: {
|
|
131
|
-
title: "Input Required",
|
|
132
|
-
fields,
|
|
133
|
-
},
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
// Wait for user interaction
|
|
137
|
-
const response = await canvasManager.waitForInteraction(sessionId, formId, 300000);
|
|
138
|
-
|
|
139
|
-
return {
|
|
140
|
-
ok: true,
|
|
141
|
-
message: "Form submitted by user",
|
|
142
|
-
data: response,
|
|
143
|
-
formId,
|
|
144
|
-
};
|
|
145
|
-
} catch (error) {
|
|
146
|
-
return {
|
|
147
|
-
ok: false,
|
|
148
|
-
error: `Form interaction failed: ${(error as Error).message}`,
|
|
149
|
-
formId,
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
},
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
// ─── canvas_confirm ──────────────────────────────────────────────────────────
|
|
156
|
-
|
|
157
|
-
export const canvasConfirmTool: Tool = {
|
|
158
|
-
name: "canvas_confirm",
|
|
159
|
-
description: "Show a confirmation dialog before executing an action. Spanish: confirmar acción, diálogo, aprobar",
|
|
160
|
-
parameters: {
|
|
161
|
-
type: "object",
|
|
162
|
-
properties: {
|
|
163
|
-
message: { type: "string", description: "Confirmation message" },
|
|
164
|
-
action: { type: "string", description: "Action to confirm" },
|
|
165
|
-
},
|
|
166
|
-
required: ["message", "action"],
|
|
167
|
-
},
|
|
168
|
-
execute: async (params: Record<string, unknown>, config?: any) => {
|
|
169
|
-
const message = params.message as string;
|
|
170
|
-
const action = params.action as string;
|
|
171
|
-
|
|
172
|
-
const confirmId = `confirm-${Date.now()}`;
|
|
173
|
-
|
|
174
|
-
emitCanvas("canvas:render", {
|
|
175
|
-
component: {
|
|
176
|
-
id: confirmId,
|
|
177
|
-
type: "alert-dialog",
|
|
178
|
-
props: { title: action, description: message, confirmLabel: "Confirmar", cancelLabel: "Cancelar" },
|
|
179
|
-
position: { x: 0, y: 0 },
|
|
180
|
-
size: { width: 400, height: 200 },
|
|
181
|
-
agentId: "agent",
|
|
182
|
-
},
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
try {
|
|
186
|
-
const interactionData = await waitForCanvasInteraction(confirmId, 300000) as any;
|
|
187
|
-
removeCanvasComponent(confirmId);
|
|
188
|
-
const confirmed = interactionData?.confirmed === true;
|
|
189
|
-
return { ok: true, confirmed, action, message };
|
|
190
|
-
} catch (error) {
|
|
191
|
-
removeCanvasComponent(confirmId);
|
|
192
|
-
return { ok: false, confirmed: false, error: (error as Error).message };
|
|
193
|
-
}
|
|
194
|
-
},
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
// ─── canvas_show_card ────────────────────────────────────────────────────────
|
|
198
|
-
|
|
199
|
-
export const canvasShowCardTool: Tool = {
|
|
200
|
-
name: "canvas_show_card",
|
|
201
|
-
description: "Display structured information in card format. Spanish: mostrar tarjeta, card, información estructurada",
|
|
202
|
-
parameters: {
|
|
203
|
-
type: "object",
|
|
204
|
-
properties: {
|
|
205
|
-
title: { type: "string", description: "Card title" },
|
|
206
|
-
content: { type: "string", description: "Card content (Markdown supported)" },
|
|
207
|
-
items: {
|
|
208
|
-
type: "array",
|
|
209
|
-
description: "List of key-value items",
|
|
210
|
-
items: {
|
|
211
|
-
type: "object",
|
|
212
|
-
properties: {
|
|
213
|
-
label: { type: "string" },
|
|
214
|
-
value: { type: "string" },
|
|
215
|
-
},
|
|
216
|
-
},
|
|
217
|
-
},
|
|
218
|
-
},
|
|
219
|
-
required: ["title"],
|
|
220
|
-
},
|
|
221
|
-
execute: async (params: Record<string, unknown>) => {
|
|
222
|
-
const title = params.title as string;
|
|
223
|
-
const content = params.content as string | undefined;
|
|
224
|
-
const items = (params.items as Array<{ label: string; value: string }>) || [];
|
|
225
|
-
|
|
226
|
-
try {
|
|
227
|
-
const id = `card_${Date.now()}`;
|
|
228
|
-
emitCanvas("canvas:render", {
|
|
229
|
-
component: {
|
|
230
|
-
id,
|
|
231
|
-
type: "card",
|
|
232
|
-
props: {
|
|
233
|
-
title,
|
|
234
|
-
children: content ?? (items.length > 0 ? items.map((item) => `**${item.label}:** ${item.value}`).join("\n") : ""),
|
|
235
|
-
// Pass items as table rows for richer rendering
|
|
236
|
-
items,
|
|
237
|
-
},
|
|
238
|
-
position: { x: 0, y: 0 },
|
|
239
|
-
size: { width: 320, height: 200 },
|
|
240
|
-
agentId: "agent",
|
|
241
|
-
},
|
|
242
|
-
});
|
|
243
|
-
return { ok: true, message: `Card "${title}" displayed.` };
|
|
244
|
-
} catch (error) {
|
|
245
|
-
return { ok: false, error: `Failed to display card: ${(error as Error).message }` };
|
|
246
|
-
}
|
|
247
|
-
},
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
// ─── canvas_show_progress ────────────────────────────────────────────────────
|
|
251
|
-
|
|
252
|
-
export const canvasShowProgressTool: Tool = {
|
|
253
|
-
name: "canvas_show_progress",
|
|
254
|
-
description: "Show progress bar or status indicator. Spanish: barra de progreso, indicador, progreso visual",
|
|
255
|
-
parameters: {
|
|
256
|
-
type: "object",
|
|
257
|
-
properties: {
|
|
258
|
-
bars: {
|
|
259
|
-
type: "array",
|
|
260
|
-
description: "List of progress bars",
|
|
261
|
-
items: {
|
|
262
|
-
type: "object",
|
|
263
|
-
properties: {
|
|
264
|
-
label: { type: "string" },
|
|
265
|
-
value: { type: "number", minimum: 0, maximum: 100 },
|
|
266
|
-
},
|
|
267
|
-
},
|
|
268
|
-
},
|
|
269
|
-
},
|
|
270
|
-
required: ["bars"],
|
|
271
|
-
},
|
|
272
|
-
execute: async (params: Record<string, unknown>) => {
|
|
273
|
-
const bars = params.bars as Array<{ label: string; value: number }>;
|
|
274
|
-
|
|
275
|
-
try {
|
|
276
|
-
// Render each bar as a separate progress component
|
|
277
|
-
for (const bar of bars) {
|
|
278
|
-
const id = `progress_${bar.label.replace(/\s+/g, "_")}_${Date.now()}`;
|
|
279
|
-
emitCanvas("canvas:render", {
|
|
280
|
-
component: {
|
|
281
|
-
id,
|
|
282
|
-
type: "progress",
|
|
283
|
-
props: { value: bar.value, label: bar.label },
|
|
284
|
-
position: { x: 0, y: 0 },
|
|
285
|
-
size: { width: 320, height: 60 },
|
|
286
|
-
agentId: "agent",
|
|
287
|
-
},
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
return { ok: true, message: "Progress displayed." };
|
|
291
|
-
} catch (error) {
|
|
292
|
-
return { ok: false, error: `Failed to display progress: ${(error as Error).message }` };
|
|
293
|
-
}
|
|
294
|
-
},
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
// ─── canvas_show_list ────────────────────────────────────────────────────────
|
|
298
|
-
|
|
299
|
-
export const canvasShowListTool: Tool = {
|
|
300
|
-
name: "canvas_show_list",
|
|
301
|
-
description: "Display key-value list information. Spanish: lista clave-valor, mostrar lista, información en lista",
|
|
302
|
-
parameters: {
|
|
303
|
-
type: "object",
|
|
304
|
-
properties: {
|
|
305
|
-
title: { type: "string", description: "List title" },
|
|
306
|
-
items: {
|
|
307
|
-
type: "object",
|
|
308
|
-
description: "Key-value pairs",
|
|
309
|
-
additionalProperties: { type: "string" },
|
|
310
|
-
},
|
|
311
|
-
},
|
|
312
|
-
required: ["title", "items"],
|
|
313
|
-
},
|
|
314
|
-
execute: async (params: Record<string, unknown>) => {
|
|
315
|
-
const title = params.title as string;
|
|
316
|
-
const items = params.items as Record<string, string>;
|
|
317
|
-
|
|
318
|
-
try {
|
|
319
|
-
const id = `list_${Date.now()}`;
|
|
320
|
-
// Render as a table with key/value columns
|
|
321
|
-
const columns = [{ header: "Campo", key: "key" }, { header: "Valor", key: "value" }];
|
|
322
|
-
const data = Object.entries(items).map(([key, value]) => ({ key, value }));
|
|
323
|
-
|
|
324
|
-
emitCanvas("canvas:render", {
|
|
325
|
-
component: {
|
|
326
|
-
id,
|
|
327
|
-
type: "table",
|
|
328
|
-
props: { title, columns, data },
|
|
329
|
-
position: { x: 0, y: 0 },
|
|
330
|
-
size: { width: 400, height: 300 },
|
|
331
|
-
agentId: "agent",
|
|
332
|
-
},
|
|
333
|
-
});
|
|
334
|
-
return { ok: true, message: `List "${title}" displayed.` };
|
|
335
|
-
} catch (error) {
|
|
336
|
-
return { ok: false, error: `Failed to display list: ${(error as Error).message }` };
|
|
337
|
-
}
|
|
338
|
-
},
|
|
339
|
-
};
|
|
340
|
-
|
|
341
|
-
// ─── canvas_clear ────────────────────────────────────────────────────────────
|
|
342
|
-
|
|
343
|
-
export const canvasClearTool: Tool = {
|
|
344
|
-
name: "canvas_clear",
|
|
345
|
-
description: "Clear current canvas content. Spanish: limpiar canvas, borrar visualización, resetear",
|
|
346
|
-
parameters: {
|
|
347
|
-
type: "object",
|
|
348
|
-
properties: {},
|
|
349
|
-
},
|
|
350
|
-
execute: async () => {
|
|
351
|
-
try {
|
|
352
|
-
emitCanvas("canvas:clear", {});
|
|
353
|
-
return { ok: true, message: "Canvas cleared." };
|
|
354
|
-
} catch (error) {
|
|
355
|
-
return { ok: false, error: `Failed to clear canvas: ${(error as Error).message }` };
|
|
356
|
-
}
|
|
357
|
-
},
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
export function createTools(config?: Config): Tool[] {
|
|
361
|
-
const a2uiConfig = config ?? {} as Config;
|
|
362
|
-
return [
|
|
363
|
-
canvasRenderTool,
|
|
364
|
-
canvasAskTool,
|
|
365
|
-
canvasConfirmTool,
|
|
366
|
-
canvasShowCardTool,
|
|
367
|
-
canvasShowProgressTool,
|
|
368
|
-
canvasShowListTool,
|
|
369
|
-
canvasClearTool,
|
|
370
|
-
createA2UISurfaceTool(a2uiConfig),
|
|
371
|
-
createA2UIUpdateComponentsTool(a2uiConfig),
|
|
372
|
-
createA2UIUpdateDataModelTool(a2uiConfig),
|
|
373
|
-
createA2UIDeleteSurfaceTool(a2uiConfig),
|
|
374
|
-
];
|
|
375
|
-
}
|