@johpaz/hive-sdk 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/CHANGELOG.md +306 -0
  2. package/README.md +11 -3
  3. package/package.json +10 -4
  4. package/packages/core/src/agent/agent-catalog.ts +81 -24
  5. package/packages/core/src/agent/compaction.ts +20 -1
  6. package/packages/core/src/agent/context-compiler.ts +6 -3
  7. package/packages/core/src/agent/conversation-store.ts +136 -2
  8. package/packages/core/src/agent/curator.ts +12 -3
  9. package/packages/core/src/agent/llm-providers/nvidia.ts +39 -0
  10. package/packages/core/src/agent/llm-providers/openai-compat-base.ts +38 -2
  11. package/packages/core/src/agent/playbook-selector.ts +18 -3
  12. package/packages/core/src/agent/prompt-builder.ts +2 -2
  13. package/packages/core/src/agent/providers/index.ts +36 -1
  14. package/packages/core/src/agent/reflector.ts +32 -9
  15. package/packages/core/src/agent/skill-selector.ts +2 -2
  16. package/packages/core/src/agent/thread-store.ts +43 -0
  17. package/packages/core/src/agent/tool-selector.ts +2 -0
  18. package/packages/core/src/api/createAgent.ts +66 -1
  19. package/packages/core/src/artifacts/index.ts +15 -0
  20. package/packages/core/src/artifacts/store.ts +77 -2
  21. package/packages/core/src/canvas/index.ts +9 -0
  22. package/packages/core/src/ethics/EthicsGuard.ts +7 -1
  23. package/packages/core/src/events/index.ts +18 -0
  24. package/packages/core/src/events/tool-narration.ts +4 -0
  25. package/packages/core/src/gateway/channel-notify.ts +103 -6
  26. package/packages/core/src/gateway/durable-queue.ts +13 -1
  27. package/packages/core/src/gateway/index.ts +3 -0
  28. package/packages/core/src/gateway/job-store.ts +6 -0
  29. package/packages/core/src/harness/executors.ts +493 -0
  30. package/packages/core/src/harness/index.ts +12 -2
  31. package/packages/core/src/hooks/index.ts +203 -0
  32. package/packages/core/src/images/index.ts +161 -0
  33. package/packages/core/src/index.ts +1 -0
  34. package/packages/core/src/multimodal/vision-service.ts +45 -13
  35. package/packages/core/src/resilience/index.ts +13 -0
  36. package/packages/core/src/scheduler/CronScheduler.ts +48 -21
  37. package/packages/core/src/scheduler/cron/expression.ts +165 -0
  38. package/packages/core/src/scheduler/cron/index.ts +10 -0
  39. package/packages/core/src/scheduler/cron/job.ts +339 -0
  40. package/packages/core/src/scheduler/cron/next-run.ts +121 -0
  41. package/packages/core/src/scheduler/cron/zoned-time.ts +138 -0
  42. package/packages/core/src/scheduler/index.ts +21 -3
  43. package/packages/core/src/scheduler/integration.ts +16 -5
  44. package/packages/core/src/scheduler/types.ts +3 -18
  45. package/packages/core/src/services/agents.ts +268 -0
  46. package/packages/core/src/services/cron.ts +257 -0
  47. package/packages/core/src/services/endpoints.ts +289 -0
  48. package/packages/core/src/services/ethics.ts +107 -0
  49. package/packages/core/src/services/images.ts +212 -0
  50. package/packages/core/src/services/index.ts +112 -0
  51. package/packages/core/src/services/mcp.ts +201 -0
  52. package/packages/core/src/services/memory.ts +133 -0
  53. package/packages/core/src/services/models.ts +179 -0
  54. package/packages/core/src/services/providers.ts +152 -0
  55. package/packages/core/src/services/setup.ts +222 -0
  56. package/packages/core/src/services/skills.ts +241 -0
  57. package/packages/core/src/services/swarms.ts +307 -0
  58. package/packages/core/src/services/tools.ts +106 -0
  59. package/packages/core/src/sessions/index.ts +5 -3
  60. package/packages/core/src/sessions/resolve.ts +108 -0
  61. package/packages/core/src/skills/SkillLoader.ts +8 -1
  62. package/packages/core/src/skills/bundled/artifacts/artifact_reader/SKILL.md +105 -0
  63. package/packages/core/src/skills/bundled/cron_manager/SKILL.md +21 -11
  64. package/packages/core/src/skills/bundled/images/image_editor/SKILL.md +120 -0
  65. package/packages/core/src/skills/bundled/web/browser_automate/SKILL.md +12 -3
  66. package/packages/core/src/skills/bundled/web/browser_scrape/SKILL.md +22 -7
  67. package/packages/core/src/skills/bundled-data.generated.ts +110 -12
  68. package/packages/core/src/storage/bootstrap.ts +74 -5
  69. package/packages/core/src/storage/collections.ts +106 -1
  70. package/packages/core/src/storage/crypto.ts +24 -7
  71. package/packages/core/src/storage/index.ts +2 -1
  72. package/packages/core/src/storage/onboarding.ts +59 -43
  73. package/packages/core/src/storage/reconcile.ts +6 -1
  74. package/packages/core/src/storage/seed.ts +89 -11
  75. package/packages/core/src/swarm/types.ts +3 -18
  76. package/packages/core/src/tool-runtime/embedded-worker.generated.ts +21 -0
  77. package/packages/core/src/tool-runtime/index.ts +129 -14
  78. package/packages/core/src/tools/agents/index.ts +18 -60
  79. package/packages/core/src/tools/cli/index.ts +55 -0
  80. package/packages/core/src/tools/core/index.ts +50 -2
  81. package/packages/core/src/tools/cron/index.ts +4 -4
  82. package/packages/core/src/tools/images/index.ts +130 -0
  83. package/packages/core/src/tools/index.ts +14 -1
  84. package/packages/core/src/tools/office/office-escribir-xlsx.ts +2 -1
  85. package/packages/core/src/tools/office/office-leer-xlsx.ts +2 -1
  86. package/packages/core/src/tools/office/xlsx-loader.ts +19 -0
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Tools de imagen — redimensionar, convertir y medir.
3
+ *
4
+ * Se apoyan en `Bun.Image` (ver `images/`), así que no agregan dependencias: el
5
+ * SDK ya exige Bun ≥ 1.4.
6
+ *
7
+ * Trabajan sobre **artefactos**, no sobre base64 suelto, y eso es deliberado.
8
+ * Devolver una imagen en base64 al modelo es exactamente lo que llena la
9
+ * ventana de contexto —el problema que `mcp-result-normalizer.ts` existe para
10
+ * evitar—. Acá la entrada es un `artifact_id` y la salida es otro: el modelo
11
+ * maneja referencias y sólo mira la imagen si de verdad la necesita.
12
+ *
13
+ * Como cualquier otra tool, se activan o desactivan desde el catálogo.
14
+ */
15
+
16
+ import type { Tool } from "../types.ts";
17
+ import { createArtifact, readArtifactBytes } from "../../artifacts/store.ts";
18
+ import { measureImage, transformImage, imagesSupported, type ImageFormat } from "../../images/index.ts";
19
+ import { resolveUserId } from "../../storage/onboarding.ts";
20
+ import { logger } from "../../utils/logger.ts";
21
+
22
+ const log = logger.child("tools/images");
23
+
24
+ const FORMATOS: ImageFormat[] = ["jpeg", "png", "webp", "avif", "heic"];
25
+
26
+ /** Mensaje común: sin Bun 1.4 estas tools no pueden hacer nada. */
27
+ function sinSoporte() {
28
+ return { ok: false, error: "El procesamiento de imágenes necesita Bun >= 1.4 (Bun.Image no está disponible)" };
29
+ }
30
+
31
+ async function leerArtefacto(artifactId: string) {
32
+ const datos = await readArtifactBytes(artifactId);
33
+ if (!datos) return null;
34
+ return datos;
35
+ }
36
+
37
+ export const imageMetadataTool: Tool = {
38
+ name: "image_metadata",
39
+ description:
40
+ "Lee las dimensiones y el formato de una imagen guardada, sin abrirla ni cargarla al contexto. " +
41
+ "Spanish: medir imagen, dimensiones de la imagen, tamaño de la foto, formato de imagen",
42
+ parameters: {
43
+ type: "object",
44
+ properties: {
45
+ artifact_id: { type: "string", description: "Id del artefacto que contiene la imagen" },
46
+ },
47
+ required: ["artifact_id"],
48
+ },
49
+ execute: async (params: Record<string, unknown>) => {
50
+ if (!imagesSupported()) return sinSoporte();
51
+ const id = params.artifact_id as string;
52
+ try {
53
+ const datos = await leerArtefacto(id);
54
+ if (!datos) return { ok: false, error: `No encontré el artefacto ${id}` };
55
+ const meta = await measureImage(datos.bytes);
56
+ return { ok: true, artifact_id: id, ...meta, bytes: datos.bytes.length };
57
+ } catch (error) {
58
+ return { ok: false, error: `No pude leer la imagen: ${(error as Error).message}` };
59
+ }
60
+ },
61
+ };
62
+
63
+ export const imageTransformTool: Tool = {
64
+ name: "image_transform",
65
+ description:
66
+ "Redimensiona, rota o convierte de formato una imagen guardada y devuelve un artefacto nuevo. " +
67
+ "El original no se toca. Spanish: redimensionar imagen, cambiar tamaño, convertir a webp, " +
68
+ "comprimir imagen, rotar foto, achicar imagen",
69
+ parameters: {
70
+ type: "object",
71
+ properties: {
72
+ artifact_id: { type: "string", description: "Id del artefacto de origen" },
73
+ width: { type: "number", description: "Ancho en píxeles. Si sólo se da uno, se mantiene la proporción" },
74
+ height: { type: "number", description: "Alto en píxeles" },
75
+ format: { type: "string", description: "Formato de salida", enum: FORMATOS },
76
+ quality: { type: "number", description: "1–100, sólo para formatos con pérdida", minimum: 1, maximum: 100 },
77
+ rotate: { type: "number", description: "Grados: 90, 180 o 270" },
78
+ },
79
+ required: ["artifact_id"],
80
+ },
81
+ execute: async (params: Record<string, unknown>) => {
82
+ if (!imagesSupported()) return sinSoporte();
83
+ const id = params.artifact_id as string;
84
+
85
+ const formato = params.format as ImageFormat | undefined;
86
+ if (formato && !FORMATOS.includes(formato)) {
87
+ return { ok: false, error: `Formato no soportado: ${formato}. Disponibles: ${FORMATOS.join(", ")}` };
88
+ }
89
+
90
+ try {
91
+ const datos = await leerArtefacto(id);
92
+ if (!datos) return { ok: false, error: `No encontré el artefacto ${id}` };
93
+
94
+ const { bytes, metadata } = await transformImage(datos.bytes, {
95
+ width: params.width as number | undefined,
96
+ height: params.height as number | undefined,
97
+ format: formato,
98
+ quality: params.quality as number | undefined,
99
+ rotate: params.rotate as number | undefined,
100
+ });
101
+
102
+ const userId = (await resolveUserId({}).catch(() => null)) ?? "";
103
+ const artefacto = await createArtifact({
104
+ bytes,
105
+ mimeType: `image/${metadata.format}`,
106
+ kind: "image",
107
+ userId,
108
+ });
109
+
110
+ log.info(`imagen ${id} → ${artefacto.id} (${metadata.width}x${metadata.height} ${metadata.format})`);
111
+ // Se devuelve la referencia, nunca los bytes: el base64 en el contexto es
112
+ // justo lo que se quiere evitar.
113
+ return {
114
+ ok: true,
115
+ artifact_id: artefacto.id,
116
+ width: metadata.width,
117
+ height: metadata.height,
118
+ format: metadata.format,
119
+ bytes: bytes.length,
120
+ original_bytes: datos.bytes.length,
121
+ };
122
+ } catch (error) {
123
+ return { ok: false, error: `No pude transformar la imagen: ${(error as Error).message}` };
124
+ }
125
+ },
126
+ };
127
+
128
+ export function createTools(): Tool[] {
129
+ return [imageMetadataTool, imageTransformTool];
130
+ }
@@ -13,8 +13,9 @@ import * as filesystem from "./filesystem/index.ts";
13
13
 
