ft-scout 9.4.5 → 9.4.6
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/.firebase/hosting.d2Vi.cache +7 -7
- package/README.md +2 -2
- package/bin/src/engine/agentEngine.d.ts.map +1 -1
- package/bin/src/engine/agentEngine.js +59 -11
- package/bin/src/engine/agentEngine.js.map +1 -1
- package/bin/src/engine/llm.d.ts.map +1 -1
- package/bin/src/engine/llm.js +76 -29
- package/bin/src/engine/llm.js.map +1 -1
- package/bin/src/engine/runtime/agentRuntime.d.ts.map +1 -1
- package/bin/src/engine/runtime/agentRuntime.js +29 -4
- package/bin/src/engine/runtime/agentRuntime.js.map +1 -1
- package/bin/src/index.js +4 -4
- package/bin/src/mcp/client.js +1 -1
- package/bin/src/utils/branding.js +1 -1
- package/bin/src/utils/qrBridge.js +1 -1
- package/package.json +2 -1
- package/web/app.js +2 -2
- package/web/styles.css +2 -2
- package/artifacts/scout_drone_3d.glb +0 -0
- package/artifacts/scout_drone_3d_render.png +0 -0
|
@@ -7,10 +7,10 @@ robots.txt,1789399790675,418c5507fe368b5796fdb0751f0ca1670caf4a6eefcee5068223854
|
|
|
7
7
|
og-image.png,1789399497410,8be057c37517aa535ca2b7f3487cbd4e3971ff8a3666823d455bf2aea98d2261
|
|
8
8
|
oauth.html,1789398886636,3e8a49ae29c1595e1fcefaf44f64f98cf7c9eb4d08bfae6917e6d9f595046784
|
|
9
9
|
ft-logo.png,1789399419347,f208460882dfbd12aeacdab811ed69dab9ef9e01714df34eeb534d54a832faf6
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
styles.css,
|
|
14
|
-
index.html,
|
|
15
|
-
admin.html,
|
|
16
|
-
app.js,
|
|
10
|
+
authentication.html,1791355368030,8ffbb737c011e0dd2988ba7f82e0c02baa4dae29d01a8af46d7d786a3273c367
|
|
11
|
+
paid_plans.html,1791355368033,f29d10c5d5c1deb318b254e66fe1dd26def1202d52a585d1461004d35a4d3fff
|
|
12
|
+
web_cli.html,1791355368033,c5fcf04b10dc0503f2cab7b510ea72e01787938abe7d60913609017b92e742f6
|
|
13
|
+
styles.css,1791355368033,e1a4078f39f3689e117a488bd0b292968863aba88b3a11fc5704fa4e397a4625
|
|
14
|
+
index.html,1791355368033,3291145646e76c9578f6965c81f8a9770f123db1d973a72f5e2772ba20065491
|
|
15
|
+
admin.html,1791355368030,e81d88bdbe940fb31b6a0e1e98c18ca6ddd4fe3fe007239dd56121ef14e0387a
|
|
16
|
+
app.js,1791355368033,c66ee3f08bd28b8ba7e24ea27884b1e623489076430b02a9dc40ff54238a5f60
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# scout (FrontTerrain CLI v9.4.
|
|
1
|
+
# scout (FrontTerrain CLI v9.4.6)
|
|
2
2
|
|
|
3
3
|
**FrontTerrain (`scout`)** The Autonomous AI Principal Software Engineer & Codebase Co-Pilot in your terminal.
|
|
4
4
|
|
|
@@ -428,7 +428,7 @@ Inside an active `scout agent` interactive session, type any slash command to tr
|
|
|
428
428
|
|
|
429
429
|
---
|
|
430
430
|
|
|
431
|
-
## What's New in v9.4.
|
|
431
|
+
## What's New in v9.4.6
|
|
432
432
|
- **Ultra-Realistic ElevenLabs AI Voice Engine**: Integrated human-grade voice synthesis via ElevenLabs for Pro and Enterprise subscribers, bringing lifelike conversational audio feedback directly to the CLI co-pilot.
|
|
433
433
|
- **Native C# Audio Recorder with Real-Time VAD**: Standalone Win32 `waveIn` audio recording binary (`scout_audio_recorder.exe`) with RMS energy detection and 2.5s silence debounce cutoff.
|
|
434
434
|
- **Zero-Latency Groq Whisper STT**: Integrated Groq `whisper-large-v3-turbo` with specialized developer vocabulary hints to eliminate speech recognition errors.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentEngine.d.ts","sourceRoot":"","sources":["agentEngine.ts"],"names":[],"mappings":"AAMA,OAAO,EAA0C,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAM7F,OAAO,EAAE,gBAAgB,EAA4B,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,KAAK,kBAAkB,EAA6B,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAkB,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAwB,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,KAAK,mBAAmB,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AACjH,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACtH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"agentEngine.d.ts","sourceRoot":"","sources":["agentEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,6 +22,7 @@ import { AgentRuntime } from './runtime/index.js';
|
|
|
22
22
|
import { loadAuthConfig, isProOrHigher } from '../utils/auth.js';
|
|
23
23
|
import { getMCPManager } from '../mcp/index.js';
|
|
24
24
|
import { writeTelemetry } from '../utils/qrBridge.js';
|
|
25
|
+
import { compress, LEVEL_FAST } from 'codrop';
|
|
25
26
|
export { AgentRuntime, AgentWorkspace, inferExecutionIntent, resolveDesktopPath, SystemComputerController, MockComputerController };
|
|
26
27
|
const execAsync = promisify(exec);
|
|
27
28
|
export function robustSnippetReplace(origContent, target, replacement) {
|
|
@@ -581,7 +582,7 @@ export class AgentExecutionLoop {
|
|
|
581
582
|
}
|
|
582
583
|
}
|
|
583
584
|
systemPrompt() {
|
|
584
|
-
const filesList = getDirectoryFiles(this.cwd).slice(0,
|
|
585
|
+
const filesList = getDirectoryFiles(this.cwd).slice(0, 10);
|
|
585
586
|
const intentInfo = this.executionIntent ? `
|
|
586
587
|
Task Execution Intent & Constraints:
|
|
587
588
|
• Required Applications: ${this.executionIntent.requiredApplications.length > 0 ? this.executionIntent.requiredApplications.join(', ') : 'None specified'}
|
|
@@ -607,7 +608,7 @@ PLAN TIER & CAPABILITIES: DEVELOPER FREE (BASIC DEVELOPER OPS ONLY)
|
|
|
607
608
|
`;
|
|
608
609
|
const mcpRouting = getMCPManager().routeTools(this.currentGoal);
|
|
609
610
|
const mcpCapabilitiesSection = mcpRouting.capabilitiesSummary ? `\n${mcpRouting.capabilitiesSummary}\n` : '';
|
|
610
|
-
const recentSessionsMemory = getRecentSessionsSummary(
|
|
611
|
+
const recentSessionsMemory = getRecentSessionsSummary(1);
|
|
611
612
|
const sessionHistorySection = recentSessionsMemory ? `\n${recentSessionsMemory}\n` : '';
|
|
612
613
|
return `You are Scout Agent, an elite AI Principal Software Engineer & Autonomous Computer-Use Operator (developed by FrontTerrain).
|
|
613
614
|
|
|
@@ -671,7 +672,7 @@ CORE ARCHITECTURAL PRINCIPLES:
|
|
|
671
672
|
* Light: light_data.energy = 1000.0 (watts)
|
|
672
673
|
* Primitives: bpy.ops.mesh.primitive_uv_sphere_add, primitive_cylinder_add, primitive_cube_add
|
|
673
674
|
- Apply cel-shading or toon materials with vibrant anime colors matching the request (e.g. Genshin Impact aesthetic).
|
|
674
|
-
- Position camera and lighting
|
|
675
|
+
- Position camera and lighting. Immediately after your Blender script creates the 3D model (or after a single quick verification step), you MUST call task_completed with a complete description of the created 3D character and mesh hierarchy. Do NOT run unnecessary repeated polling turns.
|
|
675
676
|
|
|
676
677
|
When returning tool calls, use standard OpenAI function calling format or JSON tool call payload format:
|
|
677
678
|
\`\`\`json
|
|
@@ -860,7 +861,7 @@ When returning tool calls, use standard OpenAI function calling format or JSON t
|
|
|
860
861
|
}
|
|
861
862
|
return {
|
|
862
863
|
name: mt.originalName,
|
|
863
|
-
description: `[MCP: ${mt.serverName}] ${desc.length >
|
|
864
|
+
description: `[MCP: ${mt.serverName}] ${desc.length > 160 ? desc.slice(0, 157) + '...' : desc}`,
|
|
864
865
|
parameters: {
|
|
865
866
|
type: 'object',
|
|
866
867
|
properties: mt.inputSchema.properties || {},
|
|
@@ -871,7 +872,18 @@ When returning tool calls, use standard OpenAI function calling format or JSON t
|
|
|
871
872
|
mcpServerName: mt.serverName,
|
|
872
873
|
};
|
|
873
874
|
});
|
|
874
|
-
const
|
|
875
|
+
const goalLower = (userGoal || '').toLowerCase();
|
|
876
|
+
const needsBrowser = goalLower.includes('browser') || goalLower.includes('website') || goalLower.includes('webpage') || goalLower.includes('http') || goalLower.includes('url') || goalLower.includes('scrape') || goalLower.includes('chrome');
|
|
877
|
+
const needsComputer = goalLower.includes('computer') || goalLower.includes('desktop') || goalLower.includes('mouse') || goalLower.includes('coordinate') || goalLower.includes('drag') || goalLower.includes('double click');
|
|
878
|
+
let baseTools = this.toolRegistry.getToolsForTier(this.userTier);
|
|
879
|
+
if (mcpToolDefs.length > 0 && !needsBrowser && !needsComputer) {
|
|
880
|
+
const ESSENTIAL_BASE_TOOLS = new Set(['read_file', 'write_file', 'edit_file', 'run_command', 'list_dir', 'grep_search', 'task_completed', 'ask_user', 'speak_text', 'scratchpad', 'computer_open_app']);
|
|
881
|
+
baseTools = baseTools.filter((t) => ESSENTIAL_BASE_TOOLS.has(t.name));
|
|
882
|
+
}
|
|
883
|
+
else if (!needsBrowser) {
|
|
884
|
+
baseTools = baseTools.filter((t) => !t.name.startsWith('browser_'));
|
|
885
|
+
}
|
|
886
|
+
const activeLoopTools = [...baseTools, ...mcpToolDefs];
|
|
875
887
|
try {
|
|
876
888
|
response = await callOpenAIWithRetry(async (model) => {
|
|
877
889
|
return await openai.chat.completions.create({
|
|
@@ -890,14 +902,15 @@ When returning tool calls, use standard OpenAI function calling format or JSON t
|
|
|
890
902
|
if (errStr.includes('tool') || errStr.includes('400') || errStr.includes('not supported') || errStr.includes('reasoning')) {
|
|
891
903
|
// Model doesn't support native function calling inject tool-call formatting hint
|
|
892
904
|
// so extractJsonToolCall can parse the response as a structured tool invocation
|
|
905
|
+
const availableToolNames = activeLoopTools.map((t) => t.name).join(', ');
|
|
893
906
|
const toolHintMsg = {
|
|
894
907
|
role: 'user',
|
|
895
908
|
content: `IMPORTANT: This model does not support native function/tool calling. You MUST format your tool invocations as a JSON code block in your response like this:
|
|
896
909
|
\`\`\`json
|
|
897
910
|
{ "tool": "tool_name", "args": { ... } }
|
|
898
911
|
\`\`\`
|
|
899
|
-
Available tools:
|
|
900
|
-
You MUST output exactly ONE JSON code block per tool call. Do NOT describe what you would do in plain
|
|
912
|
+
Available tools: ${availableToolNames}
|
|
913
|
+
You MUST output exactly ONE JSON code block per tool call. Do NOT describe what you would do in plain text — output the JSON tool call directly!`,
|
|
901
914
|
};
|
|
902
915
|
const fallbackMessages = [...this.historyMessages, toolHintMsg];
|
|
903
916
|
response = await callOpenAIWithRetry(async (model) => {
|
|
@@ -964,10 +977,24 @@ You MUST output exactly ONE JSON code block per tool call. Do NOT describe what
|
|
|
964
977
|
const toolResult = await this.dispatchToolCall(fnName, args);
|
|
965
978
|
this.totalToolCalls++;
|
|
966
979
|
this.syncTelemetry('running', `scout: [step ${step}] executed tool ${fnName}`);
|
|
980
|
+
const toolResStr = String(toolResult.result || '');
|
|
981
|
+
let cappedResult = toolResStr;
|
|
982
|
+
if (toolResStr.length > 800) {
|
|
983
|
+
try {
|
|
984
|
+
const origBytes = Buffer.byteLength(toolResStr, 'utf-8');
|
|
985
|
+
const cdp = compress(Buffer.from(toolResStr, 'utf-8'), LEVEL_FAST);
|
|
986
|
+
const ratio = (origBytes / Math.max(1, cdp.length)).toFixed(1);
|
|
987
|
+
cappedResult = toolResStr.slice(0, 800) + `\n... [Codrop: ${origBytes}B compressed to ${cdp.length}B (${ratio}x ratio) for LLM context]`;
|
|
988
|
+
this.syncTelemetry('running', `scout: [codrop] compressed ${fnName} output (${ratio}x ratio)`);
|
|
989
|
+
}
|
|
990
|
+
catch {
|
|
991
|
+
cappedResult = toolResStr.slice(0, 800) + '\n... [output truncated for token efficiency]';
|
|
992
|
+
}
|
|
993
|
+
}
|
|
967
994
|
this.historyMessages.push({
|
|
968
995
|
role: 'user',
|
|
969
996
|
tool_call_id: tc.id,
|
|
970
|
-
content: `Tool Execution Result (${fnName}):\n${
|
|
997
|
+
content: `Tool Execution Result (${fnName}):\n${cappedResult}`,
|
|
971
998
|
});
|
|
972
999
|
this.handleToolConsecutiveTracking(fnName, args, step);
|
|
973
1000
|
// Automatic immediate completion for simple app actions (open/close/switch window)
|
|
@@ -1022,9 +1049,22 @@ You MUST output exactly ONE JSON code block per tool call. Do NOT describe what
|
|
|
1022
1049
|
const parsedJsonTool = this.extractJsonToolCall(textContent);
|
|
1023
1050
|
if (parsedJsonTool) {
|
|
1024
1051
|
const toolResult = await this.dispatchToolCall(parsedJsonTool.tool, parsedJsonTool.args);
|
|
1052
|
+
const jsonResStr = String(toolResult.result || '');
|
|
1053
|
+
let cappedJsonResult = jsonResStr;
|
|
1054
|
+
if (jsonResStr.length > 800) {
|
|
1055
|
+
try {
|
|
1056
|
+
const origBytes = Buffer.byteLength(jsonResStr, 'utf-8');
|
|
1057
|
+
const cdp = compress(Buffer.from(jsonResStr, 'utf-8'), LEVEL_FAST);
|
|
1058
|
+
const ratio = (origBytes / Math.max(1, cdp.length)).toFixed(1);
|
|
1059
|
+
cappedJsonResult = jsonResStr.slice(0, 800) + `\n... [Codrop: ${origBytes}B compressed to ${cdp.length}B (${ratio}x ratio) for LLM context]`;
|
|
1060
|
+
}
|
|
1061
|
+
catch {
|
|
1062
|
+
cappedJsonResult = jsonResStr.slice(0, 800) + '\n... [output truncated for token efficiency]';
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1025
1065
|
this.historyMessages.push({
|
|
1026
1066
|
role: 'user',
|
|
1027
|
-
content: `Tool Execution Result (${parsedJsonTool.tool}):\n${
|
|
1067
|
+
content: `Tool Execution Result (${parsedJsonTool.tool}):\n${cappedJsonResult}`,
|
|
1028
1068
|
});
|
|
1029
1069
|
this.handleToolConsecutiveTracking(parsedJsonTool.tool, parsedJsonTool.args, step);
|
|
1030
1070
|
// Automatic immediate completion for simple app actions (open/close/switch window)
|
|
@@ -1298,13 +1338,21 @@ You MUST output exactly ONE JSON code block per tool call. Do NOT describe what
|
|
|
1298
1338
|
}
|
|
1299
1339
|
if (action === 'write') {
|
|
1300
1340
|
fs.writeFileSync(scratchPath, content, 'utf-8');
|
|
1301
|
-
|
|
1341
|
+
try {
|
|
1342
|
+
fs.writeFileSync(path.join(ftDir, 'scratchpad.cdp'), compress(Buffer.from(content, 'utf-8'), LEVEL_FAST));
|
|
1343
|
+
}
|
|
1344
|
+
catch { }
|
|
1345
|
+
this.taskStateManager.addObservation(name, `Scratchpad updated (${content.length} chars, Codrop .cdp archived)`, true);
|
|
1302
1346
|
return { result: `Scratchpad updated successfully:\n${content}` };
|
|
1303
1347
|
}
|
|
1304
1348
|
else if (action === 'append') {
|
|
1305
1349
|
const updated = currentScratch ? `${currentScratch}\n\n---\n<!-- ${new Date().toISOString()} -->\n${content}` : content;
|
|
1306
1350
|
fs.writeFileSync(scratchPath, updated, 'utf-8');
|
|
1307
|
-
|
|
1351
|
+
try {
|
|
1352
|
+
fs.writeFileSync(path.join(ftDir, 'scratchpad.cdp'), compress(Buffer.from(updated, 'utf-8'), LEVEL_FAST));
|
|
1353
|
+
}
|
|
1354
|
+
catch { }
|
|
1355
|
+
this.taskStateManager.addObservation(name, `Appended to scratchpad (${content.length} chars, Codrop .cdp archived)`, true);
|
|
1308
1356
|
return { result: `Appended to scratchpad. Current contents:\n${updated}` };
|
|
1309
1357
|
}
|
|
1310
1358
|
else if (action === 'clear') {
|