@duckmind/dm-darwin-x64 0.43.4 → 0.43.8
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/dm +0 -0
- package/extensions/.dm-extensions.json +241 -49
- package/extensions/dm-9router-ext/package.json +2 -19
- package/extensions/dm-9router-ext/src/index.js +5 -0
- package/extensions/dm-ask-user/index.js +10 -0
- package/extensions/dm-ask-user/package.json +1 -21
- package/extensions/dm-cli-anything/package.json +0 -6
- package/extensions/dm-context/package.json +2 -12
- package/extensions/dm-context/src/context.js +1 -0
- package/extensions/dm-context/src/index.js +7 -0
- package/extensions/dm-context/src/utils.js +1 -0
- package/extensions/dm-cua/package.json +0 -7
- package/extensions/dm-fff/package.json +1 -28
- package/extensions/dm-fff/src/index.js +15 -0
- package/extensions/dm-fff/src/query.js +1 -0
- package/extensions/dm-goal/package.json +2 -31
- package/extensions/dm-goal/src/goal.js +43 -0
- package/extensions/dm-grill-me/index.js +174 -0
- package/extensions/dm-grill-me/package.json +1 -26
- package/extensions/dm-image2/package.json +0 -7
- package/extensions/dm-subagents/package.json +1 -32
- package/extensions/dm-subagents/src/agents/agent-management.js +37 -0
- package/extensions/dm-subagents/src/agents/agent-memory.js +6 -0
- package/extensions/dm-subagents/src/agents/agent-scope.js +1 -0
- package/extensions/dm-subagents/src/agents/agent-selection.js +1 -0
- package/extensions/dm-subagents/src/agents/agent-serializer.js +7 -0
- package/extensions/dm-subagents/src/agents/agents.js +11 -0
- package/extensions/dm-subagents/src/agents/chain-serializer.js +12 -0
- package/extensions/dm-subagents/src/agents/frontmatter.js +6 -0
- package/extensions/dm-subagents/src/agents/identity.js +1 -0
- package/extensions/dm-subagents/src/agents/proactive-skills.js +1 -0
- package/extensions/dm-subagents/src/agents/skills.js +6 -0
- package/extensions/dm-subagents/src/extension/config.js +2 -0
- package/extensions/dm-subagents/src/extension/control-notices.js +4 -0
- package/extensions/dm-subagents/src/extension/doctor.js +16 -0
- package/extensions/dm-subagents/src/extension/fanout-child.js +231 -0
- package/extensions/dm-subagents/src/extension/index.js +367 -0
- package/extensions/dm-subagents/src/extension/rpc.js +8 -0
- package/extensions/dm-subagents/src/extension/schemas.js +1 -0
- package/extensions/dm-subagents/src/extension/{tool-description.ts → tool-description.js} +6 -126
- package/extensions/dm-subagents/src/intercom/intercom-bridge.js +13 -0
- package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +5 -0
- package/extensions/dm-subagents/src/intercom/result-intercom.js +3 -0
- package/extensions/dm-subagents/src/profiles/profiles.js +3 -0
- package/extensions/dm-subagents/src/runs/background/async-execution.js +46 -0
- package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +14 -0
- package/extensions/dm-subagents/src/runs/background/async-resume.js +8 -0
- package/extensions/dm-subagents/src/runs/background/async-status.js +12 -0
- package/extensions/dm-subagents/src/runs/background/chain-append.js +2 -0
- package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +1 -0
- package/extensions/dm-subagents/src/runs/background/completion-batcher.js +1 -0
- package/extensions/dm-subagents/src/runs/background/completion-dedupe.js +1 -0
- package/extensions/dm-subagents/src/runs/background/control-channel.js +1 -0
- package/extensions/dm-subagents/src/runs/background/fleet-view.js +17 -0
- package/extensions/dm-subagents/src/runs/background/notify.js +3 -0
- package/extensions/dm-subagents/src/runs/background/parallel-groups.js +1 -0
- package/extensions/dm-subagents/src/runs/background/result-watcher.js +8 -0
- package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +4 -0
- package/extensions/dm-subagents/src/runs/background/run-status.js +23 -0
- package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +4 -0
- package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +11 -0
- package/extensions/dm-subagents/src/runs/background/subagent-runner.js +78 -0
- package/extensions/dm-subagents/src/runs/background/top-level-async.js +1 -0
- package/extensions/dm-subagents/src/runs/background/wait.js +11 -0
- package/extensions/dm-subagents/src/runs/foreground/chain-clarify.js +12 -0
- package/extensions/dm-subagents/src/runs/foreground/chain-execution.js +102 -0
- package/extensions/dm-subagents/src/runs/foreground/execution.js +51 -0
- package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +228 -0
- package/extensions/dm-subagents/src/runs/shared/acceptance.js +3 -0
- package/extensions/dm-subagents/src/runs/shared/chain-outputs.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/completion-guard.js +3 -0
- package/extensions/dm-subagents/src/runs/shared/dm-args.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/long-running-guard.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/model-fallback.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/model-scope.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/nested-events.js +8 -0
- package/extensions/dm-subagents/src/runs/shared/nested-path.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/nested-render.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/parallel-utils.js +5 -0
- package/extensions/dm-subagents/src/runs/shared/run-history.js +5 -0
- package/extensions/dm-subagents/src/runs/shared/single-output.js +14 -0
- package/extensions/dm-subagents/src/runs/shared/structured-output.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/subagent-control.js +5 -0
- package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +22 -0
- package/extensions/dm-subagents/src/runs/shared/tool-budget.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/turn-budget.js +7 -0
- package/extensions/dm-subagents/src/runs/shared/workflow-graph.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/worktree.js +3 -0
- package/extensions/dm-subagents/src/shared/artifacts.js +2 -0
- package/extensions/dm-subagents/src/shared/atomic-json.js +1 -0
- package/extensions/dm-subagents/src/shared/child-transcript.js +5 -0
- package/extensions/dm-subagents/src/shared/file-coalescer.js +1 -0
- package/extensions/dm-subagents/src/shared/fork-context.js +6 -0
- package/extensions/dm-subagents/src/shared/formatters.js +9 -0
- package/extensions/dm-subagents/src/shared/jsonl-writer.js +2 -0
- package/extensions/dm-subagents/src/shared/model-info.js +1 -0
- package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.js +1 -0
- package/extensions/dm-subagents/src/shared/session-identity.js +1 -0
- package/extensions/dm-subagents/src/shared/session-tokens.js +2 -0
- package/extensions/dm-subagents/src/shared/settings.js +23 -0
- package/extensions/dm-subagents/src/shared/status-format.js +1 -0
- package/extensions/dm-subagents/src/shared/types.js +8 -0
- package/extensions/dm-subagents/src/shared/utils.js +2 -0
- package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +1 -0
- package/extensions/dm-subagents/src/slash/prompt-workflows.js +7 -0
- package/extensions/dm-subagents/src/slash/slash-bridge.js +1 -0
- package/extensions/dm-subagents/src/slash/slash-commands.js +38 -0
- package/extensions/dm-subagents/src/slash/slash-live-state.js +6 -0
- package/extensions/dm-subagents/src/tui/render-helpers.js +1 -0
- package/extensions/dm-subagents/src/tui/render.js +4 -0
- package/extensions/dm-tasks/package.json +1 -30
- package/extensions/dm-tasks/src/auto-clear.js +1 -0
- package/extensions/dm-tasks/src/index.js +212 -0
- package/extensions/dm-tasks/src/process-tracker.js +1 -0
- package/extensions/dm-tasks/src/task-store.js +1 -0
- package/extensions/dm-tasks/src/tasks-config.js +1 -0
- package/extensions/dm-tasks/src/types.js +0 -0
- package/extensions/dm-tasks/src/ui/settings-menu.js +1 -0
- package/extensions/dm-tasks/src/ui/task-widget.js +1 -0
- package/extensions/dm-usage/index.js +9 -0
- package/extensions/dm-usage/package.json +1 -18
- package/extensions/greedysearch-dm/index.js +20 -0
- package/extensions/greedysearch-dm/package.json +1 -22
- package/extensions/greedysearch-dm/src/formatters/results.js +8 -0
- package/extensions/greedysearch-dm/src/formatters/sources.js +1 -0
- package/extensions/greedysearch-dm/src/formatters/synthesis.js +1 -0
- package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +20 -0
- package/extensions/greedysearch-dm/src/tools/shared.js +9 -0
- package/extensions/greedysearch-dm/src/types.js +0 -0
- package/extensions/greedysearch-dm/src/utils/helpers.js +1 -0
- package/package.json +1 -1
- package/extensions/dm-9router-ext/src/index.ts +0 -541
- package/extensions/dm-ask-user/index.ts +0 -857
- package/extensions/dm-context/src/context.ts +0 -158
- package/extensions/dm-context/src/index.ts +0 -439
- package/extensions/dm-context/src/utils.ts +0 -6
- package/extensions/dm-fff/src/index.ts +0 -1023
- package/extensions/dm-fff/src/query.ts +0 -87
- package/extensions/dm-goal/src/goal.ts +0 -1073
- package/extensions/dm-grill-me/index.ts +0 -1085
- package/extensions/dm-subagents/src/agents/agent-management.ts +0 -1052
- package/extensions/dm-subagents/src/agents/agent-memory.ts +0 -254
- package/extensions/dm-subagents/src/agents/agent-scope.ts +0 -6
- package/extensions/dm-subagents/src/agents/agent-selection.ts +0 -25
- package/extensions/dm-subagents/src/agents/agent-serializer.ts +0 -121
- package/extensions/dm-subagents/src/agents/agents.ts +0 -1553
- package/extensions/dm-subagents/src/agents/chain-serializer.ts +0 -277
- package/extensions/dm-subagents/src/agents/frontmatter.ts +0 -93
- package/extensions/dm-subagents/src/agents/identity.ts +0 -30
- package/extensions/dm-subagents/src/agents/proactive-skills.ts +0 -191
- package/extensions/dm-subagents/src/agents/skills.ts +0 -729
- package/extensions/dm-subagents/src/extension/config.ts +0 -39
- package/extensions/dm-subagents/src/extension/control-notices.ts +0 -92
- package/extensions/dm-subagents/src/extension/doctor.ts +0 -214
- package/extensions/dm-subagents/src/extension/fanout-child.ts +0 -172
- package/extensions/dm-subagents/src/extension/index.ts +0 -656
- package/extensions/dm-subagents/src/extension/rpc.ts +0 -369
- package/extensions/dm-subagents/src/extension/schemas.ts +0 -309
- package/extensions/dm-subagents/src/intercom/intercom-bridge.ts +0 -180
- package/extensions/dm-subagents/src/intercom/native-supervisor-channel.ts +0 -519
- package/extensions/dm-subagents/src/intercom/result-intercom.ts +0 -377
- package/extensions/dm-subagents/src/profiles/profiles.ts +0 -637
- package/extensions/dm-subagents/src/runs/background/async-execution.ts +0 -1065
- package/extensions/dm-subagents/src/runs/background/async-job-tracker.ts +0 -441
- package/extensions/dm-subagents/src/runs/background/async-resume.ts +0 -391
- package/extensions/dm-subagents/src/runs/background/async-status.ts +0 -395
- package/extensions/dm-subagents/src/runs/background/chain-append.ts +0 -282
- package/extensions/dm-subagents/src/runs/background/chain-root-attachment.ts +0 -191
- package/extensions/dm-subagents/src/runs/background/completion-batcher.ts +0 -166
- package/extensions/dm-subagents/src/runs/background/completion-dedupe.ts +0 -63
- package/extensions/dm-subagents/src/runs/background/control-channel.ts +0 -332
- package/extensions/dm-subagents/src/runs/background/fleet-view.ts +0 -515
- package/extensions/dm-subagents/src/runs/background/notify.ts +0 -225
- package/extensions/dm-subagents/src/runs/background/parallel-groups.ts +0 -45
- package/extensions/dm-subagents/src/runs/background/result-watcher.ts +0 -315
- package/extensions/dm-subagents/src/runs/background/run-id-resolver.ts +0 -84
- package/extensions/dm-subagents/src/runs/background/run-status.ts +0 -434
- package/extensions/dm-subagents/src/runs/background/scheduled-runs.ts +0 -514
- package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.ts +0 -368
- package/extensions/dm-subagents/src/runs/background/subagent-runner.ts +0 -3171
- package/extensions/dm-subagents/src/runs/background/top-level-async.ts +0 -13
- package/extensions/dm-subagents/src/runs/background/wait.ts +0 -353
- package/extensions/dm-subagents/src/runs/foreground/chain-clarify.ts +0 -1333
- package/extensions/dm-subagents/src/runs/foreground/chain-execution.ts +0 -1313
- package/extensions/dm-subagents/src/runs/foreground/execution.ts +0 -1239
- package/extensions/dm-subagents/src/runs/foreground/subagent-executor.ts +0 -3613
- package/extensions/dm-subagents/src/runs/shared/acceptance.ts +0 -879
- package/extensions/dm-subagents/src/runs/shared/chain-outputs.ts +0 -116
- package/extensions/dm-subagents/src/runs/shared/completion-guard.ts +0 -147
- package/extensions/dm-subagents/src/runs/shared/dm-args.ts +0 -271
- package/extensions/dm-subagents/src/runs/shared/dm-spawn.ts +0 -147
- package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.ts +0 -295
- package/extensions/dm-subagents/src/runs/shared/long-running-guard.ts +0 -175
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +0 -365
- package/extensions/dm-subagents/src/runs/shared/model-fallback.ts +0 -292
- package/extensions/dm-subagents/src/runs/shared/model-scope.ts +0 -128
- package/extensions/dm-subagents/src/runs/shared/nested-events.ts +0 -908
- package/extensions/dm-subagents/src/runs/shared/nested-path.ts +0 -52
- package/extensions/dm-subagents/src/runs/shared/nested-render.ts +0 -115
- package/extensions/dm-subagents/src/runs/shared/parallel-utils.ts +0 -198
- package/extensions/dm-subagents/src/runs/shared/run-history.ts +0 -60
- package/extensions/dm-subagents/src/runs/shared/single-output.ts +0 -180
- package/extensions/dm-subagents/src/runs/shared/structured-output.ts +0 -77
- package/extensions/dm-subagents/src/runs/shared/subagent-control.ts +0 -223
- package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.ts +0 -342
- package/extensions/dm-subagents/src/runs/shared/tool-budget.ts +0 -74
- package/extensions/dm-subagents/src/runs/shared/turn-budget.ts +0 -52
- package/extensions/dm-subagents/src/runs/shared/workflow-graph.ts +0 -206
- package/extensions/dm-subagents/src/runs/shared/worktree.ts +0 -600
- package/extensions/dm-subagents/src/shared/artifacts.ts +0 -113
- package/extensions/dm-subagents/src/shared/atomic-json.ts +0 -86
- package/extensions/dm-subagents/src/shared/child-transcript.ts +0 -212
- package/extensions/dm-subagents/src/shared/file-coalescer.ts +0 -40
- package/extensions/dm-subagents/src/shared/fork-context.ts +0 -194
- package/extensions/dm-subagents/src/shared/formatters.ts +0 -133
- package/extensions/dm-subagents/src/shared/jsonl-writer.ts +0 -81
- package/extensions/dm-subagents/src/shared/model-info.ts +0 -78
- package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.ts +0 -85
- package/extensions/dm-subagents/src/shared/session-identity.ts +0 -10
- package/extensions/dm-subagents/src/shared/session-tokens.ts +0 -44
- package/extensions/dm-subagents/src/shared/settings.ts +0 -450
- package/extensions/dm-subagents/src/shared/status-format.ts +0 -49
- package/extensions/dm-subagents/src/shared/types.ts +0 -1257
- package/extensions/dm-subagents/src/shared/utils.ts +0 -554
- package/extensions/dm-subagents/src/slash/prompt-template-bridge.ts +0 -420
- package/extensions/dm-subagents/src/slash/prompt-workflows.ts +0 -330
- package/extensions/dm-subagents/src/slash/slash-bridge.ts +0 -176
- package/extensions/dm-subagents/src/slash/slash-commands.ts +0 -1296
- package/extensions/dm-subagents/src/slash/slash-live-state.ts +0 -292
- package/extensions/dm-subagents/src/tui/render-helpers.ts +0 -80
- package/extensions/dm-subagents/src/tui/render.ts +0 -1748
- package/extensions/dm-tasks/src/auto-clear.ts +0 -91
- package/extensions/dm-tasks/src/index.ts +0 -1145
- package/extensions/dm-tasks/src/process-tracker.ts +0 -140
- package/extensions/dm-tasks/src/task-store.ts +0 -305
- package/extensions/dm-tasks/src/tasks-config.ts +0 -23
- package/extensions/dm-tasks/src/types.ts +0 -40
- package/extensions/dm-tasks/src/ui/settings-menu.ts +0 -100
- package/extensions/dm-tasks/src/ui/task-widget.ts +0 -265
- package/extensions/dm-usage/index.ts +0 -1718
- package/extensions/greedysearch-dm/index.ts +0 -177
- package/extensions/greedysearch-dm/src/formatters/results.ts +0 -163
- package/extensions/greedysearch-dm/src/formatters/sources.ts +0 -116
- package/extensions/greedysearch-dm/src/formatters/synthesis.ts +0 -87
- package/extensions/greedysearch-dm/src/tools/greedy-search-handler.ts +0 -370
- package/extensions/greedysearch-dm/src/tools/shared.ts +0 -187
- package/extensions/greedysearch-dm/src/types.ts +0 -110
- package/extensions/greedysearch-dm/src/utils/helpers.ts +0 -40
|
@@ -1,370 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* greedy_search tool handler — multi-engine AI web search
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { Type } from "@sinclair/typebox";
|
|
6
|
-
|
|
7
|
-
type ExtensionAPI = {
|
|
8
|
-
registerTool(tool: Record<string, unknown>): void;
|
|
9
|
-
};
|
|
10
|
-
import { formatResults } from "../formatters/results.js";
|
|
11
|
-
import {
|
|
12
|
-
ALL_ENGINES,
|
|
13
|
-
cdpAvailable,
|
|
14
|
-
cdpMissingResult,
|
|
15
|
-
errorResult,
|
|
16
|
-
makeProgressTracker,
|
|
17
|
-
runSearch,
|
|
18
|
-
stripQuotes,
|
|
19
|
-
type ProgressUpdate,
|
|
20
|
-
type ToolResult,
|
|
21
|
-
} from "./shared.js";
|
|
22
|
-
|
|
23
|
-
type GreedySearchParams = {
|
|
24
|
-
query: string;
|
|
25
|
-
engine?: string;
|
|
26
|
-
synthesize?: boolean;
|
|
27
|
-
synthesizer?: string;
|
|
28
|
-
depth?: "fast" | "standard" | "deep" | "research" | string;
|
|
29
|
-
breadth?: number;
|
|
30
|
-
iterations?: number;
|
|
31
|
-
maxSources?: number;
|
|
32
|
-
researchOutDir?: string;
|
|
33
|
-
writeResearchBundle?: boolean;
|
|
34
|
-
fullAnswer?: boolean;
|
|
35
|
-
headless?: boolean;
|
|
36
|
-
visible?: boolean;
|
|
37
|
-
alwaysVisible?: boolean;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
type ToolTheme = {
|
|
41
|
-
fg(style: string, text: string): string;
|
|
42
|
-
bold(text: string): string;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
type RenderState = {
|
|
46
|
-
expanded: boolean;
|
|
47
|
-
isPartial?: boolean;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
class Text {
|
|
51
|
-
constructor(
|
|
52
|
-
private text: string,
|
|
53
|
-
private paddingX = 0,
|
|
54
|
-
private paddingY = 0,
|
|
55
|
-
) {}
|
|
56
|
-
|
|
57
|
-
render(width: number): string[] {
|
|
58
|
-
const horizontal = " ".repeat(this.paddingX);
|
|
59
|
-
const blank = "";
|
|
60
|
-
const contentWidth = Math.max(1, width - this.paddingX * 2);
|
|
61
|
-
const lines = this.text.split("\n").flatMap((line) => {
|
|
62
|
-
if (line.length <= contentWidth) return [`${horizontal}${line}`];
|
|
63
|
-
const wrapped: string[] = [];
|
|
64
|
-
for (let i = 0; i < line.length; i += contentWidth) {
|
|
65
|
-
wrapped.push(`${horizontal}${line.slice(i, i + contentWidth)}`);
|
|
66
|
-
}
|
|
67
|
-
return wrapped;
|
|
68
|
-
});
|
|
69
|
-
return [
|
|
70
|
-
...Array.from({ length: this.paddingY }, () => blank),
|
|
71
|
-
...lines,
|
|
72
|
-
...Array.from({ length: this.paddingY }, () => blank),
|
|
73
|
-
];
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
invalidate() {}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export function registerGreedySearchTool(dm: ExtensionAPI, baseDir: string) {
|
|
80
|
-
dm.registerTool({
|
|
81
|
-
name: "greedy_search",
|
|
82
|
-
label: "Greedy Search",
|
|
83
|
-
description:
|
|
84
|
-
"WEB/RESEARCH SEARCH ONLY — searches live web via Perplexity, Google AI, ChatGPT, and Gemini, plus opt-in research through Semantic Scholar and Logically. " +
|
|
85
|
-
"Research mode reuses the configured ~/.dm/greedyconfig engines for child searches and Gemini for planning/final synthesis. " +
|
|
86
|
-
"Research mode is the centerpiece: it plans follow-up actions, fetches sources, audits citations, " +
|
|
87
|
-
"and writes a structured research bundle on disk. " +
|
|
88
|
-
"Use for: library docs, recent framework changes, error messages, best practices, current events. " +
|
|
89
|
-
"Reports streaming progress as each engine completes.",
|
|
90
|
-
promptSnippet: "Multi-engine AI web search with streaming progress",
|
|
91
|
-
parameters: Type.Object({
|
|
92
|
-
query: Type.String({ description: "The search query" }),
|
|
93
|
-
engine: Type.String({
|
|
94
|
-
description:
|
|
95
|
-
'Engine to use: "all" (default), "perplexity", "google", "chatgpt", "gemini", "gem". Research engines: "semantic-scholar" (alias "s2") and "logically". "all" fans out to the configured engines and fetches top sources. Customize via ~/.dm/greedyconfig. Bing Copilot is still available as "bing" for signed-in users.',
|
|
96
|
-
default: "all",
|
|
97
|
-
}),
|
|
98
|
-
synthesize: Type.Optional(
|
|
99
|
-
Type.Boolean({
|
|
100
|
-
description:
|
|
101
|
-
'Only for engine="all": synthesize the multi-engine results and fetched sources. Default: false.',
|
|
102
|
-
default: false,
|
|
103
|
-
}),
|
|
104
|
-
),
|
|
105
|
-
synthesizer: Type.Optional(
|
|
106
|
-
Type.String({
|
|
107
|
-
description:
|
|
108
|
-
'Synthesis engine for synthesize=true. Defaults to ~/.dm/greedyconfig synthesizer (currently "gemini" by default). Supported: "gemini", "chatgpt".',
|
|
109
|
-
}),
|
|
110
|
-
),
|
|
111
|
-
depth: Type.Optional(
|
|
112
|
-
Type.String({
|
|
113
|
-
description:
|
|
114
|
-
'Deprecated except "research". Use depth="research" for the iterative research workflow. Research child searches use ~/.dm/greedyconfig engines; Gemini handles research planning/final synthesis. Legacy values: "fast" skips source fetching; "standard"/"deep" alias synthesize=true.',
|
|
115
|
-
}),
|
|
116
|
-
),
|
|
117
|
-
breadth: Type.Optional(
|
|
118
|
-
Type.Number({
|
|
119
|
-
description:
|
|
120
|
-
'Only for depth="research": number of parallel research directions per round, 1-5 (default: 3).',
|
|
121
|
-
default: 3,
|
|
122
|
-
}),
|
|
123
|
-
),
|
|
124
|
-
iterations: Type.Optional(
|
|
125
|
-
Type.Number({
|
|
126
|
-
description:
|
|
127
|
-
'Only for depth="research": number of iterative research rounds, 1-3 (default: 2).',
|
|
128
|
-
default: 2,
|
|
129
|
-
}),
|
|
130
|
-
),
|
|
131
|
-
maxSources: Type.Optional(
|
|
132
|
-
Type.Number({
|
|
133
|
-
description:
|
|
134
|
-
'Only for depth="research": maximum fetched sources for the final report, 3-12.',
|
|
135
|
-
}),
|
|
136
|
-
),
|
|
137
|
-
researchOutDir: Type.Optional(
|
|
138
|
-
Type.String({
|
|
139
|
-
description:
|
|
140
|
-
'Only for depth="research": optional directory for the structured research bundle. Defaults to .dm/greedysearch-research/<timestamp>_<query>.',
|
|
141
|
-
}),
|
|
142
|
-
),
|
|
143
|
-
writeResearchBundle: Type.Optional(
|
|
144
|
-
Type.Boolean({
|
|
145
|
-
description:
|
|
146
|
-
'Only for depth="research": write the structured research bundle to disk (default true).',
|
|
147
|
-
default: true,
|
|
148
|
-
}),
|
|
149
|
-
),
|
|
150
|
-
fullAnswer: Type.Optional(
|
|
151
|
-
Type.Boolean({
|
|
152
|
-
description:
|
|
153
|
-
"When true, returns the complete answer instead of a truncated preview (default: false, answers are shortened to ~300 chars to save tokens).",
|
|
154
|
-
default: false,
|
|
155
|
-
}),
|
|
156
|
-
),
|
|
157
|
-
headless: Type.Optional(
|
|
158
|
-
Type.Boolean({
|
|
159
|
-
description:
|
|
160
|
-
"Set to false to show Chrome window (headless is the default). Set GREEDY_SEARCH_VISIBLE=1 to disable headless globally.",
|
|
161
|
-
default: true,
|
|
162
|
-
}),
|
|
163
|
-
),
|
|
164
|
-
visible: Type.Optional(
|
|
165
|
-
Type.Boolean({
|
|
166
|
-
description:
|
|
167
|
-
"Set to true to always use visible Chrome for this search. Alias for headless: false.",
|
|
168
|
-
default: false,
|
|
169
|
-
}),
|
|
170
|
-
),
|
|
171
|
-
alwaysVisible: Type.Optional(
|
|
172
|
-
Type.Boolean({
|
|
173
|
-
description:
|
|
174
|
-
"Set to true to keep GreedySearch in visible Chrome mode for this search. Alias for visible: true.",
|
|
175
|
-
default: false,
|
|
176
|
-
}),
|
|
177
|
-
),
|
|
178
|
-
}),
|
|
179
|
-
execute: async (
|
|
180
|
-
_toolCallId: string,
|
|
181
|
-
params: GreedySearchParams,
|
|
182
|
-
signal?: AbortSignal,
|
|
183
|
-
onUpdate?: (update: ProgressUpdate) => void,
|
|
184
|
-
) => {
|
|
185
|
-
const { query, fullAnswer: fullAnswerParam } = params;
|
|
186
|
-
const engine = stripQuotes(params.engine ?? "all") || "all";
|
|
187
|
-
const depthRaw = stripQuotes(params.depth ?? "") as
|
|
188
|
-
| "fast"
|
|
189
|
-
| "standard"
|
|
190
|
-
| "deep"
|
|
191
|
-
| "research"
|
|
192
|
-
| "";
|
|
193
|
-
const researchMode = depthRaw === "research";
|
|
194
|
-
const legacyFast = depthRaw === "fast";
|
|
195
|
-
const legacySynthesisDepth =
|
|
196
|
-
depthRaw === "standard" || depthRaw === "deep";
|
|
197
|
-
const synthesize =
|
|
198
|
-
engine === "all" &&
|
|
199
|
-
!legacyFast &&
|
|
200
|
-
(params.synthesize === true || legacySynthesisDepth);
|
|
201
|
-
const effectiveEngine = researchMode ? "all" : engine;
|
|
202
|
-
const visible =
|
|
203
|
-
params.visible === true ||
|
|
204
|
-
params.alwaysVisible === true ||
|
|
205
|
-
params.headless === false ||
|
|
206
|
-
process.env.GREEDY_SEARCH_VISIBLE === "1" ||
|
|
207
|
-
process.env.GREEDY_SEARCH_ALWAYS_VISIBLE === "1";
|
|
208
|
-
const headless = !visible;
|
|
209
|
-
|
|
210
|
-
if (!cdpAvailable(baseDir)) return cdpMissingResult();
|
|
211
|
-
|
|
212
|
-
const flags: string[] = [];
|
|
213
|
-
const fullAnswer = fullAnswerParam ?? effectiveEngine !== "all";
|
|
214
|
-
if (fullAnswer) flags.push("--full");
|
|
215
|
-
if (researchMode) {
|
|
216
|
-
flags.push("--depth", "research");
|
|
217
|
-
if (typeof params.breadth === "number")
|
|
218
|
-
flags.push("--breadth", String(params.breadth));
|
|
219
|
-
if (typeof params.iterations === "number")
|
|
220
|
-
flags.push("--iterations", String(params.iterations));
|
|
221
|
-
if (typeof params.maxSources === "number")
|
|
222
|
-
flags.push("--max-sources", String(params.maxSources));
|
|
223
|
-
if (typeof params.researchOutDir === "string")
|
|
224
|
-
flags.push("--research-out-dir", params.researchOutDir);
|
|
225
|
-
if (params.writeResearchBundle === false)
|
|
226
|
-
flags.push("--no-research-bundle");
|
|
227
|
-
} else if (legacyFast) flags.push("--fast");
|
|
228
|
-
else if (depthRaw === "deep") flags.push("--depth", "deep");
|
|
229
|
-
else if (synthesize) flags.push("--synthesize");
|
|
230
|
-
if (synthesize && typeof params.synthesizer === "string") {
|
|
231
|
-
flags.push("--synthesizer", params.synthesizer);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
const onProgress =
|
|
235
|
-
effectiveEngine === "all"
|
|
236
|
-
? makeProgressTracker(
|
|
237
|
-
ALL_ENGINES,
|
|
238
|
-
onUpdate,
|
|
239
|
-
researchMode ? "Researching" : "Searching",
|
|
240
|
-
synthesize,
|
|
241
|
-
)
|
|
242
|
-
: undefined;
|
|
243
|
-
|
|
244
|
-
try {
|
|
245
|
-
const data = await runSearch(
|
|
246
|
-
effectiveEngine,
|
|
247
|
-
query,
|
|
248
|
-
flags,
|
|
249
|
-
`${baseDir}/bin/search.mjs`,
|
|
250
|
-
signal,
|
|
251
|
-
onProgress,
|
|
252
|
-
{ headless },
|
|
253
|
-
);
|
|
254
|
-
const text = formatResults(effectiveEngine, data);
|
|
255
|
-
return {
|
|
256
|
-
content: [{ type: "text", text: text || "No results returned." }],
|
|
257
|
-
details: { raw: data },
|
|
258
|
-
};
|
|
259
|
-
} catch (e) {
|
|
260
|
-
return errorResult("Search failed", e);
|
|
261
|
-
}
|
|
262
|
-
},
|
|
263
|
-
|
|
264
|
-
renderCall(args: Partial<GreedySearchParams>, theme: ToolTheme) {
|
|
265
|
-
const q = (args.query || "").slice(0, 60);
|
|
266
|
-
const qDisplay = q.length < (args.query || "").length ? `${q}...` : q;
|
|
267
|
-
const engineDisplay =
|
|
268
|
-
args.engine && args.engine !== "all"
|
|
269
|
-
? theme.fg("dim", ` (${args.engine})`)
|
|
270
|
-
: "";
|
|
271
|
-
return new Text(
|
|
272
|
-
`${theme.fg("toolTitle", theme.bold("greedy_search"))} "${theme.fg("accent", qDisplay)}"${engineDisplay}`,
|
|
273
|
-
0,
|
|
274
|
-
0,
|
|
275
|
-
);
|
|
276
|
-
},
|
|
277
|
-
|
|
278
|
-
renderResult(
|
|
279
|
-
result: ToolResult,
|
|
280
|
-
{ expanded, isPartial }: RenderState,
|
|
281
|
-
theme: ToolTheme,
|
|
282
|
-
) {
|
|
283
|
-
if (isPartial) {
|
|
284
|
-
const progressText = result.content.find(
|
|
285
|
-
(c) => c.type === "text",
|
|
286
|
-
)?.text;
|
|
287
|
-
const display = progressText
|
|
288
|
-
? progressText.replace(/\*\*/g, "")
|
|
289
|
-
: "Searching...";
|
|
290
|
-
return new Text(theme.fg("warning", display), 0, 0);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
const textContent = result.content.find((c) => c.type === "text");
|
|
294
|
-
const raw = result.details?.raw as Record<string, unknown> | undefined;
|
|
295
|
-
|
|
296
|
-
// Collapsed: one-line summary only
|
|
297
|
-
if (!expanded) {
|
|
298
|
-
const needsHuman = raw?._needsHumanVerification as
|
|
299
|
-
| Record<string, unknown>
|
|
300
|
-
| undefined;
|
|
301
|
-
if (needsHuman) {
|
|
302
|
-
return new Text(
|
|
303
|
-
theme.fg("warning", " → Manual verification required"),
|
|
304
|
-
0,
|
|
305
|
-
0,
|
|
306
|
-
);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
const synthesis = raw?._synthesis as
|
|
310
|
-
| Record<string, unknown>
|
|
311
|
-
| undefined;
|
|
312
|
-
const sources = raw?._sources as Array<unknown> | undefined;
|
|
313
|
-
if (synthesis) {
|
|
314
|
-
const sourceCount = Array.isArray(sources) ? sources.length : 0;
|
|
315
|
-
const agreement = (
|
|
316
|
-
synthesis.agreement as Record<string, unknown> | undefined
|
|
317
|
-
)?.level as string | undefined;
|
|
318
|
-
let summary = " → Synthesized";
|
|
319
|
-
if (sourceCount > 0)
|
|
320
|
-
summary += ` · ${sourceCount} source${sourceCount > 1 ? "s" : ""}`;
|
|
321
|
-
if (agreement) summary += ` · ${agreement}`;
|
|
322
|
-
return new Text(theme.fg("muted", summary), 0, 0);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// Single engine: count its sources
|
|
326
|
-
const engineKeys = Object.keys(raw || {}).filter(
|
|
327
|
-
(k) => !k.startsWith("_"),
|
|
328
|
-
);
|
|
329
|
-
let totalSources = 0;
|
|
330
|
-
for (const key of engineKeys) {
|
|
331
|
-
const eng = raw?.[key] as Record<string, unknown> | undefined;
|
|
332
|
-
const s = eng?.sources as Array<unknown> | undefined;
|
|
333
|
-
if (Array.isArray(s)) totalSources += s.length;
|
|
334
|
-
}
|
|
335
|
-
if (totalSources > 0) {
|
|
336
|
-
return new Text(
|
|
337
|
-
theme.fg(
|
|
338
|
-
"muted",
|
|
339
|
-
` → ${totalSources} source${totalSources > 1 ? "s" : ""}`,
|
|
340
|
-
),
|
|
341
|
-
0,
|
|
342
|
-
0,
|
|
343
|
-
);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
// No structured data — show content text as error/fallback
|
|
347
|
-
const snippet = textContent?.text;
|
|
348
|
-
if (snippet) {
|
|
349
|
-
return new Text(
|
|
350
|
-
theme.fg("warning", ` → ${snippet.slice(0, 80)}`),
|
|
351
|
-
0,
|
|
352
|
-
0,
|
|
353
|
-
);
|
|
354
|
-
}
|
|
355
|
-
return new Text(theme.fg("muted", " → Done"), 0, 0);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
// Expanded: full output
|
|
359
|
-
if (!textContent || textContent.type !== "text") {
|
|
360
|
-
return new Text("", 0, 0);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
const lines = textContent.text
|
|
364
|
-
.split("\n")
|
|
365
|
-
.map((line) => theme.fg("toolOutput", line))
|
|
366
|
-
.join("\n");
|
|
367
|
-
return new Text(`\n${lines}`, 0, 0);
|
|
368
|
-
},
|
|
369
|
-
});
|
|
370
|
-
}
|
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared types, utilities, and runSearch for DM tool handlers
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { spawn } from "node:child_process";
|
|
6
|
-
import { existsSync } from "node:fs";
|
|
7
|
-
import { join } from "node:path";
|
|
8
|
-
import type { ProgressUpdate, ToolResult } from "../types.js";
|
|
9
|
-
import { nodeRuntimeCommand } from "../utils/node-runtime.mjs";
|
|
10
|
-
|
|
11
|
-
export type { ProgressUpdate, ToolResult } from "../types.js";
|
|
12
|
-
|
|
13
|
-
// Import and re-export ALL_ENGINES from constants.mjs so it's always in sync.
|
|
14
|
-
// constants.mjs reads ~/.dm/greedyconfig for user overrides.
|
|
15
|
-
import { ALL_ENGINES } from "../search/constants.mjs";
|
|
16
|
-
export { ALL_ENGINES };
|
|
17
|
-
|
|
18
|
-
/** Strip surrounding double-quotes that some framework versions inject into string params */
|
|
19
|
-
export function stripQuotes(val: string): string {
|
|
20
|
-
return val.replace(/^"|"$/g, "");
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Check if the CDP module is available in the package directory
|
|
25
|
-
*/
|
|
26
|
-
export function cdpAvailable(baseDir: string): boolean {
|
|
27
|
-
return existsSync(join(baseDir, "bin", "cdp.mjs"));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Create a "cdp missing" error result
|
|
32
|
-
*/
|
|
33
|
-
export function cdpMissingResult(): ToolResult {
|
|
34
|
-
return {
|
|
35
|
-
content: [
|
|
36
|
-
{
|
|
37
|
-
type: "text",
|
|
38
|
-
text: "cdp.mjs missing — try reinstalling: Rebuild or reinstall DM to refresh the bundled GreedySearch asset.",
|
|
39
|
-
},
|
|
40
|
-
],
|
|
41
|
-
details: {} as Record<string, unknown>,
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Create an error result with a message
|
|
47
|
-
*/
|
|
48
|
-
export function errorResult(prefix: string, e: unknown): ToolResult {
|
|
49
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
50
|
-
return {
|
|
51
|
-
content: [{ type: "text", text: `${prefix}: ${msg}` }],
|
|
52
|
-
details: {} as Record<string, unknown>,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Spawn search.mjs and collect JSON results, with progress streaming via stderr.
|
|
58
|
-
* Shared by GreedySearch tool handlers.
|
|
59
|
-
*/
|
|
60
|
-
export function runSearch(
|
|
61
|
-
engine: string,
|
|
62
|
-
query: string,
|
|
63
|
-
flags: string[],
|
|
64
|
-
searchBin: string,
|
|
65
|
-
signal?: AbortSignal,
|
|
66
|
-
onProgress?: (
|
|
67
|
-
engine: string,
|
|
68
|
-
status: "done" | "error" | "needs-human",
|
|
69
|
-
) => void,
|
|
70
|
-
options: { headless?: boolean } = {},
|
|
71
|
-
): Promise<Record<string, unknown>> {
|
|
72
|
-
return new Promise((resolve, reject) => {
|
|
73
|
-
const { headless = true } = options;
|
|
74
|
-
const allFlags = [...flags];
|
|
75
|
-
// Headless is default — only skip if explicitly false or GREEDY_SEARCH_VISIBLE=1
|
|
76
|
-
if (headless !== false && process.env.GREEDY_SEARCH_VISIBLE !== "1")
|
|
77
|
-
allFlags.push("--headless");
|
|
78
|
-
if (headless === false) allFlags.push("--always-visible");
|
|
79
|
-
// Propagate visibility preference via env (--headless flag is informational;
|
|
80
|
-
// the actual headless control in search.mjs / launch.mjs reads the env var).
|
|
81
|
-
const procEnv = { ...process.env };
|
|
82
|
-
if (headless === false) {
|
|
83
|
-
procEnv.GREEDY_SEARCH_VISIBLE = "1";
|
|
84
|
-
procEnv.GREEDY_SEARCH_ALWAYS_VISIBLE = "1";
|
|
85
|
-
}
|
|
86
|
-
const proc = spawn(nodeRuntimeCommand(),
|
|
87
|
-
[searchBin, engine, "--inline", "--stdin", ...allFlags],
|
|
88
|
-
{ stdio: ["pipe", "pipe", "pipe"], env: procEnv },
|
|
89
|
-
);
|
|
90
|
-
// Pipe query via stdin to avoid leaking it in process table command-line
|
|
91
|
-
proc.stdin.write(query);
|
|
92
|
-
proc.stdin.end();
|
|
93
|
-
let out = "";
|
|
94
|
-
let err = "";
|
|
95
|
-
|
|
96
|
-
const onAbort = () => {
|
|
97
|
-
proc.kill("SIGTERM");
|
|
98
|
-
reject(new Error("Aborted"));
|
|
99
|
-
};
|
|
100
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
101
|
-
|
|
102
|
-
proc.stderr.on("data", (d: Buffer) => {
|
|
103
|
-
err += d;
|
|
104
|
-
// Match PROGRESS lines for any known engine.
|
|
105
|
-
const ENGINE_PROGRESS_RE =
|
|
106
|
-
/^PROGRESS:(perplexity|google|chatgpt|bing|gemini|semantic-scholar|semanticscholar|s2|logically):(done|error|needs-human)$/;
|
|
107
|
-
for (const line of d.toString().split("\n")) {
|
|
108
|
-
// Engine progress: any known engine
|
|
109
|
-
const engineMatch = line.match(ENGINE_PROGRESS_RE);
|
|
110
|
-
if (engineMatch && onProgress) {
|
|
111
|
-
onProgress(
|
|
112
|
-
engineMatch[1],
|
|
113
|
-
engineMatch[2] as "done" | "error" | "needs-human",
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
// Synthesis progress: skipped (manual verification) or done/error
|
|
117
|
-
const synthMatch = line.match(
|
|
118
|
-
/^PROGRESS:synthesis:(done|error|skipped)$/,
|
|
119
|
-
);
|
|
120
|
-
if (synthMatch && onProgress) {
|
|
121
|
-
onProgress(
|
|
122
|
-
"synthesis",
|
|
123
|
-
synthMatch[1] as "done" | "error" | "needs-human",
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
proc.stdout.on("data", (d: Buffer) => (out += d));
|
|
130
|
-
proc.on("close", (code: number) => {
|
|
131
|
-
signal?.removeEventListener("abort", onAbort);
|
|
132
|
-
if (code !== 0) {
|
|
133
|
-
reject(new Error(err.trim() || `search.mjs exited with code ${code}`));
|
|
134
|
-
} else {
|
|
135
|
-
try {
|
|
136
|
-
resolve(JSON.parse(out.trim()));
|
|
137
|
-
} catch {
|
|
138
|
-
reject(
|
|
139
|
-
new Error(`Invalid JSON from search.mjs: ${out.slice(0, 200)}`),
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Build a progress callback that tracks completed engines.
|
|
149
|
-
* Returns an onProgress function suitable for runSearch.
|
|
150
|
-
*/
|
|
151
|
-
export function makeProgressTracker(
|
|
152
|
-
engines: readonly string[],
|
|
153
|
-
onUpdate: ((update: ProgressUpdate) => void) | undefined,
|
|
154
|
-
suffix: "Searching" | "Researching",
|
|
155
|
-
showSynthesis: boolean,
|
|
156
|
-
) {
|
|
157
|
-
const completed = new Map<string, "done" | "error" | "needs-human">();
|
|
158
|
-
|
|
159
|
-
return (eng: string, status: "done" | "error" | "needs-human") => {
|
|
160
|
-
completed.set(eng, status);
|
|
161
|
-
const parts: string[] = [];
|
|
162
|
-
for (const e of engines) {
|
|
163
|
-
const s = completed.get(e);
|
|
164
|
-
if (s === "done") parts.push(`✅ ${e} done`);
|
|
165
|
-
else if (s === "error") parts.push(`❌ ${e} failed`);
|
|
166
|
-
else if (s === "needs-human")
|
|
167
|
-
parts.push(`🔓 ${e} needs manual verification`);
|
|
168
|
-
else parts.push(`⏳ ${e}`);
|
|
169
|
-
}
|
|
170
|
-
// Synthesis status is shown only when the caller explicitly requested
|
|
171
|
-
// Gemini synthesis for a multi-engine search.
|
|
172
|
-
if (showSynthesis && completed.size >= engines.length) {
|
|
173
|
-
const synStatus = completed.get("synthesis");
|
|
174
|
-
if (synStatus === "done") parts.push("✅ synthesized");
|
|
175
|
-
else if (synStatus === "error") parts.push("❌ synthesis failed");
|
|
176
|
-
else if (synStatus === "needs-human") parts.push("⏭️ synthesis skipped");
|
|
177
|
-
else parts.push("🔄 synthesizing");
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
onUpdate?.({
|
|
181
|
-
content: [
|
|
182
|
-
{ type: "text", text: `**${suffix}...** ${parts.join(" · ")}` },
|
|
183
|
-
],
|
|
184
|
-
details: { _progress: true },
|
|
185
|
-
} satisfies ProgressUpdate);
|
|
186
|
-
};
|
|
187
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TypeScript interfaces for GreedySearch data structures
|
|
3
|
-
*
|
|
4
|
-
* These types document the shape of data flowing between modules.
|
|
5
|
-
* They can be imported by TypeScript files (index.ts, tool handlers, formatters)
|
|
6
|
-
* and used for type safety without runtime overhead.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
// ============================================================================
|
|
10
|
-
// Search Result Types
|
|
11
|
-
// ============================================================================
|
|
12
|
-
|
|
13
|
-
/** A single source extracted from search results */
|
|
14
|
-
export interface Source {
|
|
15
|
-
url: string;
|
|
16
|
-
title: string;
|
|
17
|
-
type?:
|
|
18
|
-
| "official-docs"
|
|
19
|
-
| "maintainer-blog"
|
|
20
|
-
| "repo"
|
|
21
|
-
| "academic"
|
|
22
|
-
| "community"
|
|
23
|
-
| "website";
|
|
24
|
-
domain?: string;
|
|
25
|
-
snippet?: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** Result from a single search engine */
|
|
29
|
-
export interface SearchResult {
|
|
30
|
-
engine: string;
|
|
31
|
-
answer: string;
|
|
32
|
-
sources: Source[];
|
|
33
|
-
url?: string;
|
|
34
|
-
query?: string;
|
|
35
|
-
error?: string;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Synthesis result combining multiple engine results */
|
|
39
|
-
export interface SynthesisResult {
|
|
40
|
-
answer: string;
|
|
41
|
-
agreementLevel?: "consensus" | "majority" | "mixed" | "conflicting";
|
|
42
|
-
claims?: Claim[];
|
|
43
|
-
sourceIds?: string[];
|
|
44
|
-
confidence?: ConfidenceMetrics;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/** A single claim within a synthesis */
|
|
48
|
-
export interface Claim {
|
|
49
|
-
text: string;
|
|
50
|
-
sourceIds: string[];
|
|
51
|
-
confidence?: "high" | "medium" | "low";
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/** Confidence metrics for a synthesis */
|
|
55
|
-
export interface ConfidenceMetrics {
|
|
56
|
-
overall: number; // 0-1
|
|
57
|
-
consensus: number; // fraction of engines agreeing
|
|
58
|
-
sourceCount: number;
|
|
59
|
-
engineCount: number;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// ============================================================================
|
|
63
|
-
// Source Registry Types
|
|
64
|
-
// ============================================================================
|
|
65
|
-
|
|
66
|
-
/** A classified source in the registry */
|
|
67
|
-
export interface ClassifiedSource extends Source {
|
|
68
|
-
engineOrigin: string[];
|
|
69
|
-
isOfficial: boolean;
|
|
70
|
-
consensus: number; // fraction of engines citing this source
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// ============================================================================
|
|
74
|
-
// Tool Result Types
|
|
75
|
-
// ============================================================================
|
|
76
|
-
|
|
77
|
-
/** Progress update sent via onUpdate during long-running searches */
|
|
78
|
-
export interface ProgressUpdate {
|
|
79
|
-
content: Array<{ type: "text"; text: string }>;
|
|
80
|
-
details: { _progress: true };
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/** DM tool result format */
|
|
84
|
-
export interface ToolResult {
|
|
85
|
-
content: Array<{ type: "text"; text: string }>;
|
|
86
|
-
details: Record<string, unknown>;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// ============================================================================
|
|
90
|
-
// Engine Configuration Types
|
|
91
|
-
// ============================================================================
|
|
92
|
-
|
|
93
|
-
/** Engine definition for the ENGINES map */
|
|
94
|
-
export interface EngineConfig {
|
|
95
|
-
/** Extractor script filename (e.g. "perplexity.mjs") */
|
|
96
|
-
script: string;
|
|
97
|
-
/** Human-readable label for progress messages */
|
|
98
|
-
label: string;
|
|
99
|
-
/** Domain pattern for source matching */
|
|
100
|
-
domain: string;
|
|
101
|
-
/** URL pattern for the engine */
|
|
102
|
-
url: string;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// ============================================================================
|
|
106
|
-
// Constants
|
|
107
|
-
// ============================================================================
|
|
108
|
-
|
|
109
|
-
// Runtime defaults are in src/search/defaults.mjs (since .ts files can't be
|
|
110
|
-
// imported directly by Node.js). Import DEFAULTS from there for runtime values.
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utility helpers for formatting
|
|
3
|
-
* Consolidated from single-use functions in index.ts
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Format engine name for display
|
|
8
|
-
* Replaces 'bing' with 'Bing Copilot', etc.
|
|
9
|
-
*/
|
|
10
|
-
export function formatEngineName(engine: string): string {
|
|
11
|
-
const displayNames: Record<string, string> = {
|
|
12
|
-
bing: "Bing Copilot",
|
|
13
|
-
google: "Google AI",
|
|
14
|
-
gemini: "Gemini",
|
|
15
|
-
copilot: "Copilot",
|
|
16
|
-
perplexity: "Perplexity",
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
displayNames[engine] ??
|
|
21
|
-
engine.charAt(0).toUpperCase() + engine.slice(1)
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Humanize source type labels
|
|
27
|
-
*/
|
|
28
|
-
export function humanizeSourceType(sourceType: string): string {
|
|
29
|
-
if (!sourceType) return "";
|
|
30
|
-
if (sourceType === "official-docs") return "official docs";
|
|
31
|
-
return sourceType.replace(/-/g, " ");
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Format agreement level with proper capitalization
|
|
36
|
-
*/
|
|
37
|
-
export function formatAgreementLevel(level: string): string {
|
|
38
|
-
if (!level) return "Mixed";
|
|
39
|
-
return level.charAt(0).toUpperCase() + level.slice(1);
|
|
40
|
-
}
|