14
14
  // Web (10)
15
15
  import * as web from "./web/index.ts";
16
+ import * as images from "./images/index.ts";
16
17
 
17
- // Cron (8) - Croner-based scheduler tools
18
+ // Cron (8) - scheduler tools
18
19
  import * as cron from "./cron/index.ts";
19
20
 
20
21
  // CLI (1)
@@ -70,6 +71,7 @@ export function createAllTools(config: Config): Tool[] {
70
71
 
71
72
  // WEB (10)
72
73
  ...web.createTools(),
74
+ ...images.createTools(),
73
75
 
74
76
  // CRON (8)
75
77
  ...cron.createTools(),
@@ -215,3 +217,14 @@ export {
215
217
  export {
216
218
  apiRequestTool,
217
219
  } from "./api/index.ts";
220
+
221
+ // Arranque del navegador. Las browser tools existen en el catálogo desde el
222
+ // seed, pero no operan hasta que alguien levanta el servicio: quien construya
223
+ // sobre el SDK necesita poder hacerlo sin importar rutas internas.
224
+ export {
225
+ initializeBrowserService,
226
+ getBrowserService,
227
+ shutdownBrowser,
228
+ } from "./web/browser-service.ts";
229
+
230
+ export * from "./images/index.ts";
@@ -10,6 +10,7 @@ import type { Tool } from "../types.ts";
10
10
  import { logger } from "../../utils/logger.ts";
11
11
  import * as path from "node:path";
12
12
  import * as fs from "node:fs";
13
+ import { cargarXlsx } from "./xlsx-loader.ts";
13
14
 
14
15
  const log = logger.child("office-escribir-xlsx");
15
16
 
@@ -55,7 +56,7 @@ export const officeEscribirXlsxTool: Tool = {
55
56
  log.debug(`Generando XLSX: ${ruta}`);
56
57
 
57
58
  try {
58
- const XLSX = await import("xlsx");
59
+ const XLSX = await cargarXlsx();
59
60
 
60
61
  const workbook = XLSX.utils.book_new();
61
62
 
@@ -10,6 +10,7 @@ import type { Tool } from "../types.ts";
10
10
  import { logger } from "../../utils/logger.ts";
11
11
  import * as fs from "node:fs";
12
12
  import * as path from "node:path";
13
+ import { cargarXlsx } from "./xlsx-loader.ts";
13
14
 
14
15
  const log = logger.child("office-leer-xlsx");
15
16
 
@@ -55,7 +56,7 @@ export const officeLeerXlsxTool: Tool = {
55
56
  return { ok: false, error: `Archivo no encontrado: ${rutaAbsoluta}` };
56
57
  }
57
58
 
58
- const XLSX = await import("xlsx");
59
+ const XLSX = await cargarXlsx();
59
60
  const buffer = fs.readFileSync(rutaAbsoluta);
60
61
  const workbook = XLSX.read(buffer, { type: "buffer" });
61
62
 
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Carga el lector de hojas de cálculo, o explica por qué no puede.
3
+ *
4
+ * `xlsx` se importa en caliente para no pagarlo en cada arranque, y eso deja el
5
+ * fallo a merced del momento: si la dependencia no llegó a instalarse —su
6
+ * tarball se cayó una vez en mitad de un release— el usuario recibía un
7
+ * "Cannot find module" crudo en medio de una respuesta.
8
+ */
9
+ export async function cargarXlsx(): Promise<typeof import("xlsx")> {
10
+ try {
11
+ return await import("xlsx");
12
+ } catch (error) {
13
+ throw new Error(
14
+ "El soporte de hojas de cálculo no está disponible en esta instalación: " +
15
+ `falta la dependencia «xlsx» (${(error as Error).message}). ` +
16
+ "Reinstala las dependencias con `bun install` para recuperarlo.",
17
+ );
18
+ }
19
+ }