@johpaz/hive-sdk 0.4.8 → 0.5.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.
- package/CHANGELOG.md +75 -1
- package/README.md +1 -1
- package/package.json +1 -1
- package/packages/core/src/agent/agent-loop.ts +92 -7
- package/packages/core/src/agent/compaction.ts +81 -35
- package/packages/core/src/agent/context-compiler.ts +122 -23
- package/packages/core/src/agent/index.ts +2 -0
- package/packages/core/src/agent/jev-decisions.ts +199 -0
- package/packages/core/src/agent/jev-planner.ts +298 -0
- package/packages/core/src/agent/tool-selector.ts +1 -0
- package/packages/core/src/canvas/emitter.ts +19 -0
- package/packages/core/src/events/channel-narration.ts +3 -0
- package/packages/core/src/services/swarms.ts +4 -0
- package/packages/core/src/storage/collections.ts +9 -2
- package/packages/core/src/storage/crypto.ts +15 -7
- package/packages/core/src/storage/seed.ts +4 -0
- package/packages/core/src/storage/usage.ts +55 -2
- package/packages/core/src/swarm/RoleSwarm.ts +6 -0
- package/packages/core/src/tool-runtime/index.ts +20 -1
- package/packages/core/src/tools/agents/get-available-models.ts +3 -1
- package/packages/core/src/tools/core/index.ts +33 -2
|
@@ -47,6 +47,8 @@ export type ExecuteToolBatchOptions = {
|
|
|
47
47
|
}
|
|
48
48
|
hiveConfig?: Config
|
|
49
49
|
workerPool?: ToolRuntimeConfig
|
|
50
|
+
/** Per-batch decision (Jev). Undefined preserves the configured behavior. */
|
|
51
|
+
parallelToolCalls?: boolean
|
|
50
52
|
mainThreadToolNames?: string[]
|
|
51
53
|
signal?: AbortSignal
|
|
52
54
|
}
|
|
@@ -199,6 +201,7 @@ const DEFAULT_MAIN_THREAD_TOOL_NAMES = new Set([
|
|
|
199
201
|
// These tools depend on process-local singleton state (HiveDB handle, live
|
|
200
202
|
// channel senders, schedulers, browser sessions, or in-memory services).
|
|
201
203
|
"search_knowledge",
|
|
204
|
+
"conversation_read",
|
|
202
205
|
"save_note",
|
|
203
206
|
"memory_write",
|
|
204
207
|
"memory_read",
|
|
@@ -670,6 +673,7 @@ export async function executeToolBatch(options: ExecuteToolBatchOptions): Promis
|
|
|
670
673
|
|
|
671
674
|
async function executeToolBatchInner(options: ExecuteToolBatchOptions): Promise<ToolBatchResult[]> {
|
|
672
675
|
const runtimeConfig = resolveRuntimeConfig(options.workerPool)
|
|
676
|
+
const parallelToolCalls = options.parallelToolCalls ?? runtimeConfig.parallelToolCalls
|
|
673
677
|
const hiveConfig = options.hiveConfig ?? loadConfig()
|
|
674
678
|
const mainThreadToolNames = [
|
|
675
679
|
...DEFAULT_MAIN_THREAD_TOOL_NAMES,
|
|
@@ -690,11 +694,26 @@ async function executeToolBatchInner(options: ExecuteToolBatchOptions): Promise<
|
|
|
690
694
|
|
|
691
695
|
// A null pool means workers are disabled, unnecessary (single call), or
|
|
692
696
|
// unavailable in this build — all three degrade to the main thread.
|
|
693
|
-
const pool = runtimeConfig.enabled &&
|
|
697
|
+
const pool = runtimeConfig.enabled && parallelToolCalls && options.toolCalls.length > 1
|
|
694
698
|
? getPool(runtimeConfig.maxWorkers)
|
|
695
699
|
: null
|
|
696
700
|
|
|
697
701
|
if (!pool) {
|
|
702
|
+
// Jev judged the batch independent: run it concurrently even without workers.
|
|
703
|
+
if (options.parallelToolCalls === true && options.toolCalls.length > 1) {
|
|
704
|
+
return Promise.all(options.toolCalls.map(async (toolCall) => {
|
|
705
|
+
const startedAt = performance.now()
|
|
706
|
+
const effectiveTimeout = resolveToolTimeout(toolCall.function.name, options.allTools, hiveConfig, runtimeConfig.toolTimeoutMs)
|
|
707
|
+
const result = await executeInMainThreadWithTimeout({
|
|
708
|
+
toolCall, allTools: options.allTools, toolConfig: options.toolConfig, signal: options.signal,
|
|
709
|
+
}, effectiveTimeout)
|
|
710
|
+
return {
|
|
711
|
+
toolCall, toolName: toolCall.function.name, result,
|
|
712
|
+
ok: !(result && typeof result === "object" && (result as any).error === true),
|
|
713
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
714
|
+
}
|
|
715
|
+
}))
|
|
716
|
+
}
|
|
698
717
|
const results: ToolBatchResult[] = []
|
|
699
718
|
for (const toolCall of options.toolCalls) {
|
|
700
719
|
const startedAt = performance.now()
|
|
@@ -60,7 +60,9 @@ export const getAvailableModelsTool: Tool = {
|
|
|
60
60
|
.filter(m => m.enabled && providersById.has(m.provider_id));
|
|
61
61
|
|
|
62
62
|
if (providerId) models = models.filter(m => m.provider_id === providerId);
|
|
63
|
-
|
|
63
|
+
// Decision models (Jev) only answer the Decisions API, never chat: an
|
|
64
|
+
// agent assigned one would fail every turn.
|
|
65
|
+
models = modelType ? models.filter(m => m.model_type === modelType) : models.filter(m => m.model_type !== "decision");
|
|
64
66
|
if (capabilities) models = models.filter(m => (m.capabilities ?? "").includes(capabilities));
|
|
65
67
|
|
|
66
68
|
// Transformar a formato amigable
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
type CapabilityType,
|
|
15
15
|
} from "../../agent/capability-search.ts";
|
|
16
16
|
import { CORE_TOOL_CATALOG } from "../../agent/tool-selector.ts";
|
|
17
|
-
import { saveScratchpadNote } from "../../agent/conversation-store.ts";
|
|
17
|
+
import { saveScratchpadNote, getRecentMessages, getScratchpad } from "../../agent/conversation-store.ts";
|
|
18
18
|
|
|
19
19
|
const log = logger.child("core");
|
|
20
20
|
|
|
@@ -503,6 +503,37 @@ export const reportProgressTool: Tool = {
|
|
|
503
503
|
},
|
|
504
504
|
};
|
|
505
505
|
|
|
506
|
+
/** Recover a small, scoped slice of conversation omitted by Jev's context plan. */
|
|
507
|
+
export const conversationReadTool: Tool = {
|
|
508
|
+
name: "conversation_read",
|
|
509
|
+
description: "Read earlier messages from the current conversation by message IDs or text query when selected context is insufficient.",
|
|
510
|
+
parameters: {
|
|
511
|
+
type: "object",
|
|
512
|
+
properties: {
|
|
513
|
+
message_ids: { type: "array", description: "Message IDs shown in the context plan", items: { type: "number" } },
|
|
514
|
+
note_keys: { type: "array", description: "Scratchpad note keys shown in the context plan", items: { type: "string" } },
|
|
515
|
+
query: { type: "string", description: "Optional case-insensitive text to search in earlier messages" },
|
|
516
|
+
},
|
|
517
|
+
},
|
|
518
|
+
execute: async (params, config) => {
|
|
519
|
+
const threadId = config?.configurable?.thread_id as string | undefined
|
|
520
|
+
if (!threadId) return { ok: false, error: "Conversation scope unavailable" }
|
|
521
|
+
const ids = new Set(Array.isArray(params.message_ids) ? params.message_ids.map(Number).filter(Number.isFinite) : [])
|
|
522
|
+
const noteKeys = new Set(Array.isArray(params.note_keys) ? params.note_keys.map(String) : [])
|
|
523
|
+
const query = String(params.query ?? "").trim().toLocaleLowerCase()
|
|
524
|
+
if (!ids.size && !noteKeys.size && !query) return { ok: false, error: "Provide message_ids, note_keys or query" }
|
|
525
|
+
const rows = await getRecentMessages(threadId, 200)
|
|
526
|
+
const notes = await getScratchpad(threadId)
|
|
527
|
+
return {
|
|
528
|
+
ok: true,
|
|
529
|
+
messages: rows.filter(row => (ids.size && ids.has(row.id)) || (query && row.content.toLocaleLowerCase().includes(query)))
|
|
530
|
+
.slice(-8).map(row => ({ id: row.id, role: row.role, source: row.source, content: row.content.slice(0, 2000) })),
|
|
531
|
+
notes: notes.filter(note => noteKeys.has(note.key) || (query && `${note.key} ${note.value}`.toLocaleLowerCase().includes(query)))
|
|
532
|
+
.slice(0, 8).map(note => ({ key: note.key, value: note.value.slice(0, 2000) })),
|
|
533
|
+
}
|
|
534
|
+
},
|
|
535
|
+
};
|
|
536
|
+
|
|
506
537
|
export function createTools(): Tool[] {
|
|
507
|
-
return [searchKnowledgeTool, notifyTool, saveNoteTool, reportProgressTool];
|
|
538
|
+
return [searchKnowledgeTool, notifyTool, saveNoteTool, reportProgressTool, conversationReadTool];
|
|
508
539
|
}
|