@ekzs/cli 0.3.5 → 0.3.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/LICENSE +21 -0
- package/README.md +12 -12
- package/dist/commands/ask.d.ts.map +1 -1
- package/dist/commands/ask.js +12 -5
- package/dist/commands/local-agent.d.ts.map +1 -1
- package/dist/commands/local-agent.js +47 -3
- package/dist/lib/context.d.ts +12 -2
- package/dist/lib/context.d.ts.map +1 -1
- package/dist/lib/context.js +75 -23
- package/dist/lib/doctor-quiet.d.ts +3 -1
- package/dist/lib/doctor-quiet.d.ts.map +1 -1
- package/dist/lib/doctor-quiet.js +16 -2
- package/dist/lib/local-answer.d.ts +4 -0
- package/dist/lib/local-answer.d.ts.map +1 -0
- package/dist/lib/local-answer.js +26 -0
- package/dist/lib/providers/agent-runner.d.ts +1 -0
- package/dist/lib/providers/agent-runner.d.ts.map +1 -1
- package/dist/lib/providers/agent-runner.js +48 -22
- package/dist/lib/providers/catalog.d.ts +14 -0
- package/dist/lib/providers/catalog.d.ts.map +1 -1
- package/dist/lib/providers/catalog.js +125 -38
- package/dist/lib/providers/chat.d.ts.map +1 -1
- package/dist/lib/providers/chat.js +46 -31
- package/dist/lib/providers/cursor-runner.d.ts.map +1 -1
- package/dist/lib/providers/cursor-runner.js +16 -8
- package/dist/lib/providers/http.d.ts +6 -0
- package/dist/lib/providers/http.d.ts.map +1 -0
- package/dist/lib/providers/http.js +35 -0
- package/dist/lib/providers/ui.d.ts.map +1 -1
- package/dist/lib/providers/ui.js +4 -3
- package/dist/lib/skills.d.ts +3 -1
- package/dist/lib/skills.d.ts.map +1 -1
- package/dist/lib/skills.js +18 -8
- package/dist/lib/terminal-answer.d.ts +5 -0
- package/dist/lib/terminal-answer.d.ts.map +1 -0
- package/dist/lib/terminal-answer.js +55 -0
- package/package.json +2 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alberto Moises
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @ekzs/cli
|
|
2
2
|
|
|
3
|
-
**Version:** 0.3.
|
|
3
|
+
**Version:** 0.3.8
|
|
4
4
|
|
|
5
5
|
**Ekz** is a local coding agent for e-Kwanza Pagamento Integrado v2.4 — like Claude Code, but specialized for `@ekzs/connect`, GPO, EMIS ref, and Ticket integrations.
|
|
6
6
|
|
|
@@ -65,17 +65,17 @@ Setup required · Configuração necessária · 需要设置
|
|
|
65
65
|
|
|
66
66
|
### Supported providers
|
|
67
67
|
|
|
68
|
-
| Provider | Example models |
|
|
69
|
-
|
|
70
|
-
| **Cursor** |
|
|
71
|
-
| **OpenAI** | `gpt-
|
|
72
|
-
| **Anthropic** | `claude-sonnet-4-
|
|
73
|
-
| **DeepSeek** | `deepseek-
|
|
74
|
-
| **Kimi (Moonshot)** | `
|
|
75
|
-
| **Groq** | `llama-3.3-70b-versatile`, … |
|
|
76
|
-
| **Mistral** | `mistral-large-latest`, `codestral-latest`, … |
|
|
77
|
-
| **Google Gemini** | `gemini-
|
|
78
|
-
| **Ollama** | `llama3.
|
|
68
|
+
| Provider | Example models (May 2026) |
|
|
69
|
+
|----------|---------------------------|
|
|
70
|
+
| **Cursor** | `composer-2.5-fast`, `composer-2.5`, `claude-4.6-sonnet-thinking`, `gpt-5.5`, … |
|
|
71
|
+
| **OpenAI** | `gpt-5.5`, `gpt-5.4-mini`, `gpt-4.1`, `o3`, `o4-mini`, … |
|
|
72
|
+
| **Anthropic** | `claude-sonnet-4-6`, `claude-opus-4-7`, `claude-haiku-4-5-20251001`, … |
|
|
73
|
+
| **DeepSeek** | `deepseek-v4-flash`, `deepseek-v4-pro` (legacy: `deepseek-chat` until Jul 2026) |
|
|
74
|
+
| **Kimi (Moonshot)** | `kimi-k2.6`, `kimi-k2.5`, `moonshot-v1-8k`, … |
|
|
75
|
+
| **Groq** | `llama-3.3-70b-versatile`, `openai/gpt-oss-120b`, `qwen/qwen3-32b`, … |
|
|
76
|
+
| **Mistral** | `mistral-large-latest`, `codestral-latest`, `devstral-latest`, … |
|
|
77
|
+
| **Google Gemini** | `gemini-3.5-flash`, `gemini-3.1-pro-preview`, `gemini-2.5-pro`, … |
|
|
78
|
+
| **Ollama** | `llama3.3`, `qwen3:8b`, `deepseek-r1:8b`, … (local tags) |
|
|
79
79
|
|
|
80
80
|
Manage keys anytime:
|
|
81
81
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../src/commands/ask.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAA0B,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../src/commands/ask.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAA0B,MAAM,kBAAkB,CAAC;AA2C1E,MAAM,MAAM,UAAU,GAAG;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB,CAAC;AAEF,mDAAmD;AACnD,wBAAsB,cAAc,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAgC1E;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,iBAO9D;AAgDD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,iBAwEA;AAED,wBAAsB,eAAe,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAM/E"}
|
package/dist/commands/ask.js
CHANGED
|
@@ -6,6 +6,8 @@ import { parseMode } from "../lib/mode.js";
|
|
|
6
6
|
import { fail, heading, info, ok } from "../lib/output.js";
|
|
7
7
|
import { loadPreferences, savePreferences } from "../lib/preferences.js";
|
|
8
8
|
import { ensureAgentReady, offlineModelLabel } from "../lib/onboarding.js";
|
|
9
|
+
import { localQuickAnswer } from "../lib/local-answer.js";
|
|
10
|
+
import { formatTerminalAnswer } from "../lib/terminal-answer.js";
|
|
9
11
|
import { executeByokAskTurn } from "../lib/providers/chat.js";
|
|
10
12
|
import { executeCursorAskTurn } from "../lib/providers/cursor-runner.js";
|
|
11
13
|
import { isCursorProvider, requireActiveCredentials, ProviderSetupError, } from "../lib/providers/credentials.js";
|
|
@@ -14,24 +16,29 @@ import { redactText } from "../lib/redact.js";
|
|
|
14
16
|
import { askWithPlaceholder, formatInputPrompt } from "../lib/ui/prompt.js";
|
|
15
17
|
import { inputPlaceholder } from "../lib/ui/splash.js";
|
|
16
18
|
function deterministicAnswer(question, ctx, locale) {
|
|
17
|
-
const lines = ["
|
|
19
|
+
const lines = ["Ekz assistant (offline):", "", question, ""];
|
|
18
20
|
if (ctx.doctor.issues.length) {
|
|
19
|
-
lines.push("
|
|
21
|
+
lines.push("Issues:", ...ctx.doctor.issues.map((i) => `- ${i}`), "");
|
|
20
22
|
}
|
|
21
23
|
if (ctx.scan.length) {
|
|
22
|
-
lines.push("
|
|
24
|
+
lines.push("Scan:", ...ctx.scan.slice(0, 8).map((f) => `- \`${f.file}:${f.line}\` · ${f.message}`), "");
|
|
23
25
|
}
|
|
24
|
-
lines.push("
|
|
26
|
+
lines.push("Next steps:", "- Run `ekz setup` to configure language, name, and provider", "- Or `ekz --offline` for doctor/scan only");
|
|
25
27
|
return lines.join("\n");
|
|
26
28
|
}
|
|
27
29
|
/** Q&A via BYOK provider (no local file edits). */
|
|
28
30
|
export async function executeAskTurn(options) {
|
|
29
31
|
const { cwd, question, offline, quiet, locale = "pt" } = options;
|
|
32
|
+
const quick = localQuickAnswer(question, locale);
|
|
33
|
+
if (quick) {
|
|
34
|
+
console.log("\n" + quick);
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
30
37
|
if (offline) {
|
|
31
38
|
const ctx = await buildBootstrapContext(cwd);
|
|
32
39
|
if (!quiet)
|
|
33
40
|
info("Ask mode (offline) · no file edits.\n");
|
|
34
|
-
console.log("\n" + deterministicAnswer(question, ctx, locale));
|
|
41
|
+
console.log("\n" + formatTerminalAnswer(deterministicAnswer(question, ctx, locale)));
|
|
35
42
|
return true;
|
|
36
43
|
}
|
|
37
44
|
let creds;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-agent.d.ts","sourceRoot":"","sources":["../../src/commands/local-agent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"local-agent.d.ts","sourceRoot":"","sources":["../../src/commands/local-agent.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAsC,KAAK,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAsBlF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAiQF,wBAAsB,aAAa,CAAC,IAAI,EAAE,iBAAiB,iBA0I1D;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,aAAa,CAAC,iBAmG9F"}
|
|
@@ -6,9 +6,10 @@ import { inputPlaceholder, printHelp, printLangSwitch, printModeSwitch, printWel
|
|
|
6
6
|
import { loadProjectEnv } from "../lib/env.js";
|
|
7
7
|
import { ensureAgentReady, offlineAgentHint, offlineModelLabel } from "../lib/onboarding.js";
|
|
8
8
|
import { resolveReplMetaCommand, isProvidersMetaCommand } from "../lib/commands-i18n.js";
|
|
9
|
-
import { buildAgentPrompt, buildBootstrapContext } from "../lib/context.js";
|
|
9
|
+
import { buildAgentPrompt, buildBootstrapContext, invalidateBootstrapContext, isLiteTurn, wantsLocalScan, } from "../lib/context.js";
|
|
10
10
|
import { resolveComposerModel } from "../lib/composer-model.js";
|
|
11
11
|
import { parseLocale, uiStrings } from "../lib/locale.js";
|
|
12
|
+
import { localQuickAnswer } from "../lib/local-answer.js";
|
|
12
13
|
import { modeRequiresCursorAgent, parseMode } from "../lib/mode.js";
|
|
13
14
|
import { loadPreferences, savePreferences } from "../lib/preferences.js";
|
|
14
15
|
import { runByokAgentTurn, usesCursorSdk } from "../lib/providers/agent-runner.js";
|
|
@@ -47,13 +48,14 @@ function providerModelLabel(creds) {
|
|
|
47
48
|
return `${creds.definition.name} · ${creds.model}`;
|
|
48
49
|
}
|
|
49
50
|
async function runAgentTurn(options) {
|
|
51
|
+
const lite = options.lite ?? isLiteTurn(options.task);
|
|
50
52
|
if (usesCursorSdk(options.creds)) {
|
|
51
53
|
if (!options.cursorAgent) {
|
|
52
54
|
fail(options.locale === "pt" ? "Sem agente Cursor activo." : "No active Cursor agent.");
|
|
53
55
|
return { cursorAgent: null, ok: false };
|
|
54
56
|
}
|
|
55
|
-
const ctx = await buildBootstrapContext(options.cwd);
|
|
56
|
-
const prompt = buildAgentPrompt(options.task, ctx, options.locale);
|
|
57
|
+
const ctx = await buildBootstrapContext(options.cwd, { includeScan: !lite });
|
|
58
|
+
const prompt = buildAgentPrompt(options.task, ctx, options.locale, { lite });
|
|
57
59
|
try {
|
|
58
60
|
await streamRun(options.cursorAgent, prompt, options.locale);
|
|
59
61
|
console.log("\n");
|
|
@@ -73,6 +75,7 @@ async function runAgentTurn(options) {
|
|
|
73
75
|
creds: options.creds,
|
|
74
76
|
locale: options.locale,
|
|
75
77
|
mode: options.mode,
|
|
78
|
+
lite,
|
|
76
79
|
});
|
|
77
80
|
return { cursorAgent: options.cursorAgent, ok: okResult };
|
|
78
81
|
}
|
|
@@ -161,10 +164,12 @@ function handleMetaCommand(line, locale, cwd, currentMode) {
|
|
|
161
164
|
return { kind: "mode", mode: next };
|
|
162
165
|
}
|
|
163
166
|
if (cmd === "doctor") {
|
|
167
|
+
invalidateBootstrapContext(cwd);
|
|
164
168
|
void runDoctor(cwd).then(() => console.log(""));
|
|
165
169
|
return { kind: "handled" };
|
|
166
170
|
}
|
|
167
171
|
if (cmd === "scan") {
|
|
172
|
+
invalidateBootstrapContext(cwd);
|
|
168
173
|
void runScan(cwd).then(() => console.log(""));
|
|
169
174
|
return { kind: "handled" };
|
|
170
175
|
}
|
|
@@ -489,6 +494,21 @@ async function runRepl(opts) {
|
|
|
489
494
|
if (live) {
|
|
490
495
|
currentOffline = false;
|
|
491
496
|
currentCreds = live;
|
|
497
|
+
if (currentMode !== "ask" && usesCursorSdk(live)) {
|
|
498
|
+
currentAgent = await recreateAgentForMode(opts.cwd, currentAgent, currentMode, opts.apiKey, currentLocale);
|
|
499
|
+
}
|
|
500
|
+
else if (currentAgent) {
|
|
501
|
+
await disposeAgent(currentAgent);
|
|
502
|
+
currentAgent = null;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
currentOffline = true;
|
|
507
|
+
currentCreds = null;
|
|
508
|
+
if (currentAgent) {
|
|
509
|
+
await disposeAgent(currentAgent);
|
|
510
|
+
currentAgent = null;
|
|
511
|
+
}
|
|
492
512
|
}
|
|
493
513
|
continue;
|
|
494
514
|
}
|
|
@@ -569,7 +589,24 @@ async function runRepl(opts) {
|
|
|
569
589
|
}
|
|
570
590
|
console.log("");
|
|
571
591
|
process.stdout.write(turnDivider());
|
|
592
|
+
const quick = localQuickAnswer(line, currentLocale);
|
|
593
|
+
if (quick) {
|
|
594
|
+
console.log(quick + "\n");
|
|
595
|
+
turn++;
|
|
596
|
+
continue;
|
|
597
|
+
}
|
|
598
|
+
if (wantsLocalScan(line)) {
|
|
599
|
+
invalidateBootstrapContext(opts.cwd);
|
|
600
|
+
info(currentLocale === "pt" ? "Scan local (sem LLM)..." : "Local scan (no LLM)...");
|
|
601
|
+
await runScan(opts.cwd);
|
|
602
|
+
console.log("\n");
|
|
603
|
+
turn++;
|
|
604
|
+
continue;
|
|
605
|
+
}
|
|
572
606
|
if (currentMode === "ask") {
|
|
607
|
+
if (!currentOffline && resolveCreds()) {
|
|
608
|
+
info(`${currentCreds.definition.name} · ${currentCreds.model}…`);
|
|
609
|
+
}
|
|
573
610
|
await executeAskTurn({
|
|
574
611
|
cwd: opts.cwd,
|
|
575
612
|
question: line,
|
|
@@ -591,8 +628,14 @@ async function runRepl(opts) {
|
|
|
591
628
|
fail(currentLocale === "pt" ? "Sem agente Cursor activo." : "No active Cursor agent.");
|
|
592
629
|
continue;
|
|
593
630
|
}
|
|
631
|
+
info(currentLocale === "pt"
|
|
632
|
+
? `${creds.definition.name} · ${creds.model}…`
|
|
633
|
+
: currentLocale === "zh"
|
|
634
|
+
? `${creds.definition.name} · ${creds.model}…`
|
|
635
|
+
: `${creds.definition.name} · ${creds.model}…`);
|
|
594
636
|
if (currentAgent)
|
|
595
637
|
await persistAgent(opts.cwd, currentAgent, creds);
|
|
638
|
+
const lite = isLiteTurn(line);
|
|
596
639
|
const outcome = await runAgentTurn({
|
|
597
640
|
cwd: opts.cwd,
|
|
598
641
|
task: line,
|
|
@@ -600,6 +643,7 @@ async function runRepl(opts) {
|
|
|
600
643
|
locale: currentLocale,
|
|
601
644
|
mode: currentMode,
|
|
602
645
|
cursorAgent: currentAgent,
|
|
646
|
+
lite,
|
|
603
647
|
});
|
|
604
648
|
if (outcome.cursorAgent)
|
|
605
649
|
currentAgent = outcome.cursorAgent;
|
package/dist/lib/context.d.ts
CHANGED
|
@@ -6,7 +6,17 @@ export type BootstrapContext = {
|
|
|
6
6
|
scan: Awaited<ReturnType<typeof collectScanFindings>>;
|
|
7
7
|
env: Record<string, string>;
|
|
8
8
|
};
|
|
9
|
-
export declare function
|
|
10
|
-
|
|
9
|
+
export declare function invalidateBootstrapContext(cwd?: string): void;
|
|
10
|
+
/** Integration-heavy tasks need repo scan + full skill bundle. */
|
|
11
|
+
export declare function needsIntegrationContext(task: string): boolean;
|
|
12
|
+
export declare function isLiteTurn(task: string): boolean;
|
|
13
|
+
export declare function wantsLocalScan(line: string): boolean;
|
|
14
|
+
export declare function buildBootstrapContext(cwd: string, options?: {
|
|
15
|
+
refresh?: boolean;
|
|
16
|
+
includeScan?: boolean;
|
|
17
|
+
}): Promise<BootstrapContext>;
|
|
18
|
+
export declare function buildAgentPrompt(task: string, ctx: BootstrapContext, locale?: EkzLocale, options?: {
|
|
19
|
+
lite?: boolean;
|
|
20
|
+
}): string;
|
|
11
21
|
export declare const FIX_DEFAULT_TASK = "Audit this project's e-Kwanza v2.4 integration end-to-end.\nFix env wiring, payment rails (gpo / emis_ref / ticket), checkout flows, and webhook handlers.\nUse @ekzs/connect. Follow the loaded Ekz skills. Stay within e-Kwanza payment scope only \u2014 read unrelated code for context, do not edit it.\nAfter edits, suggest running `ekz doctor`.";
|
|
12
22
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/lib/context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/lib/context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAItD,OAAO,EAAE,KAAK,SAAS,EAAuB,MAAM,aAAa,CAAC;AAMlE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC;IACxD,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC;IACtD,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B,CAAC;AASF,wBAAgB,0BAA0B,CAAC,GAAG,CAAC,EAAE,MAAM,QAGtD;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAS7D;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,GACrD,OAAO,CAAC,gBAAgB,CAAC,CA6B3B;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,gBAAgB,EACrB,MAAM,GAAE,SAAgB,EACxB,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC3B,MAAM,CA4CR;AAED,eAAO,MAAM,gBAAgB,6VAGgB,CAAC"}
|
package/dist/lib/context.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolve } from "path";
|
|
1
2
|
import { collectDoctorResult } from "./doctor-quiet.js";
|
|
2
3
|
import { collectScanFindings } from "./scan-quiet.js";
|
|
3
4
|
import { loadProjectEnv } from "./env.js";
|
|
@@ -6,23 +7,81 @@ import { formatSkillsForPrompt, selectSkillsForTask } from "./skills.js";
|
|
|
6
7
|
import { languageInstruction } from "./locale.js";
|
|
7
8
|
import { agentScopeBlock } from "./scope.js";
|
|
8
9
|
import { detectShellEnvironment, shellGuidanceBlock } from "./shell.js";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
import { isLocalQuickTurn } from "./local-answer.js";
|
|
11
|
+
import { terminalStyleInstruction } from "./terminal-answer.js";
|
|
12
|
+
const bootstrapCache = new Map();
|
|
13
|
+
export function invalidateBootstrapContext(cwd) {
|
|
14
|
+
if (cwd)
|
|
15
|
+
bootstrapCache.delete(resolve(cwd));
|
|
16
|
+
else
|
|
17
|
+
bootstrapCache.clear();
|
|
18
|
+
}
|
|
19
|
+
/** Integration-heavy tasks need repo scan + full skill bundle. */
|
|
20
|
+
export function needsIntegrationContext(task) {
|
|
21
|
+
const t = task.trim();
|
|
22
|
+
if (t.length < 4)
|
|
23
|
+
return false;
|
|
24
|
+
if (isLocalQuickTurn(t)) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
return /ekwanza|webhook|gpo|emis|ticket|checkout|integr|doctor|scan|payment|cobran|multicaixa|fix|\.env|rail|sdk|connect|audit|implement|starter|projeto|project|merchant|cobrança|referência|multicaixa|appypay|oauth|env var/i.test(t);
|
|
28
|
+
}
|
|
29
|
+
export function isLiteTurn(task) {
|
|
30
|
+
return !needsIntegrationContext(task);
|
|
31
|
+
}
|
|
32
|
+
export function wantsLocalScan(line) {
|
|
33
|
+
return /\b(scan|analis[aá]r?)\b/i.test(line) && /\b(run|corre|execut|faz|do|faça)\b/i.test(line);
|
|
34
|
+
}
|
|
35
|
+
export async function buildBootstrapContext(cwd, options) {
|
|
36
|
+
const root = resolve(cwd);
|
|
37
|
+
const includeScan = options?.includeScan !== false;
|
|
38
|
+
if (!options?.refresh && bootstrapCache.has(root)) {
|
|
39
|
+
const cached = bootstrapCache.get(root);
|
|
40
|
+
if (!includeScan || cached.scanComplete)
|
|
41
|
+
return cached.ctx;
|
|
42
|
+
}
|
|
43
|
+
const doctor = await collectDoctorResult(root, { live: false });
|
|
44
|
+
const scan = includeScan
|
|
45
|
+
? await collectScanFindings(root)
|
|
46
|
+
: bootstrapCache.get(root)?.ctx.scan ?? [];
|
|
47
|
+
const { env } = loadProjectEnv(root);
|
|
13
48
|
const envSnapshot = {};
|
|
14
49
|
for (const key of Object.keys(env)) {
|
|
15
50
|
if (key.startsWith("EKWANZA_") || key.startsWith("EKZ_")) {
|
|
16
51
|
envSnapshot[key] = env[key];
|
|
17
52
|
}
|
|
18
53
|
}
|
|
19
|
-
|
|
54
|
+
const ctx = {
|
|
55
|
+
doctor,
|
|
56
|
+
scan,
|
|
57
|
+
env: redactEnv(envSnapshot),
|
|
58
|
+
};
|
|
59
|
+
bootstrapCache.set(root, { ctx, scanComplete: includeScan });
|
|
60
|
+
return ctx;
|
|
20
61
|
}
|
|
21
|
-
export function buildAgentPrompt(task, ctx, locale = "pt") {
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
62
|
+
export function buildAgentPrompt(task, ctx, locale = "pt", options) {
|
|
63
|
+
const lite = options?.lite ?? isLiteTurn(task);
|
|
64
|
+
const scanHints = lite ? [] : ctx.scan.map((f) => `${f.rule}: ${f.message}`);
|
|
65
|
+
const skills = selectSkillsForTask(task, scanHints, { lite });
|
|
66
|
+
const skillBlock = lite
|
|
67
|
+
? `# Skill: ekz-connect\n\nScoped e-Kwanza v2.4 assistant. Use /analisar or /diagnóstico for free local checks.`
|
|
68
|
+
: formatSkillsForPrompt(skills);
|
|
25
69
|
const shell = detectShellEnvironment();
|
|
70
|
+
const diagnostics = lite
|
|
71
|
+
? {
|
|
72
|
+
issues: ctx.doctor.issues.slice(0, 6),
|
|
73
|
+
rails: ctx.doctor.rails,
|
|
74
|
+
envKeys: Object.keys(ctx.env),
|
|
75
|
+
}
|
|
76
|
+
: {
|
|
77
|
+
issues: ctx.doctor.issues,
|
|
78
|
+
warnings: ctx.doctor.warnings,
|
|
79
|
+
rails: ctx.doctor.rails,
|
|
80
|
+
health: ctx.doctor.health,
|
|
81
|
+
scan: ctx.scan.slice(0, 12),
|
|
82
|
+
env: ctx.env,
|
|
83
|
+
shell,
|
|
84
|
+
};
|
|
26
85
|
return `${skillBlock}
|
|
27
86
|
|
|
28
87
|
---
|
|
@@ -32,20 +91,13 @@ Never commit secrets.
|
|
|
32
91
|
|
|
33
92
|
${agentScopeBlock(locale)}
|
|
34
93
|
|
|
35
|
-
${shellGuidanceBlock(locale)}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
warnings: ctx.doctor.warnings,
|
|
43
|
-
rails: ctx.doctor.rails,
|
|
44
|
-
health: ctx.doctor.health,
|
|
45
|
-
scan: ctx.scan.slice(0, 12),
|
|
46
|
-
env: ctx.env,
|
|
47
|
-
shell,
|
|
48
|
-
}, null, 2)}
|
|
94
|
+
${lite ? "" : `${shellGuidanceBlock(locale)}\n\n`}
|
|
95
|
+
${languageInstruction(locale)}
|
|
96
|
+
|
|
97
|
+
${terminalStyleInstruction(locale)}
|
|
98
|
+
|
|
99
|
+
## Pre-flight diagnostics (ekz doctor + scan)
|
|
100
|
+
${JSON.stringify(diagnostics, null, 2)}
|
|
49
101
|
|
|
50
102
|
## Task
|
|
51
103
|
${task}`;
|
|
@@ -7,5 +7,7 @@ export type DoctorResult = {
|
|
|
7
7
|
warnings: string[];
|
|
8
8
|
health: Awaited<ReturnType<EkzConnect["healthCheck"]>> | null;
|
|
9
9
|
};
|
|
10
|
-
export declare function collectDoctorResult(cwd: string
|
|
10
|
+
export declare function collectDoctorResult(cwd: string, options?: {
|
|
11
|
+
live?: boolean;
|
|
12
|
+
}): Promise<DoctorResult>;
|
|
11
13
|
//# sourceMappingURL=doctor-quiet.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-quiet.d.ts","sourceRoot":"","sources":["../../src/lib/doctor-quiet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAiB,MAAM,eAAe,CAAC;AAE1D,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;CAC/D,CAAC;AAEF,wBAAsB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"doctor-quiet.d.ts","sourceRoot":"","sources":["../../src/lib/doctor-quiet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAiB,MAAM,eAAe,CAAC;AAE1D,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;CAC/D,CAAC;AAEF,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC3B,OAAO,CAAC,YAAY,CAAC,CAkDvB"}
|
package/dist/lib/doctor-quiet.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EkzConnect, configFromEnv } from "@ekzs/connect";
|
|
2
2
|
import { auditEnv, loadProjectEnv } from "./env.js";
|
|
3
|
-
export async function collectDoctorResult(cwd) {
|
|
3
|
+
export async function collectDoctorResult(cwd, options) {
|
|
4
|
+
const live = options?.live !== false;
|
|
4
5
|
const { envFiles, env } = loadProjectEnv(cwd);
|
|
5
6
|
const audit = auditEnv(env);
|
|
6
7
|
const issues = [];
|
|
@@ -18,13 +19,26 @@ export async function collectDoctorResult(cwd) {
|
|
|
18
19
|
}
|
|
19
20
|
let health = null;
|
|
20
21
|
const cfg = configFromEnv(env);
|
|
21
|
-
if (cfg) {
|
|
22
|
+
if (cfg && live) {
|
|
22
23
|
health = await new EkzConnect(cfg).healthCheck();
|
|
23
24
|
if (!health.oauth)
|
|
24
25
|
issues.push("OAuth authentication failed");
|
|
25
26
|
if (!health.configured)
|
|
26
27
|
warnings.push("healthCheck.configured is false");
|
|
27
28
|
}
|
|
29
|
+
else if (cfg && !live) {
|
|
30
|
+
health = {
|
|
31
|
+
oauth: false,
|
|
32
|
+
gpo: Boolean(cfg.paymentMethodIdGpo),
|
|
33
|
+
emisRef: Boolean(cfg.paymentMethodIdEmisRef),
|
|
34
|
+
ticket: Boolean(cfg.notificationToken && cfg.apiKey && cfg.partnerRegistrationNumber),
|
|
35
|
+
configured: Boolean(cfg.clientId &&
|
|
36
|
+
cfg.clientSecret &&
|
|
37
|
+
cfg.merchantIdentifier &&
|
|
38
|
+
cfg.apiKey),
|
|
39
|
+
env: cfg.env ?? "sandbox",
|
|
40
|
+
};
|
|
41
|
+
}
|
|
28
42
|
else {
|
|
29
43
|
issues.push("Core EKWANZA_* vars missing");
|
|
30
44
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-answer.d.ts","sourceRoot":"","sources":["../../src/lib/local-answer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAO7C,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGvD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAoBhF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const GREETING_RE = /^(olá|ola|oi|hello|hi|hey|bom dia|boa tarde|boa noite|你好|您好)[!.?\s]*$/i;
|
|
2
|
+
const THANKS_RE = /^(obrigado|obrigada|thanks|thank you|valeu|谢谢|多谢)[!.?\s]*$/i;
|
|
3
|
+
export function isLocalQuickTurn(input) {
|
|
4
|
+
const text = input.trim();
|
|
5
|
+
return GREETING_RE.test(text) || THANKS_RE.test(text);
|
|
6
|
+
}
|
|
7
|
+
export function localQuickAnswer(input, locale) {
|
|
8
|
+
const text = input.trim();
|
|
9
|
+
if (GREETING_RE.test(text)) {
|
|
10
|
+
if (locale === "zh") {
|
|
11
|
+
return "你好。我可以帮你处理 e-Kwanza 支付集成、checkout、webhook、订阅、票务和用量计费。告诉我你要接入什么,或运行 /scan 做本地诊断。";
|
|
12
|
+
}
|
|
13
|
+
if (locale === "en") {
|
|
14
|
+
return "Hello. I can help with e-Kwanza payments, checkout, webhooks, subscriptions, tickets, and overage billing. Tell me what you want to integrate, or run /scan for a local diagnostic.";
|
|
15
|
+
}
|
|
16
|
+
return "Olá. Posso ajudar com pagamentos e-Kwanza, checkout, webhooks, subscrições, tickets e cobrança de excedentes. Diz-me o que queres integrar, ou corre /scan para um diagnóstico local.";
|
|
17
|
+
}
|
|
18
|
+
if (THANKS_RE.test(text)) {
|
|
19
|
+
if (locale === "zh")
|
|
20
|
+
return "不客气。需要时我可以继续检查支付集成。";
|
|
21
|
+
if (locale === "en")
|
|
22
|
+
return "You are welcome. I can keep checking the payment integration whenever you are ready.";
|
|
23
|
+
return "De nada. Quando quiseres, posso continuar a verificar a integração de pagamentos.";
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
@@ -7,6 +7,7 @@ export declare function runByokAgentTurn(options: {
|
|
|
7
7
|
creds: ResolvedCredentials;
|
|
8
8
|
locale: EkzLocale;
|
|
9
9
|
mode: EkzMode;
|
|
10
|
+
lite?: boolean;
|
|
10
11
|
}): Promise<boolean>;
|
|
11
12
|
export declare function usesCursorSdk(creds: ResolvedCredentials): boolean;
|
|
12
13
|
//# sourceMappingURL=agent-runner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-runner.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/agent-runner.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-runner.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/agent-runner.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAI1C,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAsM5D,wBAAsB,gBAAgB,CAAC,OAAO,EAAE;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,mBAAmB,CAAC;IAC3B,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,OAAO,CAAC,CA0DnB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAEjE"}
|
|
@@ -1,34 +1,40 @@
|
|
|
1
1
|
import { resolve } from "path";
|
|
2
|
-
import { buildAgentPrompt, buildBootstrapContext } from "../context.js";
|
|
3
|
-
import {
|
|
2
|
+
import { buildAgentPrompt, buildBootstrapContext, isLiteTurn, needsIntegrationContext } from "../context.js";
|
|
3
|
+
import { localQuickAnswer } from "../local-answer.js";
|
|
4
|
+
import { fail, warn } from "../output.js";
|
|
5
|
+
import { formatTerminalAnswer } from "../terminal-answer.js";
|
|
4
6
|
import { toolDone, toolError, toolRunning } from "../theme.js";
|
|
7
|
+
import { deepseekRequestBody, fetchWithTimeout, resolveChatCompletionsUrl } from "./http.js";
|
|
5
8
|
import { AGENT_TOOL_DEFINITIONS, executeAgentTool } from "./tools.js";
|
|
6
|
-
const MAX_TOOL_ROUNDS =
|
|
9
|
+
const MAX_TOOL_ROUNDS = 12;
|
|
7
10
|
function planInstruction(mode) {
|
|
8
11
|
if (mode === "plan") {
|
|
9
|
-
return "You are in
|
|
12
|
+
return "You are in plan mode: output a clear numbered plan first. Only call write_file after the plan is clear.";
|
|
10
13
|
}
|
|
11
14
|
if (mode === "ask") {
|
|
12
|
-
return "You are in
|
|
15
|
+
return "You are in ask mode: answer only. Do not call write_file or run_command.";
|
|
13
16
|
}
|
|
14
|
-
return "You are in
|
|
17
|
+
return "You are in agent mode: use tools to inspect and fix the e-Kwanza integration.";
|
|
15
18
|
}
|
|
16
|
-
async function openAiAgentLoop(creds, cwd, messages, enableTools) {
|
|
17
|
-
const
|
|
18
|
-
const url = base.endsWith("/chat/completions") ? base : `${base}/chat/completions`;
|
|
19
|
+
async function openAiAgentLoop(creds, cwd, messages, enableTools, thinking = true, timeoutMs) {
|
|
20
|
+
const url = resolveChatCompletionsUrl(creds.baseUrl);
|
|
19
21
|
for (let round = 0; round < MAX_TOOL_ROUNDS; round++) {
|
|
20
22
|
const headers = { "Content-Type": "application/json" };
|
|
21
23
|
if (creds.apiKey && creds.apiKey !== "ollama") {
|
|
22
24
|
headers.Authorization = `Bearer ${creds.apiKey}`;
|
|
23
25
|
}
|
|
24
|
-
const
|
|
26
|
+
const payload = {
|
|
25
27
|
model: creds.model,
|
|
26
28
|
messages,
|
|
27
29
|
temperature: 0.2,
|
|
28
30
|
};
|
|
29
31
|
if (enableTools)
|
|
30
|
-
|
|
31
|
-
const res = await
|
|
32
|
+
payload.tools = AGENT_TOOL_DEFINITIONS;
|
|
33
|
+
const res = await fetchWithTimeout(url, {
|
|
34
|
+
method: "POST",
|
|
35
|
+
headers,
|
|
36
|
+
body: JSON.stringify(deepseekRequestBody(creds.model, payload, { thinking })),
|
|
37
|
+
}, timeoutMs);
|
|
32
38
|
const data = (await res.json().catch(() => ({})));
|
|
33
39
|
if (!res.ok)
|
|
34
40
|
throw new Error(data.error?.message ?? `Provider error (${res.status})`);
|
|
@@ -73,7 +79,7 @@ async function openAiAgentLoop(creds, cwd, messages, enableTools) {
|
|
|
73
79
|
}
|
|
74
80
|
throw new Error("Tool loop exceeded maximum rounds.");
|
|
75
81
|
}
|
|
76
|
-
async function anthropicAgentLoop(creds, cwd, system, messages, enableTools) {
|
|
82
|
+
async function anthropicAgentLoop(creds, cwd, system, messages, enableTools, timeoutMs) {
|
|
77
83
|
const tools = enableTools
|
|
78
84
|
? AGENT_TOOL_DEFINITIONS.map((t) => ({
|
|
79
85
|
name: t.function.name,
|
|
@@ -82,7 +88,7 @@ async function anthropicAgentLoop(creds, cwd, system, messages, enableTools) {
|
|
|
82
88
|
}))
|
|
83
89
|
: undefined;
|
|
84
90
|
for (let round = 0; round < MAX_TOOL_ROUNDS; round++) {
|
|
85
|
-
const res = await
|
|
91
|
+
const res = await fetchWithTimeout("https://api.anthropic.com/v1/messages", {
|
|
86
92
|
method: "POST",
|
|
87
93
|
headers: {
|
|
88
94
|
"Content-Type": "application/json",
|
|
@@ -96,7 +102,7 @@ async function anthropicAgentLoop(creds, cwd, system, messages, enableTools) {
|
|
|
96
102
|
messages,
|
|
97
103
|
...(tools ? { tools } : {}),
|
|
98
104
|
}),
|
|
99
|
-
});
|
|
105
|
+
}, timeoutMs);
|
|
100
106
|
const data = (await res.json().catch(() => ({})));
|
|
101
107
|
if (!res.ok)
|
|
102
108
|
throw new Error(data.error?.message ?? `Anthropic error (${res.status})`);
|
|
@@ -138,23 +144,43 @@ async function anthropicAgentLoop(creds, cwd, system, messages, enableTools) {
|
|
|
138
144
|
}
|
|
139
145
|
export async function runByokAgentTurn(options) {
|
|
140
146
|
const cwd = resolve(options.cwd);
|
|
141
|
-
const
|
|
142
|
-
|
|
147
|
+
const quick = localQuickAnswer(options.task, options.locale);
|
|
148
|
+
if (quick) {
|
|
149
|
+
console.log("\n" + quick);
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
const lite = options.lite ?? isLiteTurn(options.task);
|
|
153
|
+
const ctx = await buildBootstrapContext(cwd, { includeScan: !lite });
|
|
154
|
+
const prompt = buildAgentPrompt(options.task, ctx, options.locale, { lite });
|
|
143
155
|
const system = `${planInstruction(options.mode)}\n\n${prompt.split("## Task")[0] ?? prompt}`;
|
|
144
156
|
const userTask = `## Task\n${options.task}`;
|
|
145
|
-
const
|
|
157
|
+
const wantsTools = options.mode !== "ask" && !lite;
|
|
158
|
+
const enableTools = wantsTools && options.creds.definition.capabilities.supportsTools;
|
|
159
|
+
const thinking = !lite &&
|
|
160
|
+
options.creds.definition.capabilities.supportsReasoning &&
|
|
161
|
+
needsIntegrationContext(options.task);
|
|
162
|
+
const timeoutMs = lite
|
|
163
|
+
? options.creds.definition.capabilities.liteTimeoutMs
|
|
164
|
+
: options.creds.definition.capabilities.agentTimeoutMs;
|
|
165
|
+
if (wantsTools && !enableTools) {
|
|
166
|
+
warn(options.locale === "pt"
|
|
167
|
+
? `${options.creds.definition.name} não anuncia ferramentas de edição; vou responder sem alterar ficheiros.`
|
|
168
|
+
: options.locale === "zh"
|
|
169
|
+
? `${options.creds.definition.name} 未声明编辑工具支持;我将只回答,不修改文件。`
|
|
170
|
+
: `${options.creds.definition.name} does not advertise edit tools; answering without changing files.`);
|
|
171
|
+
}
|
|
146
172
|
try {
|
|
147
173
|
if (options.creds.definition.kind === "anthropic") {
|
|
148
|
-
const text = await anthropicAgentLoop(options.creds, cwd, system, [{ role: "user", content: userTask }], enableTools);
|
|
149
|
-
console.log("\n" + text);
|
|
174
|
+
const text = await anthropicAgentLoop(options.creds, cwd, system, [{ role: "user", content: userTask }], enableTools, timeoutMs);
|
|
175
|
+
console.log("\n" + formatTerminalAnswer(text));
|
|
150
176
|
return true;
|
|
151
177
|
}
|
|
152
178
|
const messages = [
|
|
153
179
|
{ role: "system", content: system },
|
|
154
180
|
{ role: "user", content: userTask },
|
|
155
181
|
];
|
|
156
|
-
const text = await openAiAgentLoop(options.creds, cwd, messages, enableTools);
|
|
157
|
-
console.log("\n" + text);
|
|
182
|
+
const text = await openAiAgentLoop(options.creds, cwd, messages, enableTools, thinking, timeoutMs);
|
|
183
|
+
console.log("\n" + formatTerminalAnswer(text));
|
|
158
184
|
return true;
|
|
159
185
|
}
|
|
160
186
|
catch (err) {
|