ft-scout 9.4.4 → 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 +90 -21
- package/bin/src/engine/agentEngine.js.map +1 -1
- package/bin/src/engine/computer/computerController.d.ts.map +1 -1
- package/bin/src/engine/computer/computerController.js +35 -1
- package/bin/src/engine/computer/computerController.js.map +1 -1
- package/bin/src/engine/computer/scoutDriver.cs +20 -1
- package/bin/src/engine/computer/scout_driver.exe +0 -0
- package/bin/src/engine/llm.d.ts.map +1 -1
- package/bin/src/engine/llm.js +81 -36
- 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 +51 -16
- 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/mcp/toolRouter.d.ts.map +1 -1
- package/bin/src/mcp/toolRouter.js +27 -26
- package/bin/src/mcp/toolRouter.js.map +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
- package/scripts/build_3d_drone.js +0 -130
- package/scripts/export_and_capture.js +0 -48
- package/scripts/render_and_export_drone.js +0 -94
- package/scripts/render_front_view.js +0 -76
|
@@ -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
|
|
|
@@ -660,6 +661,18 @@ CORE ARCHITECTURAL PRINCIPLES:
|
|
|
660
661
|
- When the user goal includes an external HTTP or HTTPS URL (e.g. documentation, setup instructions, raw prompt/markdown like https://.../prompt.md), you MUST call fetch_url to retrieve the remote content on Step 1.
|
|
661
662
|
- Do NOT search local directories (list_dir, glob_search) for remote URLs!
|
|
662
663
|
- After fetching the URL content, read the instructions carefully and execute the required commands (run_command) or file creations (write_file). Complete all steps directly yourself.
|
|
664
|
+
14. 3D MODELING & BLENDER WORKFLOW:
|
|
665
|
+
When asked to generate or create a 3D model in Blender (e.g. characters, anime models, props, scenes):
|
|
666
|
+
- You have access to Blender MCP (execute_blender_code, get_scene_info, etc.).
|
|
667
|
+
- DO NOT waste steps attempting to install or configure external cloud generator addons or API keys (like Hunyuan3D or Hyper3D).
|
|
668
|
+
- Use execute_blender_code to execute Python (bpy) scripts that procedurally build and model the character (head, face, anime hair, body, clothes, cel-shaded materials, eyes, colors).
|
|
669
|
+
- BPY Syntax:
|
|
670
|
+
* Materials: mat = bpy.data.materials.new(name="MatName"); mat.use_nodes = True; bsdf = mat.node_tree.nodes.get('Principled BSDF')
|
|
671
|
+
* Color: if bsdf: bsdf.inputs['Base Color'].default_value = (r, g, b, 1.0)
|
|
672
|
+
* Light: light_data.energy = 1000.0 (watts)
|
|
673
|
+
* Primitives: bpy.ops.mesh.primitive_uv_sphere_add, primitive_cylinder_add, primitive_cube_add
|
|
674
|
+
- Apply cel-shading or toon materials with vibrant anime colors matching the request (e.g. Genshin Impact aesthetic).
|
|
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.
|
|
663
676
|
|
|
664
677
|
When returning tool calls, use standard OpenAI function calling format or JSON tool call payload format:
|
|
665
678
|
\`\`\`json
|
|
@@ -838,19 +851,39 @@ When returning tool calls, use standard OpenAI function calling format or JSON t
|
|
|
838
851
|
try {
|
|
839
852
|
let response;
|
|
840
853
|
const mcpRouting = getMCPManager().routeTools(userGoal);
|
|
841
|
-
const mcpToolDefs = mcpRouting.tools.map((mt) =>
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
+
const mcpToolDefs = mcpRouting.tools.map((mt) => {
|
|
855
|
+
let desc = mt.description;
|
|
856
|
+
if (mt.originalName === 'execute_blender_code') {
|
|
857
|
+
desc = 'Execute Python (bpy) code inside Blender. Use this to procedurally create, model, texture, color, and render 3D meshes, anime/game characters, clothing, hair, materials, cel-shading, lights, cameras, and scenes directly.';
|
|
858
|
+
}
|
|
859
|
+
else if (mt.originalName === 'generate_3d') {
|
|
860
|
+
desc = 'Cloud AI text-to-3d generator (requires external API key). If keys are not set, use execute_blender_code to model directly.';
|
|
861
|
+
}
|
|
862
|
+
return {
|
|
863
|
+
name: mt.originalName,
|
|
864
|
+
description: `[MCP: ${mt.serverName}] ${desc.length > 160 ? desc.slice(0, 157) + '...' : desc}`,
|
|
865
|
+
parameters: {
|
|
866
|
+
type: 'object',
|
|
867
|
+
properties: mt.inputSchema.properties || {},
|
|
868
|
+
required: mt.inputSchema.required || [],
|
|
869
|
+
},
|
|
870
|
+
source: 'mcp',
|
|
871
|
+
mcpServerId: mt.serverId,
|
|
872
|
+
mcpServerName: mt.serverName,
|
|
873
|
+
};
|
|
874
|
+
});
|
|
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];
|
|
854
887
|
try {
|
|
855
888
|
response = await callOpenAIWithRetry(async (model) => {
|
|
856
889
|
return await openai.chat.completions.create({
|
|
@@ -869,14 +902,15 @@ When returning tool calls, use standard OpenAI function calling format or JSON t
|
|
|
869
902
|
if (errStr.includes('tool') || errStr.includes('400') || errStr.includes('not supported') || errStr.includes('reasoning')) {
|
|
870
903
|
// Model doesn't support native function calling inject tool-call formatting hint
|
|
871
904
|
// so extractJsonToolCall can parse the response as a structured tool invocation
|
|
905
|
+
const availableToolNames = activeLoopTools.map((t) => t.name).join(', ');
|
|
872
906
|
const toolHintMsg = {
|
|
873
907
|
role: 'user',
|
|
874
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:
|
|
875
909
|
\`\`\`json
|
|
876
910
|
{ "tool": "tool_name", "args": { ... } }
|
|
877
911
|
\`\`\`
|
|
878
|
-
Available tools:
|
|
879
|
-
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!`,
|
|
880
914
|
};
|
|
881
915
|
const fallbackMessages = [...this.historyMessages, toolHintMsg];
|
|
882
916
|
response = await callOpenAIWithRetry(async (model) => {
|
|
@@ -943,10 +977,24 @@ You MUST output exactly ONE JSON code block per tool call. Do NOT describe what
|
|
|
943
977
|
const toolResult = await this.dispatchToolCall(fnName, args);
|
|
944
978
|
this.totalToolCalls++;
|
|
945
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
|
+
}
|
|
946
994
|
this.historyMessages.push({
|
|
947
995
|
role: 'user',
|
|
948
996
|
tool_call_id: tc.id,
|
|
949
|
-
content: `Tool Execution Result (${fnName}):\n${
|
|
997
|
+
content: `Tool Execution Result (${fnName}):\n${cappedResult}`,
|
|
950
998
|
});
|
|
951
999
|
this.handleToolConsecutiveTracking(fnName, args, step);
|
|
952
1000
|
// Automatic immediate completion for simple app actions (open/close/switch window)
|
|
@@ -1001,9 +1049,22 @@ You MUST output exactly ONE JSON code block per tool call. Do NOT describe what
|
|
|
1001
1049
|
const parsedJsonTool = this.extractJsonToolCall(textContent);
|
|
1002
1050
|
if (parsedJsonTool) {
|
|
1003
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
|
+
}
|
|
1004
1065
|
this.historyMessages.push({
|
|
1005
1066
|
role: 'user',
|
|
1006
|
-
content: `Tool Execution Result (${parsedJsonTool.tool}):\n${
|
|
1067
|
+
content: `Tool Execution Result (${parsedJsonTool.tool}):\n${cappedJsonResult}`,
|
|
1007
1068
|
});
|
|
1008
1069
|
this.handleToolConsecutiveTracking(parsedJsonTool.tool, parsedJsonTool.args, step);
|
|
1009
1070
|
// Automatic immediate completion for simple app actions (open/close/switch window)
|
|
@@ -1277,13 +1338,21 @@ You MUST output exactly ONE JSON code block per tool call. Do NOT describe what
|
|
|
1277
1338
|
}
|
|
1278
1339
|
if (action === 'write') {
|
|
1279
1340
|
fs.writeFileSync(scratchPath, content, 'utf-8');
|
|
1280
|
-
|
|
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);
|
|
1281
1346
|
return { result: `Scratchpad updated successfully:\n${content}` };
|
|
1282
1347
|
}
|
|
1283
1348
|
else if (action === 'append') {
|
|
1284
1349
|
const updated = currentScratch ? `${currentScratch}\n\n---\n<!-- ${new Date().toISOString()} -->\n${content}` : content;
|
|
1285
1350
|
fs.writeFileSync(scratchPath, updated, 'utf-8');
|
|
1286
|
-
|
|
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);
|
|
1287
1356
|
return { result: `Appended to scratchpad. Current contents:\n${updated}` };
|
|
1288
1357
|
}
|
|
1289
1358
|
else if (action === 'clear') {
|