@sunilp-org/jam-cli 0.1.0 → 0.1.2
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/README.md +431 -63
- package/dist/commands/ask.d.ts +4 -0
- package/dist/commands/ask.d.ts.map +1 -1
- package/dist/commands/ask.js +202 -10
- package/dist/commands/ask.js.map +1 -1
- package/dist/commands/commit.d.ts +12 -0
- package/dist/commands/commit.d.ts.map +1 -0
- package/dist/commands/commit.js +135 -0
- package/dist/commands/commit.js.map +1 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +2 -1
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/context.d.ts +12 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +52 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/review.d.ts +25 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +117 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/run.d.ts +1 -0
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +199 -197
- package/dist/commands/run.js.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +39 -3
- package/dist/config/loader.js.map +1 -1
- package/dist/index.js +63 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/base.d.ts +26 -0
- package/dist/providers/base.d.ts.map +1 -1
- package/dist/providers/embedded.d.ts +20 -0
- package/dist/providers/embedded.d.ts.map +1 -0
- package/dist/providers/embedded.js +302 -0
- package/dist/providers/embedded.js.map +1 -0
- package/dist/providers/factory.d.ts.map +1 -1
- package/dist/providers/factory.js +25 -1
- package/dist/providers/factory.js.map +1 -1
- package/dist/providers/groq.d.ts +16 -0
- package/dist/providers/groq.d.ts.map +1 -0
- package/dist/providers/groq.js +23 -0
- package/dist/providers/groq.js.map +1 -0
- package/dist/providers/ollama.d.ts +6 -1
- package/dist/providers/ollama.d.ts.map +1 -1
- package/dist/providers/ollama.js +77 -4
- package/dist/providers/ollama.js.map +1 -1
- package/dist/providers/openai.d.ts +18 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +229 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/tools/all-tools.d.ts +18 -0
- package/dist/tools/all-tools.d.ts.map +1 -0
- package/dist/tools/all-tools.js +95 -0
- package/dist/tools/all-tools.js.map +1 -0
- package/dist/tools/apply_patch.js +1 -1
- package/dist/tools/apply_patch.js.map +1 -1
- package/dist/tools/context-tools.d.ts +14 -0
- package/dist/tools/context-tools.d.ts.map +1 -0
- package/dist/tools/context-tools.js +63 -0
- package/dist/tools/context-tools.js.map +1 -0
- package/dist/tools/git_diff.js +1 -1
- package/dist/tools/git_diff.js.map +1 -1
- package/dist/tools/git_status.js +1 -1
- package/dist/tools/git_status.js.map +1 -1
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +2 -0
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/run_command.d.ts +8 -3
- package/dist/tools/run_command.d.ts.map +1 -1
- package/dist/tools/run_command.js +90 -3
- package/dist/tools/run_command.js.map +1 -1
- package/dist/ui/chat.d.ts.map +1 -1
- package/dist/ui/chat.js +173 -1
- package/dist/ui/chat.js.map +1 -1
- package/dist/ui/logo.d.ts.map +1 -1
- package/dist/ui/logo.js +5 -1
- package/dist/ui/logo.js.map +1 -1
- package/dist/utils/agent.d.ts +130 -0
- package/dist/utils/agent.d.ts.map +1 -0
- package/dist/utils/agent.js +449 -0
- package/dist/utils/agent.js.map +1 -0
- package/dist/utils/cache.d.ts +30 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +62 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/context.d.ts +38 -0
- package/dist/utils/context.d.ts.map +1 -0
- package/dist/utils/context.js +383 -0
- package/dist/utils/context.js.map +1 -0
- package/dist/utils/critic.d.ts +31 -0
- package/dist/utils/critic.d.ts.map +1 -0
- package/dist/utils/critic.js +126 -0
- package/dist/utils/critic.js.map +1 -0
- package/dist/utils/index-builder.d.ts +53 -0
- package/dist/utils/index-builder.d.ts.map +1 -0
- package/dist/utils/index-builder.js +241 -0
- package/dist/utils/index-builder.js.map +1 -0
- package/dist/utils/memory.d.ts +104 -0
- package/dist/utils/memory.d.ts.map +1 -0
- package/dist/utils/memory.js +215 -0
- package/dist/utils/memory.js.map +1 -0
- package/dist/utils/past-sessions.d.ts +31 -0
- package/dist/utils/past-sessions.d.ts.map +1 -0
- package/dist/utils/past-sessions.js +126 -0
- package/dist/utils/past-sessions.js.map +1 -0
- package/dist/utils/tokens.d.ts +53 -0
- package/dist/utils/tokens.d.ts.map +1 -0
- package/dist/utils/tokens.js +138 -0
- package/dist/utils/tokens.js.map +1 -0
- package/package.json +6 -2
package/dist/ui/logo.js
CHANGED
|
@@ -46,8 +46,12 @@ function buildPlain() {
|
|
|
46
46
|
].join('\n');
|
|
47
47
|
}
|
|
48
48
|
// ── Build coloured box (synchronous ANSI, no chalk needed) ──────────────────
|
|
49
|
+
// Strip ANSI escape codes to get the visible (printable) length of a string.
|
|
50
|
+
const visibleLength = (s) =>
|
|
51
|
+
// eslint-disable-next-line no-control-regex
|
|
52
|
+
s.replace(/\x1b\[[0-9;]*m/g, '').length;
|
|
49
53
|
function buildColored() {
|
|
50
|
-
const pad = (s) => s + ' '.repeat(innerWidth - 2 - s
|
|
54
|
+
const pad = (s) => s + ' '.repeat(Math.max(0, innerWidth - 2 - visibleLength(s)));
|
|
51
55
|
const blank = ansi(A.dim, `│${' '.repeat(innerWidth)}│`);
|
|
52
56
|
const boxLine = (middle) => ansi(A.dim, '│ ') + middle + ansi(A.dim, ' │');
|
|
53
57
|
const letterLines = LETTERS.map(l => boxLine(pad(ansi(A.bold + A.gold, l))));
|
package/dist/ui/logo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logo.js","sourceRoot":"","sources":["../../src/ui/logo.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,gFAAgF;AAEhF,MAAM,OAAO,GAAG;IACd,+BAA+B;IAC/B,+BAA+B;IAC/B,+BAA+B;IAC/B,+BAA+B;IAC/B,+BAA+B;IAC/B,+BAA+B;CAChC,CAAC;AAEF,MAAM,OAAO,GAAG,0BAA0B,CAAC;AAC3C,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,sCAAsC;AAErD,+EAA+E;AAE/E,MAAM,CAAC,GAAG;IACR,KAAK,EAAI,SAAS;IAClB,GAAG,EAAM,SAAS;IAClB,IAAI,EAAK,SAAS;IAClB,IAAI,EAAK,sBAAsB,EAAI,UAAU;IAC7C,KAAK,EAAI,wBAAwB,EAAE,OAAO;CAClC,CAAC;AAEX,SAAS,IAAI,CAAC,IAAY,EAAE,IAAY;IACtC,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;AACpC,CAAC;AAED,iFAAiF;AAEjF,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;AAC7E,MAAM,UAAU,GAAK,YAAY,GAAG,GAAG,GAAG,CAAC,CAAC;AAC5C,MAAM,EAAE,GAAa,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;AAC5C,MAAM,MAAM,GAAS,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAEjF,gFAAgF;AAEhF,SAAS,UAAU;IACjB,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC;IAChE,MAAM,KAAK,GAAI,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;IAE7C,OAAO;QACL,IAAI,EAAE,GAAG;QACT,KAAK;QACL,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;QACtB,KAAK;QACL,MAAM,CAAC,GAAG,MAAM,GAAG,OAAO,EAAE,CAAC;QAC7B,KAAK;QACL,IAAI,EAAE,GAAG;KACV,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,+EAA+E;AAE/E,SAAS,YAAY;IACnB,MAAM,GAAG,GAAK,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"logo.js","sourceRoot":"","sources":["../../src/ui/logo.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,gFAAgF;AAEhF,MAAM,OAAO,GAAG;IACd,+BAA+B;IAC/B,+BAA+B;IAC/B,+BAA+B;IAC/B,+BAA+B;IAC/B,+BAA+B;IAC/B,+BAA+B;CAChC,CAAC;AAEF,MAAM,OAAO,GAAG,0BAA0B,CAAC;AAC3C,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,sCAAsC;AAErD,+EAA+E;AAE/E,MAAM,CAAC,GAAG;IACR,KAAK,EAAI,SAAS;IAClB,GAAG,EAAM,SAAS;IAClB,IAAI,EAAK,SAAS;IAClB,IAAI,EAAK,sBAAsB,EAAI,UAAU;IAC7C,KAAK,EAAI,wBAAwB,EAAE,OAAO;CAClC,CAAC;AAEX,SAAS,IAAI,CAAC,IAAY,EAAE,IAAY;IACtC,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;AACpC,CAAC;AAED,iFAAiF;AAEjF,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;AAC7E,MAAM,UAAU,GAAK,YAAY,GAAG,GAAG,GAAG,CAAC,CAAC;AAC5C,MAAM,EAAE,GAAa,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;AAC5C,MAAM,MAAM,GAAS,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAEjF,gFAAgF;AAEhF,SAAS,UAAU;IACjB,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC;IAChE,MAAM,KAAK,GAAI,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;IAE7C,OAAO;QACL,IAAI,EAAE,GAAG;QACT,KAAK;QACL,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;QACtB,KAAK;QACL,MAAM,CAAC,GAAG,MAAM,GAAG,OAAO,EAAE,CAAC;QAC7B,KAAK;QACL,IAAI,EAAE,GAAG;KACV,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,+EAA+E;AAE/E,6EAA6E;AAC7E,MAAM,aAAa,GAAG,CAAC,CAAS,EAAU,EAAE;AAC1C,4CAA4C;AAC5C,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC;AAE1C,SAAS,YAAY;IACnB,MAAM,GAAG,GAAK,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5F,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAEzD,MAAM,OAAO,GAAG,CAAC,MAAc,EAAE,EAAE,CACjC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAEjD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAClC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CACvC,CAAC;IAEF,MAAM,UAAU,GAAG,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;IAExD,OAAO;QACL,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC;QACtB,KAAK;QACL,GAAG,WAAW;QACd,KAAK;QACL,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxB,KAAK;QACL,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC;KACvB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,gFAAgF;AAEhF,iEAAiE;AACjE,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,EAAE,CAAC;AAEvC;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,OAAO,GAAG,KAAK;IACvC,MAAM,QAAQ,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;IAClD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC,CAAC;AAC1E,CAAC"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared agentic-loop intelligence for `jam ask`, `jam chat`, and `jam run`.
|
|
3
|
+
*
|
|
4
|
+
* This module provides:
|
|
5
|
+
* - Search planner (separate LLM reasoning step before tool use)
|
|
6
|
+
* - ReAct-style system prompt builder (with JAM.md / workspace context)
|
|
7
|
+
* - Query/prompt enrichment with plan-driven search guidance
|
|
8
|
+
* - Tool-call loop detection, duplicate skipping, and correction hints
|
|
9
|
+
* - Answer self-validation (JSON detection, too-short, empty, off-topic)
|
|
10
|
+
* - Synthesis grounding (reminds model of original question before answering)
|
|
11
|
+
*
|
|
12
|
+
* Individual commands wire these into their own UI layer (stdout streaming,
|
|
13
|
+
* Ink TUI, or plain stderr).
|
|
14
|
+
*/
|
|
15
|
+
import type { ProviderAdapter } from '../providers/base.js';
|
|
16
|
+
export declare const ANSI: {
|
|
17
|
+
readonly reset: "\u001B[0m";
|
|
18
|
+
readonly dim: "\u001B[2m";
|
|
19
|
+
readonly bold: "\u001B[1m";
|
|
20
|
+
readonly italic: "\u001B[3m";
|
|
21
|
+
readonly cyan: "\u001B[36m";
|
|
22
|
+
readonly yellow: "\u001B[33m";
|
|
23
|
+
readonly green: "\u001B[32m";
|
|
24
|
+
readonly magenta: "\u001B[35m";
|
|
25
|
+
readonly gray: "\u001B[90m";
|
|
26
|
+
readonly white: "\u001B[37m";
|
|
27
|
+
readonly blue: "\u001B[34m";
|
|
28
|
+
readonly red: "\u001B[31m";
|
|
29
|
+
readonly dimBlue: "\u001B[2m\u001B[34m";
|
|
30
|
+
readonly dimCyan: "\u001B[2m\u001B[36m";
|
|
31
|
+
readonly dimGreen: "\u001B[2m\u001B[32m";
|
|
32
|
+
readonly dimYellow: "\u001B[2m\u001B[33m";
|
|
33
|
+
readonly dimMagenta: "\u001B[2m\u001B[35m";
|
|
34
|
+
readonly dimGray: "\u001B[2m\u001B[90m";
|
|
35
|
+
};
|
|
36
|
+
export declare function ansi(code: string, text: string): string;
|
|
37
|
+
/** Build a concise workspace overview for the system prompt. */
|
|
38
|
+
export declare function buildWorkspaceContext(workspaceRoot: string): Promise<string>;
|
|
39
|
+
/**
|
|
40
|
+
* Load JAM.md if present, otherwise fall back to auto-detected workspace context.
|
|
41
|
+
*/
|
|
42
|
+
export declare function loadProjectContext(workspaceRoot: string): Promise<{
|
|
43
|
+
jamContext: string | null;
|
|
44
|
+
workspaceCtx: string;
|
|
45
|
+
}>;
|
|
46
|
+
export interface SystemPromptOptions {
|
|
47
|
+
/** 'readonly' for ask/chat, 'readwrite' for run */
|
|
48
|
+
mode: 'readonly' | 'readwrite';
|
|
49
|
+
/** Workspace root path (for run command context) */
|
|
50
|
+
workspaceRoot?: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Build a ReAct-style system prompt with project context.
|
|
54
|
+
*/
|
|
55
|
+
export declare function buildSystemPrompt(jamContext: string | null, workspaceCtx: string, options?: SystemPromptOptions): string;
|
|
56
|
+
/**
|
|
57
|
+
* Generate a search plan by asking the model to reason about what to search for.
|
|
58
|
+
* This is a separate LLM call (no tools) that produces a focused plan
|
|
59
|
+
* for the agentic tool loop.
|
|
60
|
+
*
|
|
61
|
+
* Returns the plan text, or null if planning fails.
|
|
62
|
+
*/
|
|
63
|
+
export declare function generateSearchPlan(provider: ProviderAdapter, question: string, projectContext: string, options: {
|
|
64
|
+
model?: string;
|
|
65
|
+
temperature?: number;
|
|
66
|
+
maxTokens?: number;
|
|
67
|
+
}): Promise<string | null>;
|
|
68
|
+
/**
|
|
69
|
+
* Enrich the user's prompt with search strategy guidance.
|
|
70
|
+
* If a search plan is provided, integrates it for focused searching.
|
|
71
|
+
* Otherwise falls back to generic search guidance.
|
|
72
|
+
*/
|
|
73
|
+
export declare function enrichUserPrompt(prompt: string, searchPlan?: string | null): string;
|
|
74
|
+
/**
|
|
75
|
+
* Build a synthesis reminder that grounds the model back to the original question.
|
|
76
|
+
* Injected as a user message when the model is about to give its final answer
|
|
77
|
+
* (i.e., returns no tool calls after gathering context).
|
|
78
|
+
*/
|
|
79
|
+
export declare function buildSynthesisReminder(originalQuestion: string): string;
|
|
80
|
+
export declare class ToolCallTracker {
|
|
81
|
+
private history;
|
|
82
|
+
private errorCount;
|
|
83
|
+
record(name: string, args: Record<string, unknown>, wasError: boolean): void;
|
|
84
|
+
/** Detect if a call was already made (exact duplicate). */
|
|
85
|
+
isDuplicate(name: string, args: Record<string, unknown>): boolean;
|
|
86
|
+
/** Build a correction hint if the model is stuck. */
|
|
87
|
+
getCorrectionHint(): string | null;
|
|
88
|
+
get totalCalls(): number;
|
|
89
|
+
/** Reset for a new turn (useful in multi-turn chat). */
|
|
90
|
+
reset(): void;
|
|
91
|
+
}
|
|
92
|
+
export interface ValidationResult {
|
|
93
|
+
valid: boolean;
|
|
94
|
+
reason?: string;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Check if the model's final answer looks acceptable.
|
|
98
|
+
* Returns { valid: false, reason } if it looks like garbage.
|
|
99
|
+
*
|
|
100
|
+
* @param text The model's answer text
|
|
101
|
+
* @param hadToolCalls Whether the model used tools (stricter validation if so)
|
|
102
|
+
* @param originalQuestion Optional: the user's original question for relevance checking
|
|
103
|
+
*/
|
|
104
|
+
export declare function validateAnswer(text: string, hadToolCalls: boolean, originalQuestion?: string): ValidationResult;
|
|
105
|
+
/**
|
|
106
|
+
* Build a correction message to inject when the answer is invalid.
|
|
107
|
+
*/
|
|
108
|
+
export declare function buildCorrectionMessage(reason: string): string;
|
|
109
|
+
/**
|
|
110
|
+
* Format the search plan text as a visually distinct block.
|
|
111
|
+
* Uses dim blue with a left-border character (│) to set it apart from tool output.
|
|
112
|
+
*/
|
|
113
|
+
export declare function formatPlanBlock(planText: string, noColor: boolean): string;
|
|
114
|
+
/** Format an internal status message (compaction, critic, scratchpad, etc). Very dim. */
|
|
115
|
+
export declare function formatInternalStatus(message: string, noColor: boolean): string;
|
|
116
|
+
/** Format a tool call for display — dim cyan to stay visually secondary. */
|
|
117
|
+
export declare function formatToolCall(name: string, args: Record<string, unknown>, noColor: boolean): string;
|
|
118
|
+
/** Format a tool result summary for display — very dim, background-level. */
|
|
119
|
+
export declare function formatToolResult(output: string, noColor: boolean): string;
|
|
120
|
+
/** Print a section separator — bold accent to clearly demarcate phases. */
|
|
121
|
+
export declare function formatSeparator(label: string, noColor: boolean): string;
|
|
122
|
+
/** Format a duplicate skip message — dim red. */
|
|
123
|
+
export declare function formatDuplicateSkip(name: string, noColor: boolean): string;
|
|
124
|
+
/** Format a retry/validation message — dim yellow, secondary prominence. */
|
|
125
|
+
export declare function formatRetry(message: string, noColor: boolean): string;
|
|
126
|
+
/** Format a correction hint injection message. */
|
|
127
|
+
export declare function formatHintInjection(noColor: boolean): string;
|
|
128
|
+
/** Format usage stats — small dim footer. */
|
|
129
|
+
export declare function formatUsage(promptTokens: number, completionTokens: number, totalTokens: number, noColor: boolean): string;
|
|
130
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/utils/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared agentic-loop intelligence for `jam ask`, `jam chat`, and `jam run`.
|
|
3
|
+
*
|
|
4
|
+
* This module provides:
|
|
5
|
+
* - Search planner (separate LLM reasoning step before tool use)
|
|
6
|
+
* - ReAct-style system prompt builder (with JAM.md / workspace context)
|
|
7
|
+
* - Query/prompt enrichment with plan-driven search guidance
|
|
8
|
+
* - Tool-call loop detection, duplicate skipping, and correction hints
|
|
9
|
+
* - Answer self-validation (JSON detection, too-short, empty, off-topic)
|
|
10
|
+
* - Synthesis grounding (reminds model of original question before answering)
|
|
11
|
+
*
|
|
12
|
+
* Individual commands wire these into their own UI layer (stdout streaming,
|
|
13
|
+
* Ink TUI, or plain stderr).
|
|
14
|
+
*/
|
|
15
|
+
import { readdir } from 'node:fs/promises';
|
|
16
|
+
import { basename, join } from 'node:path';
|
|
17
|
+
import { loadContextFile } from './context.js';
|
|
18
|
+
// ── ANSI helpers ──────────────────────────────────────────────────────────────
|
|
19
|
+
export const ANSI = {
|
|
20
|
+
reset: '\x1b[0m',
|
|
21
|
+
dim: '\x1b[2m',
|
|
22
|
+
bold: '\x1b[1m',
|
|
23
|
+
italic: '\x1b[3m',
|
|
24
|
+
cyan: '\x1b[36m',
|
|
25
|
+
yellow: '\x1b[33m',
|
|
26
|
+
green: '\x1b[32m',
|
|
27
|
+
magenta: '\x1b[35m',
|
|
28
|
+
gray: '\x1b[90m',
|
|
29
|
+
white: '\x1b[37m',
|
|
30
|
+
blue: '\x1b[34m',
|
|
31
|
+
red: '\x1b[31m',
|
|
32
|
+
// Dim variants for subtle output
|
|
33
|
+
dimBlue: '\x1b[2m\x1b[34m',
|
|
34
|
+
dimCyan: '\x1b[2m\x1b[36m',
|
|
35
|
+
dimGreen: '\x1b[2m\x1b[32m',
|
|
36
|
+
dimYellow: '\x1b[2m\x1b[33m',
|
|
37
|
+
dimMagenta: '\x1b[2m\x1b[35m',
|
|
38
|
+
dimGray: '\x1b[2m\x1b[90m',
|
|
39
|
+
};
|
|
40
|
+
export function ansi(code, text) {
|
|
41
|
+
return `${code}${text}${ANSI.reset}`;
|
|
42
|
+
}
|
|
43
|
+
// ── Workspace context ─────────────────────────────────────────────────────────
|
|
44
|
+
/** Build a concise workspace overview for the system prompt. */
|
|
45
|
+
export async function buildWorkspaceContext(workspaceRoot) {
|
|
46
|
+
const projectName = basename(workspaceRoot);
|
|
47
|
+
let entries;
|
|
48
|
+
try {
|
|
49
|
+
const dirEntries = await readdir(workspaceRoot, { withFileTypes: true });
|
|
50
|
+
entries = dirEntries
|
|
51
|
+
.filter(e => !String(e.name).startsWith('.') && String(e.name) !== 'node_modules' && String(e.name) !== 'dist')
|
|
52
|
+
.map(e => e.isDirectory() ? `${String(e.name)}/` : String(e.name))
|
|
53
|
+
.sort();
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
entries = [];
|
|
57
|
+
}
|
|
58
|
+
const hasTs = entries.some(e => e === 'tsconfig.json');
|
|
59
|
+
const hasPkg = entries.some(e => e === 'package.json');
|
|
60
|
+
const hasSrc = entries.some(e => e === 'src/');
|
|
61
|
+
let srcTree = '';
|
|
62
|
+
if (hasSrc) {
|
|
63
|
+
try {
|
|
64
|
+
const srcEntries = await readdir(join(workspaceRoot, 'src'), { withFileTypes: true });
|
|
65
|
+
const srcItems = srcEntries
|
|
66
|
+
.filter(e => !String(e.name).startsWith('.'))
|
|
67
|
+
.map(e => e.isDirectory() ? ` ${String(e.name)}/` : ` ${String(e.name)}`)
|
|
68
|
+
.sort();
|
|
69
|
+
srcTree = `\nsrc/ contents:\n${srcItems.join('\n')}`;
|
|
70
|
+
}
|
|
71
|
+
catch { /* ignore */ }
|
|
72
|
+
}
|
|
73
|
+
const lang = hasTs ? 'TypeScript' : hasPkg ? 'JavaScript/Node.js' : 'unknown';
|
|
74
|
+
return [
|
|
75
|
+
`Project: ${projectName}`,
|
|
76
|
+
`Language: ${lang}`,
|
|
77
|
+
hasTs ? 'Source files use .ts extension — always search *.ts files, NOT *.js' : '',
|
|
78
|
+
`\nRoot files:\n${entries.map(e => ` ${e}`).join('\n')}`,
|
|
79
|
+
srcTree,
|
|
80
|
+
].filter(Boolean).join('\n');
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Load JAM.md if present, otherwise fall back to auto-detected workspace context.
|
|
84
|
+
*/
|
|
85
|
+
export async function loadProjectContext(workspaceRoot) {
|
|
86
|
+
const [jamContext, workspaceCtx] = await Promise.all([
|
|
87
|
+
loadContextFile(workspaceRoot),
|
|
88
|
+
buildWorkspaceContext(workspaceRoot),
|
|
89
|
+
]);
|
|
90
|
+
return { jamContext, workspaceCtx };
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Build a ReAct-style system prompt with project context.
|
|
94
|
+
*/
|
|
95
|
+
export function buildSystemPrompt(jamContext, workspaceCtx, options = { mode: 'readonly' }) {
|
|
96
|
+
const modeDesc = options.mode === 'readwrite'
|
|
97
|
+
? 'You are an expert developer assistant with full read/write access to the local codebase via tools.'
|
|
98
|
+
: 'You are an expert code assistant. You help developers understand their codebase by reading and searching source files.';
|
|
99
|
+
return [
|
|
100
|
+
modeDesc,
|
|
101
|
+
'',
|
|
102
|
+
// Project context
|
|
103
|
+
...(jamContext
|
|
104
|
+
? ['## Project Context', '', jamContext]
|
|
105
|
+
: ['## Workspace Info', '', workspaceCtx]),
|
|
106
|
+
'',
|
|
107
|
+
options.workspaceRoot ? `Workspace root: ${options.workspaceRoot}` : '',
|
|
108
|
+
'',
|
|
109
|
+
'## Your Behavior',
|
|
110
|
+
'',
|
|
111
|
+
'You follow the ReAct (Reason → Act → Observe) pattern:',
|
|
112
|
+
'1. **Reason**: Think about what you need to find. Identify specific code identifiers (function names, class names, imports, variable names) to search for.',
|
|
113
|
+
'2. **Act**: Use tools to search for those specific identifiers and read relevant files.',
|
|
114
|
+
'3. **Observe**: Look at the results. Did you find what you need? If not, reason about different terms to try.',
|
|
115
|
+
'4. **Repeat** until you have enough context, then give your final answer.',
|
|
116
|
+
'',
|
|
117
|
+
'## CRITICAL Rules',
|
|
118
|
+
'',
|
|
119
|
+
'- NEVER search for vague English words. Always search for actual code identifiers that would appear in source files.',
|
|
120
|
+
'- NEVER repeat a search with the same query. If it returned no results, the term does not exist — try something else.',
|
|
121
|
+
'- NEVER pass an empty string as a search query.',
|
|
122
|
+
'- NEVER output raw JSON as your answer. Always respond in clean, readable Markdown.',
|
|
123
|
+
'- NEVER ask the user for information you can discover by reading code.',
|
|
124
|
+
'- NEVER just describe code you read. Always answer the user\'s SPECIFIC question.',
|
|
125
|
+
'- ALWAYS read files to verify your understanding before answering.',
|
|
126
|
+
'- ALWAYS reference specific file paths and line numbers in your answer.',
|
|
127
|
+
'- ALWAYS relate your findings back to the user\'s original question.',
|
|
128
|
+
'- When you have gathered enough context, provide a clear, well-structured Markdown answer with code snippets.',
|
|
129
|
+
...(options.mode === 'readwrite' ? [
|
|
130
|
+
'- For write operations, explain what you are changing and why BEFORE making the change.',
|
|
131
|
+
'- Always validate changes after making them (e.g. read the file back to confirm).',
|
|
132
|
+
] : []),
|
|
133
|
+
].filter(Boolean).join('\n');
|
|
134
|
+
}
|
|
135
|
+
// ── Search planner (deep reasoning step) ──────────────────────────────────────
|
|
136
|
+
const PLANNER_SYSTEM_PROMPT = `You are a search planner for a code assistant. Your job is to analyze the user's question and create a focused search plan.
|
|
137
|
+
|
|
138
|
+
You will receive:
|
|
139
|
+
1. A user's question about a codebase
|
|
140
|
+
2. Project context (language, framework, directory structure)
|
|
141
|
+
|
|
142
|
+
You must output a search plan with:
|
|
143
|
+
1. QUESTION INTENT: What the user is really asking (1 sentence)
|
|
144
|
+
2. KEY CONCEPTS: What code constructs relate to this question (function names, class names, patterns, file names)
|
|
145
|
+
3. SEARCH QUERIES: 3-5 specific strings to search for in the codebase (actual code identifiers, NOT English words)
|
|
146
|
+
4. DIRECTORIES: Which directories to explore first
|
|
147
|
+
|
|
148
|
+
Be VERY specific. For example:
|
|
149
|
+
- "where to add chatgpt as LLM" → search for: "ProviderAdapter", "createProvider", "OllamaProvider", "factory" — NOT "chatgpt" or "llm"
|
|
150
|
+
- "how does auth work" → search for: "authenticate", "token", "session", "middleware", "login" — NOT "auth" or "security"
|
|
151
|
+
- "where is the database connection" → search for: "createConnection", "pool", "DataSource", "prisma", "knex" — NOT "database"
|
|
152
|
+
|
|
153
|
+
Output ONLY the plan in the exact format above. Be concise.`;
|
|
154
|
+
/**
|
|
155
|
+
* Generate a search plan by asking the model to reason about what to search for.
|
|
156
|
+
* This is a separate LLM call (no tools) that produces a focused plan
|
|
157
|
+
* for the agentic tool loop.
|
|
158
|
+
*
|
|
159
|
+
* Returns the plan text, or null if planning fails.
|
|
160
|
+
*/
|
|
161
|
+
export async function generateSearchPlan(provider, question, projectContext, options) {
|
|
162
|
+
try {
|
|
163
|
+
const planRequest = {
|
|
164
|
+
messages: [{
|
|
165
|
+
role: 'user',
|
|
166
|
+
content: [
|
|
167
|
+
`User's question: "${question}"`,
|
|
168
|
+
'',
|
|
169
|
+
'Project context:',
|
|
170
|
+
projectContext,
|
|
171
|
+
'',
|
|
172
|
+
'Create a search plan for finding the answer in this codebase.',
|
|
173
|
+
].join('\n'),
|
|
174
|
+
}],
|
|
175
|
+
model: options.model,
|
|
176
|
+
temperature: 0.3, // Low temperature for focused planning
|
|
177
|
+
maxTokens: 400, // Plan should be concise
|
|
178
|
+
systemPrompt: PLANNER_SYSTEM_PROMPT,
|
|
179
|
+
};
|
|
180
|
+
let plan = '';
|
|
181
|
+
const stream = provider.streamCompletion(planRequest);
|
|
182
|
+
for await (const chunk of stream) {
|
|
183
|
+
if (!chunk.done)
|
|
184
|
+
plan += chunk.delta;
|
|
185
|
+
}
|
|
186
|
+
const trimmed = plan.trim();
|
|
187
|
+
// Sanity check: plan should be non-empty and not too short
|
|
188
|
+
if (trimmed.length < 20)
|
|
189
|
+
return null;
|
|
190
|
+
return trimmed;
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
// Planning failure is non-fatal
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// ── Query expansion / prompt enrichment ───────────────────────────────────────
|
|
198
|
+
/**
|
|
199
|
+
* Enrich the user's prompt with search strategy guidance.
|
|
200
|
+
* If a search plan is provided, integrates it for focused searching.
|
|
201
|
+
* Otherwise falls back to generic search guidance.
|
|
202
|
+
*/
|
|
203
|
+
export function enrichUserPrompt(prompt, searchPlan) {
|
|
204
|
+
const parts = [prompt];
|
|
205
|
+
if (searchPlan) {
|
|
206
|
+
parts.push('', '---', '', '## Your Search Plan', '', searchPlan, '', '## Instructions', '', '- Follow the search plan above. Start with the suggested search queries.', '- After finding relevant files, READ them to understand the full context.', '- Once you have enough information, answer the user\'s SPECIFIC question.', '- Do NOT just describe code you read. Directly answer what the user asked.', '- Reference specific file paths and line numbers.', '- Show relevant code snippets.', '- Format your answer in clean Markdown.', '- Do NOT output JSON.');
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
parts.push('', '---', '**Before you search, THINK about the user\'s question:**', '1. What concepts does the user\'s question involve?', '2. What are the likely function names, class names, file names, or variable names in the code for those concepts?', '3. Plan 2–3 different search queries using those specific identifiers.', '', '**Search strategy:**', '- NEVER search for vague/generic words. Search for specific code identifiers (function names, class names, imports).', '- If the user asks about "LLM calls", search for `fetch`, `api/chat`, `streamCompletion`, `chatWithTools`, `provider`, `adapter` — not "llm".', '- If the user asks about "database", search for `query`, `connection`, `pool`, `prisma`, `knex`, `sequelize` — not "database".', '- If a search returns no results, try a DIFFERENT term, not the same one again.', '- Use `glob="*.ts"` for TypeScript projects to avoid searching compiled files.', '- After finding relevant files, use read_file to understand the full context.', '', '**When answering:**', '- Directly answer the user\'s SPECIFIC question. Do NOT just describe code.', '- Give a direct, specific answer with file paths and line numbers.', '- Show relevant code snippets.', '- Format your answer in clean Markdown.', '- Do NOT output JSON. Do NOT ask the user clarifying questions — find the answer yourself.');
|
|
210
|
+
}
|
|
211
|
+
return parts.join('\n');
|
|
212
|
+
}
|
|
213
|
+
// ── Synthesis grounding ───────────────────────────────────────────────────────
|
|
214
|
+
/**
|
|
215
|
+
* Build a synthesis reminder that grounds the model back to the original question.
|
|
216
|
+
* Injected as a user message when the model is about to give its final answer
|
|
217
|
+
* (i.e., returns no tool calls after gathering context).
|
|
218
|
+
*/
|
|
219
|
+
export function buildSynthesisReminder(originalQuestion) {
|
|
220
|
+
return [
|
|
221
|
+
`[IMPORTANT — ANSWER THE QUESTION]`,
|
|
222
|
+
'',
|
|
223
|
+
`The user's original question was: "${originalQuestion}"`,
|
|
224
|
+
'',
|
|
225
|
+
'Based on ALL the code you examined, answer this specific question directly.',
|
|
226
|
+
'',
|
|
227
|
+
'Your answer MUST:',
|
|
228
|
+
'1. Directly address what the user asked — do NOT just describe code',
|
|
229
|
+
'2. Reference specific files, line numbers, and code snippets',
|
|
230
|
+
'3. If the user asked "where" or "how", give specific locations and steps',
|
|
231
|
+
'4. If the user asked about adding/changing something, explain what files to modify and how',
|
|
232
|
+
'',
|
|
233
|
+
'Your answer MUST NOT:',
|
|
234
|
+
'- Describe irrelevant code that doesn\'t answer the question',
|
|
235
|
+
'- Be a generic overview of the project',
|
|
236
|
+
'- Repeat tool output verbatim',
|
|
237
|
+
'',
|
|
238
|
+
'Format your answer in clean, readable Markdown.',
|
|
239
|
+
].join('\n');
|
|
240
|
+
}
|
|
241
|
+
export class ToolCallTracker {
|
|
242
|
+
history = [];
|
|
243
|
+
errorCount = 0;
|
|
244
|
+
record(name, args, wasError) {
|
|
245
|
+
this.history.push({ name, args: JSON.stringify(args) });
|
|
246
|
+
if (wasError)
|
|
247
|
+
this.errorCount++;
|
|
248
|
+
}
|
|
249
|
+
/** Detect if a call was already made (exact duplicate). */
|
|
250
|
+
isDuplicate(name, args) {
|
|
251
|
+
const key = JSON.stringify(args);
|
|
252
|
+
return this.history.some(h => h.name === name && h.args === key);
|
|
253
|
+
}
|
|
254
|
+
/** Build a correction hint if the model is stuck. */
|
|
255
|
+
getCorrectionHint() {
|
|
256
|
+
if (this.history.length < 2)
|
|
257
|
+
return null;
|
|
258
|
+
// Check for repeated failures
|
|
259
|
+
if (this.errorCount >= 2) {
|
|
260
|
+
return '[SYSTEM HINT: Multiple tool errors detected. Make sure the "query" argument is a non-empty, specific string. Try searching for function names, class names, or import statements instead of generic terms.]';
|
|
261
|
+
}
|
|
262
|
+
// Check for duplicate calls
|
|
263
|
+
const seen = new Set();
|
|
264
|
+
let dupes = 0;
|
|
265
|
+
for (const h of this.history) {
|
|
266
|
+
const key = `${h.name}:${h.args}`;
|
|
267
|
+
if (seen.has(key))
|
|
268
|
+
dupes++;
|
|
269
|
+
seen.add(key);
|
|
270
|
+
}
|
|
271
|
+
if (dupes >= 2) {
|
|
272
|
+
return '[SYSTEM HINT: You are repeating the same searches. STOP and try completely different search terms. Think about what function names, class names, or variable names would exist in the code. Search for those specific identifiers instead.]';
|
|
273
|
+
}
|
|
274
|
+
// Check for too many rounds with no progress
|
|
275
|
+
const lastThree = this.history.slice(-3);
|
|
276
|
+
const allSameType = lastThree.length === 3 && lastThree.every(h => h.name === 'search_text');
|
|
277
|
+
if (allSameType) {
|
|
278
|
+
return '[SYSTEM HINT: You have been searching repeatedly. Try using list_dir to explore the directory structure, or read_file to look at specific files that seem relevant based on their names.]';
|
|
279
|
+
}
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
get totalCalls() { return this.history.length; }
|
|
283
|
+
/** Reset for a new turn (useful in multi-turn chat). */
|
|
284
|
+
reset() {
|
|
285
|
+
this.history = [];
|
|
286
|
+
this.errorCount = 0;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Check if the model's final answer looks acceptable.
|
|
291
|
+
* Returns { valid: false, reason } if it looks like garbage.
|
|
292
|
+
*
|
|
293
|
+
* @param text The model's answer text
|
|
294
|
+
* @param hadToolCalls Whether the model used tools (stricter validation if so)
|
|
295
|
+
* @param originalQuestion Optional: the user's original question for relevance checking
|
|
296
|
+
*/
|
|
297
|
+
export function validateAnswer(text, hadToolCalls, originalQuestion) {
|
|
298
|
+
const trimmed = text.trim();
|
|
299
|
+
if (trimmed.length === 0) {
|
|
300
|
+
return { valid: false, reason: 'You produced an empty response.' };
|
|
301
|
+
}
|
|
302
|
+
if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
|
|
303
|
+
// Allow short JSON-like responses if they're clearly code examples inside markdown
|
|
304
|
+
if (!trimmed.includes('```') && trimmed.length > 10) {
|
|
305
|
+
return { valid: false, reason: 'You output raw JSON instead of a Markdown answer.' };
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
if (hadToolCalls && trimmed.length < 20) {
|
|
309
|
+
return { valid: false, reason: 'Your answer was too short and unhelpful.' };
|
|
310
|
+
}
|
|
311
|
+
// Relevance check: does the answer relate to the original question?
|
|
312
|
+
if (originalQuestion && hadToolCalls && trimmed.length > 50) {
|
|
313
|
+
const relevance = checkAnswerRelevance(originalQuestion, trimmed);
|
|
314
|
+
if (!relevance.relevant) {
|
|
315
|
+
return { valid: false, reason: relevance.reason };
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return { valid: true };
|
|
319
|
+
}
|
|
320
|
+
// Stop words to ignore in relevance checking
|
|
321
|
+
const STOP_WORDS = new Set([
|
|
322
|
+
'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
|
|
323
|
+
'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
|
|
324
|
+
'should', 'may', 'might', 'can', 'shall', 'to', 'of', 'in', 'for',
|
|
325
|
+
'on', 'with', 'at', 'by', 'from', 'as', 'into', 'through', 'during',
|
|
326
|
+
'before', 'after', 'above', 'below', 'between', 'out', 'off', 'over',
|
|
327
|
+
'under', 'again', 'further', 'then', 'once', 'here', 'there', 'when',
|
|
328
|
+
'where', 'why', 'how', 'all', 'each', 'every', 'both', 'few', 'more',
|
|
329
|
+
'most', 'other', 'some', 'such', 'no', 'not', 'only', 'own', 'same',
|
|
330
|
+
'so', 'than', 'too', 'very', 'just', 'because', 'but', 'and', 'or',
|
|
331
|
+
'if', 'while', 'about', 'this', 'that', 'these', 'those', 'what',
|
|
332
|
+
'which', 'who', 'whom', 'its', 'it', 'you', 'your', 'we', 'our',
|
|
333
|
+
'they', 'their', 'i', 'me', 'my', 'change', 'adding', 'using', 'make',
|
|
334
|
+
]);
|
|
335
|
+
/**
|
|
336
|
+
* Basic relevance check: extract key terms from the question and see
|
|
337
|
+
* if the answer mentions at least some of them (or related code concepts).
|
|
338
|
+
*/
|
|
339
|
+
function checkAnswerRelevance(question, answer) {
|
|
340
|
+
const questionTerms = question
|
|
341
|
+
.toLowerCase()
|
|
342
|
+
.replace(/[^a-z0-9\s]/g, ' ')
|
|
343
|
+
.split(/\s+/)
|
|
344
|
+
.filter(w => w.length > 2 && !STOP_WORDS.has(w));
|
|
345
|
+
if (questionTerms.length === 0)
|
|
346
|
+
return { relevant: true, reason: '' };
|
|
347
|
+
const answerLower = answer.toLowerCase();
|
|
348
|
+
// Check how many question terms appear in the answer
|
|
349
|
+
const mentioned = questionTerms.filter(term => answerLower.includes(term));
|
|
350
|
+
const ratio = mentioned.length / questionTerms.length;
|
|
351
|
+
// If less than 20% of key terms from the question appear in the answer,
|
|
352
|
+
// it's likely off-topic
|
|
353
|
+
if (ratio < 0.15 && questionTerms.length >= 2) {
|
|
354
|
+
return {
|
|
355
|
+
relevant: false,
|
|
356
|
+
reason: `Your answer does not appear to address the user's question about "${questionTerms.join(', ')}". Re-read the question and provide a specific, relevant answer.`,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
return { relevant: true, reason: '' };
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Build a correction message to inject when the answer is invalid.
|
|
363
|
+
*/
|
|
364
|
+
export function buildCorrectionMessage(reason) {
|
|
365
|
+
return [
|
|
366
|
+
`[SYSTEM: Your previous response was not acceptable. ${reason}`,
|
|
367
|
+
'Please search for more relevant code if needed and provide a proper, detailed Markdown answer with:',
|
|
368
|
+
'- Specific file paths and line numbers',
|
|
369
|
+
'- Relevant code snippets',
|
|
370
|
+
'- A clear explanation',
|
|
371
|
+
'Do NOT output JSON. Write a clean Markdown response.]',
|
|
372
|
+
].join(' ');
|
|
373
|
+
}
|
|
374
|
+
// ── Formatting helpers ────────────────────────────────────────────────────────
|
|
375
|
+
/**
|
|
376
|
+
* Format the search plan text as a visually distinct block.
|
|
377
|
+
* Uses dim blue with a left-border character (│) to set it apart from tool output.
|
|
378
|
+
*/
|
|
379
|
+
export function formatPlanBlock(planText, noColor) {
|
|
380
|
+
const lines = planText.split('\n');
|
|
381
|
+
if (noColor) {
|
|
382
|
+
return lines.map(l => ` │ ${l}`).join('\n');
|
|
383
|
+
}
|
|
384
|
+
return lines
|
|
385
|
+
.map(l => ` ${ansi(ANSI.dimBlue, '│')} ${ansi(ANSI.dimBlue, l)}`)
|
|
386
|
+
.join('\n');
|
|
387
|
+
}
|
|
388
|
+
/** Format an internal status message (compaction, critic, scratchpad, etc). Very dim. */
|
|
389
|
+
export function formatInternalStatus(message, noColor) {
|
|
390
|
+
if (noColor) {
|
|
391
|
+
return ` · ${message}`;
|
|
392
|
+
}
|
|
393
|
+
return ` ${ansi(ANSI.dimGray, '·')} ${ansi(ANSI.dimGray + ANSI.italic, message)}`;
|
|
394
|
+
}
|
|
395
|
+
/** Format a tool call for display — dim cyan to stay visually secondary. */
|
|
396
|
+
export function formatToolCall(name, args, noColor) {
|
|
397
|
+
if (noColor) {
|
|
398
|
+
return ` ▸ ${name}(${Object.entries(args).map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(', ')})`;
|
|
399
|
+
}
|
|
400
|
+
const formattedArgs = Object.entries(args)
|
|
401
|
+
.map(([k, v]) => `${ansi(ANSI.gray, k)}${ansi(ANSI.dimGray, '=')}${ansi(ANSI.dimYellow, JSON.stringify(v))}`)
|
|
402
|
+
.join(ansi(ANSI.dimGray, ', '));
|
|
403
|
+
return ` ${ansi(ANSI.dimCyan, '▸')} ${ansi(ANSI.dimCyan, name)}${ansi(ANSI.dimGray, '(')}${formattedArgs}${ansi(ANSI.dimGray, ')')}`;
|
|
404
|
+
}
|
|
405
|
+
/** Format a tool result summary for display — very dim, background-level. */
|
|
406
|
+
export function formatToolResult(output, noColor) {
|
|
407
|
+
const maxLen = 200;
|
|
408
|
+
const preview = output.replace(/\n/g, ' ↵ ').slice(0, maxLen);
|
|
409
|
+
const truncated = output.length > maxLen ? '…' : '';
|
|
410
|
+
if (noColor) {
|
|
411
|
+
return ` → ${preview}${truncated}`;
|
|
412
|
+
}
|
|
413
|
+
return ` ${ansi(ANSI.dimGreen, '→')} ${ansi(ANSI.dimGray, preview + truncated)}`;
|
|
414
|
+
}
|
|
415
|
+
/** Print a section separator — bold accent to clearly demarcate phases. */
|
|
416
|
+
export function formatSeparator(label, noColor) {
|
|
417
|
+
const line = '─'.repeat(Math.max(0, 60 - label.length - 2));
|
|
418
|
+
if (noColor) {
|
|
419
|
+
return `\n── ${label} ${line}\n`;
|
|
420
|
+
}
|
|
421
|
+
return `\n${ansi(ANSI.dim, '──')} ${ansi(ANSI.bold + ANSI.magenta, label)} ${ansi(ANSI.dim, line)}\n`;
|
|
422
|
+
}
|
|
423
|
+
/** Format a duplicate skip message — dim red. */
|
|
424
|
+
export function formatDuplicateSkip(name, noColor) {
|
|
425
|
+
if (noColor) {
|
|
426
|
+
return ` ✕ skipped duplicate: ${name}`;
|
|
427
|
+
}
|
|
428
|
+
return ` ${ansi(ANSI.dim + ANSI.red, '✕')} ${ansi(ANSI.dimGray, `skipped duplicate: ${name}`)}`;
|
|
429
|
+
}
|
|
430
|
+
/** Format a retry/validation message — dim yellow, secondary prominence. */
|
|
431
|
+
export function formatRetry(message, noColor) {
|
|
432
|
+
if (noColor) {
|
|
433
|
+
return ` ⟳ ${message}`;
|
|
434
|
+
}
|
|
435
|
+
return ` ${ansi(ANSI.dimYellow, '⟳')} ${ansi(ANSI.dimGray + ANSI.italic, message)}`;
|
|
436
|
+
}
|
|
437
|
+
/** Format a correction hint injection message. */
|
|
438
|
+
export function formatHintInjection(noColor) {
|
|
439
|
+
if (noColor) {
|
|
440
|
+
return ` ⚠ injecting search guidance…`;
|
|
441
|
+
}
|
|
442
|
+
return ` ${ansi(ANSI.dimYellow, '⚠')} ${ansi(ANSI.dimGray + ANSI.italic, 'injecting search guidance…')}`;
|
|
443
|
+
}
|
|
444
|
+
/** Format usage stats — small dim footer. */
|
|
445
|
+
export function formatUsage(promptTokens, completionTokens, totalTokens, noColor) {
|
|
446
|
+
const str = `tokens: ${promptTokens} prompt + ${completionTokens} completion = ${totalTokens} total`;
|
|
447
|
+
return noColor ? str : ansi(ANSI.dimGray, str);
|
|
448
|
+
}
|
|
449
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/utils/agent.ts"],"names":[],"mappings":"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"}
|