@nomad-e/bluma-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/dist/main.js +542 -170
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -328,14 +328,14 @@ var init_async_command = __esm({
|
|
|
328
328
|
});
|
|
329
329
|
|
|
330
330
|
// src/main.ts
|
|
331
|
-
import
|
|
331
|
+
import React11 from "react";
|
|
332
332
|
import { render } from "ink";
|
|
333
333
|
import { EventEmitter as EventEmitter2 } from "events";
|
|
334
334
|
import { v4 as uuidv43 } from "uuid";
|
|
335
335
|
|
|
336
336
|
// src/app/ui/App.tsx
|
|
337
|
-
import { useState as
|
|
338
|
-
import { Box as
|
|
337
|
+
import { useState as useState7, useEffect as useEffect6, useRef as useRef5, useCallback as useCallback2, memo as memo11 } from "react";
|
|
338
|
+
import { Box as Box17, Text as Text16, Static } from "ink";
|
|
339
339
|
|
|
340
340
|
// src/app/ui/layout.tsx
|
|
341
341
|
import { Box, Text } from "ink";
|
|
@@ -3071,8 +3071,9 @@ async function readArtifact(args) {
|
|
|
3071
3071
|
import https from "https";
|
|
3072
3072
|
import http from "http";
|
|
3073
3073
|
var DEFAULT_SOURCES = ["reddit", "github", "stackoverflow"];
|
|
3074
|
-
var MAX_RESULTS_DEFAULT =
|
|
3075
|
-
var REQUEST_TIMEOUT =
|
|
3074
|
+
var MAX_RESULTS_DEFAULT = 5;
|
|
3075
|
+
var REQUEST_TIMEOUT = 15e3;
|
|
3076
|
+
var MAX_CONTENT_LENGTH = 4e3;
|
|
3076
3077
|
function httpGet(url, customHeaders) {
|
|
3077
3078
|
return new Promise((resolve, reject) => {
|
|
3078
3079
|
const protocol = url.startsWith("https") ? https : http;
|
|
@@ -3081,7 +3082,6 @@ function httpGet(url, customHeaders) {
|
|
|
3081
3082
|
"Accept": "application/json, text/html, */*",
|
|
3082
3083
|
"Accept-Language": "en-US,en;q=0.9",
|
|
3083
3084
|
"Accept-Encoding": "identity",
|
|
3084
|
-
// Não usar gzip para simplificar
|
|
3085
3085
|
"Cache-Control": "no-cache",
|
|
3086
3086
|
"Connection": "keep-alive",
|
|
3087
3087
|
...customHeaders
|
|
@@ -3111,10 +3111,18 @@ function httpGet(url, customHeaders) {
|
|
|
3111
3111
|
});
|
|
3112
3112
|
});
|
|
3113
3113
|
}
|
|
3114
|
+
function cleanContent(text, maxLength = MAX_CONTENT_LENGTH) {
|
|
3115
|
+
if (!text) return "";
|
|
3116
|
+
let cleaned = text.replace(/```[\s\S]*?```/g, (match) => match.substring(0, 500) + (match.length > 500 ? "\n[...code truncated...]" : "")).replace(/\n{3,}/g, "\n\n").trim();
|
|
3117
|
+
if (cleaned.length > maxLength) {
|
|
3118
|
+
cleaned = cleaned.substring(0, maxLength) + "\n\n[...content truncated...]";
|
|
3119
|
+
}
|
|
3120
|
+
return cleaned;
|
|
3121
|
+
}
|
|
3114
3122
|
async function searchReddit(query, limit) {
|
|
3115
3123
|
const results = [];
|
|
3116
3124
|
try {
|
|
3117
|
-
const subreddits = "programming+webdev+javascript+typescript+python+node+reactjs+learnprogramming";
|
|
3125
|
+
const subreddits = "programming+webdev+javascript+typescript+python+node+reactjs+learnprogramming+rust+golang+devops";
|
|
3118
3126
|
const encodedQuery = encodeURIComponent(query);
|
|
3119
3127
|
const url = `https://www.reddit.com/r/${subreddits}/search.json?q=${encodedQuery}&sort=relevance&limit=${limit}&restrict_sr=on`;
|
|
3120
3128
|
const response = await httpGet(url);
|
|
@@ -3122,12 +3130,46 @@ async function searchReddit(query, limit) {
|
|
|
3122
3130
|
if (data.data?.children) {
|
|
3123
3131
|
for (const child of data.data.children.slice(0, limit)) {
|
|
3124
3132
|
const post = child.data;
|
|
3133
|
+
let content = `# ${post.title}
|
|
3134
|
+
|
|
3135
|
+
`;
|
|
3136
|
+
content += `**Subreddit:** r/${post.subreddit} | **Score:** ${post.score} | **Comments:** ${post.num_comments}
|
|
3137
|
+
|
|
3138
|
+
`;
|
|
3139
|
+
if (post.selftext) {
|
|
3140
|
+
content += `## Post Content:
|
|
3141
|
+
${cleanContent(post.selftext, 2e3)}
|
|
3142
|
+
|
|
3143
|
+
`;
|
|
3144
|
+
}
|
|
3145
|
+
try {
|
|
3146
|
+
const commentsUrl = `https://www.reddit.com${post.permalink}.json?limit=3&depth=1`;
|
|
3147
|
+
const commentsResponse = await httpGet(commentsUrl);
|
|
3148
|
+
const commentsData = JSON.parse(commentsResponse);
|
|
3149
|
+
if (commentsData[1]?.data?.children) {
|
|
3150
|
+
content += `## Top Comments:
|
|
3151
|
+
`;
|
|
3152
|
+
for (const comment of commentsData[1].data.children.slice(0, 3)) {
|
|
3153
|
+
if (comment.data?.body) {
|
|
3154
|
+
content += `
|
|
3155
|
+
**[${comment.data.score || 0} pts]** ${cleanContent(comment.data.body, 500)}
|
|
3156
|
+
`;
|
|
3157
|
+
}
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
} catch {
|
|
3161
|
+
}
|
|
3125
3162
|
results.push({
|
|
3126
3163
|
title: post.title || "",
|
|
3127
3164
|
url: `https://reddit.com${post.permalink}`,
|
|
3128
3165
|
source: "reddit",
|
|
3129
|
-
|
|
3130
|
-
score: post.score
|
|
3166
|
+
content: cleanContent(content),
|
|
3167
|
+
score: post.score,
|
|
3168
|
+
metadata: {
|
|
3169
|
+
author: post.author,
|
|
3170
|
+
date: new Date(post.created_utc * 1e3).toISOString().split("T")[0],
|
|
3171
|
+
comments_count: post.num_comments
|
|
3172
|
+
}
|
|
3131
3173
|
});
|
|
3132
3174
|
}
|
|
3133
3175
|
}
|
|
@@ -3145,12 +3187,35 @@ async function searchGitHub(query, limit) {
|
|
|
3145
3187
|
const data = JSON.parse(response);
|
|
3146
3188
|
if (data.items) {
|
|
3147
3189
|
for (const item of data.items.slice(0, limit)) {
|
|
3190
|
+
let content = `# ${item.title}
|
|
3191
|
+
|
|
3192
|
+
`;
|
|
3193
|
+
content += `**Repo:** ${item.repository_url?.split("/").slice(-2).join("/") || "unknown"}
|
|
3194
|
+
`;
|
|
3195
|
+
content += `**State:** ${item.state} | **Comments:** ${item.comments} | **Reactions:** ${item.reactions?.total_count || 0}
|
|
3196
|
+
|
|
3197
|
+
`;
|
|
3198
|
+
if (item.body) {
|
|
3199
|
+
content += `## Issue Description:
|
|
3200
|
+
${cleanContent(item.body, 2500)}
|
|
3201
|
+
`;
|
|
3202
|
+
}
|
|
3203
|
+
if (item.labels?.length > 0) {
|
|
3204
|
+
content += `
|
|
3205
|
+
**Labels:** ${item.labels.map((l) => l.name).join(", ")}
|
|
3206
|
+
`;
|
|
3207
|
+
}
|
|
3148
3208
|
results.push({
|
|
3149
3209
|
title: item.title || "",
|
|
3150
3210
|
url: item.html_url || "",
|
|
3151
3211
|
source: "github",
|
|
3152
|
-
|
|
3153
|
-
score: item.reactions?.total_count || 0
|
|
3212
|
+
content: cleanContent(content),
|
|
3213
|
+
score: item.reactions?.total_count || 0,
|
|
3214
|
+
metadata: {
|
|
3215
|
+
author: item.user?.login,
|
|
3216
|
+
date: item.created_at?.split("T")[0],
|
|
3217
|
+
comments_count: item.comments
|
|
3218
|
+
}
|
|
3154
3219
|
});
|
|
3155
3220
|
}
|
|
3156
3221
|
}
|
|
@@ -3163,17 +3228,56 @@ async function searchStackOverflow(query, limit) {
|
|
|
3163
3228
|
const results = [];
|
|
3164
3229
|
try {
|
|
3165
3230
|
const encodedQuery = encodeURIComponent(query);
|
|
3166
|
-
const url = `https://api.stackexchange.com/2.3/search?order=desc&sort=relevance&
|
|
3231
|
+
const url = `https://api.stackexchange.com/2.3/search/advanced?order=desc&sort=relevance&q=${encodedQuery}&site=stackoverflow&pagesize=${limit}&filter=withbody`;
|
|
3167
3232
|
const response = await httpGet(url);
|
|
3168
3233
|
const data = JSON.parse(response);
|
|
3169
3234
|
if (data.items) {
|
|
3170
3235
|
for (const item of data.items.slice(0, limit)) {
|
|
3236
|
+
let content = `# ${item.title}
|
|
3237
|
+
|
|
3238
|
+
`;
|
|
3239
|
+
content += `**Score:** ${item.score} | **Answers:** ${item.answer_count} | **Views:** ${item.view_count}`;
|
|
3240
|
+
content += item.is_answered ? " | \u2705 Answered" : "";
|
|
3241
|
+
content += `
|
|
3242
|
+
|
|
3243
|
+
`;
|
|
3244
|
+
if (item.body) {
|
|
3245
|
+
const cleanBody = item.body.replace(/<code>/g, "`").replace(/<\/code>/g, "`").replace(/<pre>/g, "```\n").replace(/<\/pre>/g, "\n```").replace(/<[^>]+>/g, "").replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&").replace(/"/g, '"');
|
|
3246
|
+
content += `## Question:
|
|
3247
|
+
${cleanContent(cleanBody, 1500)}
|
|
3248
|
+
|
|
3249
|
+
`;
|
|
3250
|
+
}
|
|
3251
|
+
if (item.tags?.length > 0) {
|
|
3252
|
+
content += `**Tags:** ${item.tags.join(", ")}
|
|
3253
|
+
|
|
3254
|
+
`;
|
|
3255
|
+
}
|
|
3256
|
+
if (item.accepted_answer_id) {
|
|
3257
|
+
try {
|
|
3258
|
+
const answerUrl = `https://api.stackexchange.com/2.3/answers/${item.accepted_answer_id}?site=stackoverflow&filter=withbody`;
|
|
3259
|
+
const answerResponse = await httpGet(answerUrl);
|
|
3260
|
+
const answerData = JSON.parse(answerResponse);
|
|
3261
|
+
if (answerData.items?.[0]?.body) {
|
|
3262
|
+
const cleanAnswer = answerData.items[0].body.replace(/<code>/g, "`").replace(/<\/code>/g, "`").replace(/<pre>/g, "```\n").replace(/<\/pre>/g, "\n```").replace(/<[^>]+>/g, "").replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&").replace(/"/g, '"');
|
|
3263
|
+
content += `## \u2705 Accepted Answer (${answerData.items[0].score} pts):
|
|
3264
|
+
${cleanContent(cleanAnswer, 2e3)}
|
|
3265
|
+
`;
|
|
3266
|
+
}
|
|
3267
|
+
} catch {
|
|
3268
|
+
}
|
|
3269
|
+
}
|
|
3171
3270
|
results.push({
|
|
3172
3271
|
title: item.title || "",
|
|
3173
3272
|
url: item.link || "",
|
|
3174
3273
|
source: "stackoverflow",
|
|
3175
|
-
|
|
3176
|
-
score: item.score
|
|
3274
|
+
content: cleanContent(content),
|
|
3275
|
+
score: item.score,
|
|
3276
|
+
metadata: {
|
|
3277
|
+
author: item.owner?.display_name,
|
|
3278
|
+
date: item.creation_date ? new Date(item.creation_date * 1e3).toISOString().split("T")[0] : void 0,
|
|
3279
|
+
is_answered: item.is_answered
|
|
3280
|
+
}
|
|
3177
3281
|
});
|
|
3178
3282
|
}
|
|
3179
3283
|
}
|
|
@@ -3182,15 +3286,6 @@ async function searchStackOverflow(query, limit) {
|
|
|
3182
3286
|
}
|
|
3183
3287
|
return results;
|
|
3184
3288
|
}
|
|
3185
|
-
function getXSearchUrl(query) {
|
|
3186
|
-
const encodedQuery = encodeURIComponent(query);
|
|
3187
|
-
return {
|
|
3188
|
-
title: `Search X for: "${query}"`,
|
|
3189
|
-
url: `https://twitter.com/search?q=${encodedQuery}&src=typed_query&f=live`,
|
|
3190
|
-
source: "x",
|
|
3191
|
-
snippet: "X/Twitter requires authentication. Click the link to search manually."
|
|
3192
|
-
};
|
|
3193
|
-
}
|
|
3194
3289
|
async function searchWeb(args) {
|
|
3195
3290
|
try {
|
|
3196
3291
|
const {
|
|
@@ -3224,9 +3319,6 @@ async function searchWeb(args) {
|
|
|
3224
3319
|
case "stackoverflow":
|
|
3225
3320
|
searches.push(searchStackOverflow(query, resultsPerSource));
|
|
3226
3321
|
break;
|
|
3227
|
-
case "x":
|
|
3228
|
-
allResults.push(getXSearchUrl(query));
|
|
3229
|
-
break;
|
|
3230
3322
|
}
|
|
3231
3323
|
}
|
|
3232
3324
|
const searchResults = await Promise.all(searches);
|
|
@@ -3240,8 +3332,7 @@ async function searchWeb(args) {
|
|
|
3240
3332
|
query,
|
|
3241
3333
|
results: limitedResults,
|
|
3242
3334
|
sources_searched: sourcesSearched,
|
|
3243
|
-
total_results: limitedResults.length
|
|
3244
|
-
note: sources.includes("x") ? "X/Twitter requires manual search due to API restrictions" : void 0
|
|
3335
|
+
total_results: limitedResults.length
|
|
3245
3336
|
};
|
|
3246
3337
|
} catch (error) {
|
|
3247
3338
|
return {
|
|
@@ -3283,9 +3374,17 @@ async function loadSkill(args) {
|
|
|
3283
3374
|
message: `Skill "${skill_name}" not found. Available skills: ${availableNames}`
|
|
3284
3375
|
};
|
|
3285
3376
|
}
|
|
3377
|
+
if (globalContext.history) {
|
|
3378
|
+
globalContext.history.push({
|
|
3379
|
+
role: "user",
|
|
3380
|
+
content: `[SKILL:${skill.name}]
|
|
3381
|
+
|
|
3382
|
+
${skill.content}`
|
|
3383
|
+
});
|
|
3384
|
+
}
|
|
3286
3385
|
return {
|
|
3287
3386
|
success: true,
|
|
3288
|
-
message: `Skill "${skill_name}" loaded.`,
|
|
3387
|
+
message: `Skill "${skill_name}" loaded successfully. Follow the instructions in the skill content above.`,
|
|
3289
3388
|
skill_name: skill.name,
|
|
3290
3389
|
description: skill.description
|
|
3291
3390
|
};
|
|
@@ -3732,7 +3831,13 @@ async function doSaveSessionHistory(sessionFile, history) {
|
|
|
3732
3831
|
});
|
|
3733
3832
|
}
|
|
3734
3833
|
async function saveSessionHistory(sessionFile, history) {
|
|
3735
|
-
|
|
3834
|
+
const cleanHistory = history.filter((msg) => {
|
|
3835
|
+
if (msg.role === "user" && typeof msg.content === "string") {
|
|
3836
|
+
return !msg.content.startsWith("[SKILL:");
|
|
3837
|
+
}
|
|
3838
|
+
return true;
|
|
3839
|
+
});
|
|
3840
|
+
debouncedSave(sessionFile, cleanHistory);
|
|
3736
3841
|
}
|
|
3737
3842
|
|
|
3738
3843
|
// src/app/agent/core/prompt/prompt_builder.ts
|
|
@@ -4644,8 +4749,8 @@ var ToolCallNormalizer = class {
|
|
|
4644
4749
|
*/
|
|
4645
4750
|
static extractFromContent(content) {
|
|
4646
4751
|
const results = [];
|
|
4647
|
-
const
|
|
4648
|
-
const jsonMatches = this.extractJsonObjects(
|
|
4752
|
+
const cleanContent2 = content.replace(/```(?:json)?\s*([\s\S]*?)```/g, "$1");
|
|
4753
|
+
const jsonMatches = this.extractJsonObjects(cleanContent2);
|
|
4649
4754
|
for (const jsonStr of jsonMatches) {
|
|
4650
4755
|
try {
|
|
4651
4756
|
const parsed = JSON.parse(jsonStr);
|
|
@@ -4849,6 +4954,19 @@ var BluMaAgent = class {
|
|
|
4849
4954
|
this.eventBus.emit("backend_message", { type: "info", message: "Agent task cancelled before tool execution." });
|
|
4850
4955
|
return;
|
|
4851
4956
|
}
|
|
4957
|
+
const actionMap = {
|
|
4958
|
+
"edit_tool": "Editing",
|
|
4959
|
+
"shell_command": "Executing",
|
|
4960
|
+
"command_status": "Waiting",
|
|
4961
|
+
"ls_tool": "Reading",
|
|
4962
|
+
"read_file_lines": "Reading",
|
|
4963
|
+
"message": "Responding",
|
|
4964
|
+
"load_skill": "Loading skill",
|
|
4965
|
+
"search_web": "Searching",
|
|
4966
|
+
"todo": "Planning"
|
|
4967
|
+
};
|
|
4968
|
+
const action = actionMap[toolName] || "Processing";
|
|
4969
|
+
this.eventBus.emit("action_status", { action });
|
|
4852
4970
|
const result = await this.mcpClient.invoke(toolName, toolArgs);
|
|
4853
4971
|
let finalResult = result;
|
|
4854
4972
|
if (Array.isArray(result) && result.length > 0 && result[0].type === "text" && typeof result[0].text === "string") {
|
|
@@ -4915,81 +5033,200 @@ ${editData.error.display}`;
|
|
|
4915
5033
|
return;
|
|
4916
5034
|
}
|
|
4917
5035
|
const contextWindow = createApiContextWindow(this.history, this.maxContextTurns);
|
|
4918
|
-
const
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
});
|
|
5036
|
+
const llmService = this.llm;
|
|
5037
|
+
if (typeof llmService.chatCompletionStream === "function") {
|
|
5038
|
+
await this._handleStreamingResponse(contextWindow);
|
|
5039
|
+
} else {
|
|
5040
|
+
await this._handleNonStreamingResponse(contextWindow);
|
|
5041
|
+
}
|
|
5042
|
+
} catch (error) {
|
|
5043
|
+
const errorMessage = error instanceof Error ? error.message : "An unknown API error occurred.";
|
|
5044
|
+
this.eventBus.emit("backend_message", { type: "error", message: errorMessage });
|
|
5045
|
+
} finally {
|
|
5046
|
+
await saveSessionHistory(this.sessionFile, this.history);
|
|
5047
|
+
}
|
|
5048
|
+
}
|
|
5049
|
+
async _handleStreamingResponse(contextWindow) {
|
|
5050
|
+
const llmService = this.llm;
|
|
5051
|
+
this.eventBus.emit("action_status", { action: "Thinking" });
|
|
5052
|
+
let accumulatedContent = "";
|
|
5053
|
+
let toolCalls;
|
|
5054
|
+
let hasEmittedStart = false;
|
|
5055
|
+
let reasoningContent = "";
|
|
5056
|
+
const stream = llmService.chatCompletionStream({
|
|
5057
|
+
model: "x-ai/grok-code-fast-1",
|
|
5058
|
+
messages: contextWindow,
|
|
5059
|
+
temperature: 0.3,
|
|
5060
|
+
tools: this.mcpClient.getAvailableTools(),
|
|
5061
|
+
tool_choice: "required",
|
|
5062
|
+
parallel_tool_calls: false
|
|
5063
|
+
});
|
|
5064
|
+
for await (const chunk of stream) {
|
|
4927
5065
|
if (this.isInterrupted) {
|
|
5066
|
+
this.eventBus.emit("stream_end", {});
|
|
4928
5067
|
this.eventBus.emit("backend_message", { type: "info", message: "Agent task cancelled by user." });
|
|
4929
5068
|
return;
|
|
4930
5069
|
}
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
5070
|
+
if (chunk.reasoning) {
|
|
5071
|
+
if (!hasEmittedStart) {
|
|
5072
|
+
this.eventBus.emit("stream_start", {});
|
|
5073
|
+
hasEmittedStart = true;
|
|
5074
|
+
}
|
|
5075
|
+
reasoningContent += chunk.reasoning;
|
|
5076
|
+
this.eventBus.emit("stream_reasoning_chunk", { delta: chunk.reasoning });
|
|
5077
|
+
}
|
|
5078
|
+
if (chunk.delta) {
|
|
5079
|
+
if (!hasEmittedStart) {
|
|
5080
|
+
this.eventBus.emit("stream_start", {});
|
|
5081
|
+
hasEmittedStart = true;
|
|
5082
|
+
}
|
|
5083
|
+
accumulatedContent += chunk.delta;
|
|
5084
|
+
this.eventBus.emit("stream_chunk", { delta: chunk.delta });
|
|
5085
|
+
}
|
|
5086
|
+
if (chunk.tool_calls) {
|
|
5087
|
+
toolCalls = chunk.tool_calls;
|
|
5088
|
+
}
|
|
5089
|
+
if (chunk.finish_reason) {
|
|
5090
|
+
if (hasEmittedStart) {
|
|
5091
|
+
this.eventBus.emit("stream_end", {});
|
|
5092
|
+
}
|
|
5093
|
+
}
|
|
5094
|
+
}
|
|
5095
|
+
const message2 = {
|
|
5096
|
+
role: "assistant",
|
|
5097
|
+
content: accumulatedContent || null
|
|
5098
|
+
};
|
|
5099
|
+
if (toolCalls && toolCalls.length > 0) {
|
|
5100
|
+
message2.tool_calls = toolCalls;
|
|
5101
|
+
}
|
|
5102
|
+
const normalizedMessage = ToolCallNormalizer.normalizeAssistantMessage(message2);
|
|
5103
|
+
if (normalizedMessage.reasoning_content || normalizedMessage.reasoning) {
|
|
5104
|
+
const reasoningText = normalizedMessage.reasoning_content || normalizedMessage.reasoning;
|
|
5105
|
+
this.eventBus.emit("backend_message", {
|
|
5106
|
+
type: "reasoning",
|
|
5107
|
+
content: typeof reasoningText === "string" ? reasoningText : JSON.stringify(reasoningText)
|
|
5108
|
+
});
|
|
5109
|
+
}
|
|
5110
|
+
this.history.push(normalizedMessage);
|
|
5111
|
+
if (normalizedMessage.tool_calls && normalizedMessage.tool_calls.length > 0) {
|
|
5112
|
+
const validToolCalls = normalizedMessage.tool_calls.filter(
|
|
5113
|
+
(call) => ToolCallNormalizer.isValidToolCall(call)
|
|
5114
|
+
);
|
|
5115
|
+
if (validToolCalls.length === 0) {
|
|
4935
5116
|
this.eventBus.emit("backend_message", {
|
|
4936
|
-
type: "
|
|
4937
|
-
|
|
5117
|
+
type: "error",
|
|
5118
|
+
message: "Model returned invalid tool calls. Retrying..."
|
|
4938
5119
|
});
|
|
5120
|
+
await this._continueConversation();
|
|
5121
|
+
return;
|
|
4939
5122
|
}
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
}
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
"
|
|
4959
|
-
"load_skill"
|
|
4960
|
-
];
|
|
4961
|
-
const toolToCall = validToolCalls[0];
|
|
4962
|
-
const isSafeTool = autoApprovedTools.some((safeTool) => toolToCall.function.name.includes(safeTool));
|
|
4963
|
-
if (isSafeTool) {
|
|
4964
|
-
await this.handleToolResponse({ type: "user_decision_execute", tool_calls: validToolCalls });
|
|
5123
|
+
const autoApprovedTools = [
|
|
5124
|
+
"message",
|
|
5125
|
+
"ls_tool",
|
|
5126
|
+
"count_file_lines",
|
|
5127
|
+
"read_file_lines",
|
|
5128
|
+
"todo",
|
|
5129
|
+
"load_skill",
|
|
5130
|
+
"search_web"
|
|
5131
|
+
];
|
|
5132
|
+
const toolToCall = validToolCalls[0];
|
|
5133
|
+
const isSafeTool = autoApprovedTools.some((safeTool) => toolToCall.function.name.includes(safeTool));
|
|
5134
|
+
if (isSafeTool) {
|
|
5135
|
+
await this.handleToolResponse({ type: "user_decision_execute", tool_calls: validToolCalls });
|
|
5136
|
+
} else {
|
|
5137
|
+
const toolName = toolToCall.function.name;
|
|
5138
|
+
if (toolName === "edit_tool") {
|
|
5139
|
+
const args = JSON.parse(toolToCall.function.arguments);
|
|
5140
|
+
const previewContent = await this._generateEditPreview(args);
|
|
5141
|
+
this.eventBus.emit("backend_message", { type: "confirmation_request", tool_calls: validToolCalls, preview: previewContent });
|
|
4965
5142
|
} else {
|
|
4966
|
-
|
|
4967
|
-
if (toolName === "edit_tool") {
|
|
4968
|
-
const args = JSON.parse(toolToCall.function.arguments);
|
|
4969
|
-
const previewContent = await this._generateEditPreview(args);
|
|
4970
|
-
this.eventBus.emit("backend_message", { type: "confirmation_request", tool_calls: validToolCalls, preview: previewContent });
|
|
4971
|
-
} else {
|
|
4972
|
-
this.eventBus.emit("backend_message", { type: "confirmation_request", tool_calls: validToolCalls });
|
|
4973
|
-
}
|
|
5143
|
+
this.eventBus.emit("backend_message", { type: "confirmation_request", tool_calls: validToolCalls });
|
|
4974
5144
|
}
|
|
4975
|
-
}
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
5145
|
+
}
|
|
5146
|
+
} else if (accumulatedContent) {
|
|
5147
|
+
this.eventBus.emit("backend_message", { type: "assistant_message", content: accumulatedContent });
|
|
5148
|
+
const feedback = this.feedbackSystem.generateFeedback({
|
|
5149
|
+
event: "protocol_violation_direct_text",
|
|
5150
|
+
details: { violationContent: accumulatedContent }
|
|
5151
|
+
});
|
|
5152
|
+
this.eventBus.emit("backend_message", { type: "protocol_violation", message: feedback.message, content: accumulatedContent });
|
|
5153
|
+
this.history.push({ role: "system", content: feedback.correction });
|
|
5154
|
+
await this._continueConversation();
|
|
5155
|
+
} else {
|
|
5156
|
+
this.eventBus.emit("backend_message", { type: "info", message: "Agent is thinking... continuing reasoning cycle." });
|
|
5157
|
+
await this._continueConversation();
|
|
5158
|
+
}
|
|
5159
|
+
}
|
|
5160
|
+
async _handleNonStreamingResponse(contextWindow) {
|
|
5161
|
+
const response = await this.llm.chatCompletion({
|
|
5162
|
+
model: "x-ai/grok-code-fast-1",
|
|
5163
|
+
messages: contextWindow,
|
|
5164
|
+
temperature: 0.3,
|
|
5165
|
+
tools: this.mcpClient.getAvailableTools(),
|
|
5166
|
+
tool_choice: "required",
|
|
5167
|
+
parallel_tool_calls: false
|
|
5168
|
+
});
|
|
5169
|
+
if (this.isInterrupted) {
|
|
5170
|
+
this.eventBus.emit("backend_message", { type: "info", message: "Agent task cancelled by user." });
|
|
5171
|
+
return;
|
|
5172
|
+
}
|
|
5173
|
+
let message2 = response.choices[0].message;
|
|
5174
|
+
message2 = ToolCallNormalizer.normalizeAssistantMessage(message2);
|
|
5175
|
+
if (message2.reasoning_content || message2.reasoning) {
|
|
5176
|
+
const reasoningText = message2.reasoning_content || message2.reasoning;
|
|
5177
|
+
this.eventBus.emit("backend_message", {
|
|
5178
|
+
type: "reasoning",
|
|
5179
|
+
content: typeof reasoningText === "string" ? reasoningText : JSON.stringify(reasoningText)
|
|
5180
|
+
});
|
|
5181
|
+
}
|
|
5182
|
+
this.history.push(message2);
|
|
5183
|
+
if (message2.tool_calls && message2.tool_calls.length > 0) {
|
|
5184
|
+
const validToolCalls = message2.tool_calls.filter(
|
|
5185
|
+
(call) => ToolCallNormalizer.isValidToolCall(call)
|
|
5186
|
+
);
|
|
5187
|
+
if (validToolCalls.length === 0) {
|
|
5188
|
+
this.eventBus.emit("backend_message", {
|
|
5189
|
+
type: "error",
|
|
5190
|
+
message: "Model returned invalid tool calls. Retrying..."
|
|
4980
5191
|
});
|
|
4981
|
-
this.eventBus.emit("backend_message", { type: "protocol_violation", message: feedback.message, content: message2.content });
|
|
4982
|
-
this.history.push({ role: "system", content: feedback.correction });
|
|
4983
5192
|
await this._continueConversation();
|
|
5193
|
+
return;
|
|
5194
|
+
}
|
|
5195
|
+
const autoApprovedTools = [
|
|
5196
|
+
"message",
|
|
5197
|
+
"ls_tool",
|
|
5198
|
+
"count_file_lines",
|
|
5199
|
+
"read_file_lines",
|
|
5200
|
+
"todo",
|
|
5201
|
+
"load_skill",
|
|
5202
|
+
"search_web"
|
|
5203
|
+
];
|
|
5204
|
+
const toolToCall = validToolCalls[0];
|
|
5205
|
+
const isSafeTool = autoApprovedTools.some((safeTool) => toolToCall.function.name.includes(safeTool));
|
|
5206
|
+
if (isSafeTool) {
|
|
5207
|
+
await this.handleToolResponse({ type: "user_decision_execute", tool_calls: validToolCalls });
|
|
4984
5208
|
} else {
|
|
4985
|
-
|
|
4986
|
-
|
|
5209
|
+
const toolName = toolToCall.function.name;
|
|
5210
|
+
if (toolName === "edit_tool") {
|
|
5211
|
+
const args = JSON.parse(toolToCall.function.arguments);
|
|
5212
|
+
const previewContent = await this._generateEditPreview(args);
|
|
5213
|
+
this.eventBus.emit("backend_message", { type: "confirmation_request", tool_calls: validToolCalls, preview: previewContent });
|
|
5214
|
+
} else {
|
|
5215
|
+
this.eventBus.emit("backend_message", { type: "confirmation_request", tool_calls: validToolCalls });
|
|
5216
|
+
}
|
|
4987
5217
|
}
|
|
4988
|
-
}
|
|
4989
|
-
|
|
4990
|
-
this.
|
|
4991
|
-
|
|
4992
|
-
|
|
5218
|
+
} else if (message2.content) {
|
|
5219
|
+
this.eventBus.emit("backend_message", { type: "assistant_message", content: message2.content });
|
|
5220
|
+
const feedback = this.feedbackSystem.generateFeedback({
|
|
5221
|
+
event: "protocol_violation_direct_text",
|
|
5222
|
+
details: { violationContent: message2.content }
|
|
5223
|
+
});
|
|
5224
|
+
this.eventBus.emit("backend_message", { type: "protocol_violation", message: feedback.message, content: message2.content });
|
|
5225
|
+
this.history.push({ role: "system", content: feedback.correction });
|
|
5226
|
+
await this._continueConversation();
|
|
5227
|
+
} else {
|
|
5228
|
+
this.eventBus.emit("backend_message", { type: "info", message: "Agent is thinking... continuing reasoning cycle." });
|
|
5229
|
+
await this._continueConversation();
|
|
4993
5230
|
}
|
|
4994
5231
|
}
|
|
4995
5232
|
};
|
|
@@ -5006,6 +5243,9 @@ var LLMService = class {
|
|
|
5006
5243
|
});
|
|
5007
5244
|
this.defaultModel = config2.model || "";
|
|
5008
5245
|
}
|
|
5246
|
+
/**
|
|
5247
|
+
* Chamada tradicional (não-streaming) - retorna resposta completa
|
|
5248
|
+
*/
|
|
5009
5249
|
async chatCompletion(params) {
|
|
5010
5250
|
const resp = await this.client.chat.completions.create({
|
|
5011
5251
|
model: params.model || this.defaultModel,
|
|
@@ -5018,6 +5258,64 @@ var LLMService = class {
|
|
|
5018
5258
|
});
|
|
5019
5259
|
return resp;
|
|
5020
5260
|
}
|
|
5261
|
+
/**
|
|
5262
|
+
* Chamada com streaming - retorna chunks em tempo real
|
|
5263
|
+
*
|
|
5264
|
+
* Uso:
|
|
5265
|
+
* ```
|
|
5266
|
+
* for await (const chunk of llm.chatCompletionStream(params)) {
|
|
5267
|
+
* process.stdout.write(chunk.delta);
|
|
5268
|
+
* }
|
|
5269
|
+
* ```
|
|
5270
|
+
*/
|
|
5271
|
+
async *chatCompletionStream(params) {
|
|
5272
|
+
const stream = await this.client.chat.completions.create({
|
|
5273
|
+
model: params.model || this.defaultModel,
|
|
5274
|
+
messages: params.messages,
|
|
5275
|
+
tools: params.tools,
|
|
5276
|
+
tool_choice: params.tool_choice,
|
|
5277
|
+
parallel_tool_calls: params.parallel_tool_calls,
|
|
5278
|
+
temperature: params.temperature,
|
|
5279
|
+
max_tokens: params.max_tokens,
|
|
5280
|
+
stream: true
|
|
5281
|
+
});
|
|
5282
|
+
const toolCallsAccumulator = /* @__PURE__ */ new Map();
|
|
5283
|
+
for await (const chunk of stream) {
|
|
5284
|
+
const choice = chunk.choices[0];
|
|
5285
|
+
if (!choice) continue;
|
|
5286
|
+
const delta = choice.delta;
|
|
5287
|
+
if (delta?.tool_calls) {
|
|
5288
|
+
for (const tc of delta.tool_calls) {
|
|
5289
|
+
const idx = tc.index;
|
|
5290
|
+
if (!toolCallsAccumulator.has(idx)) {
|
|
5291
|
+
toolCallsAccumulator.set(idx, {
|
|
5292
|
+
id: tc.id || "",
|
|
5293
|
+
type: tc.type || "function",
|
|
5294
|
+
function: { name: "", arguments: "" }
|
|
5295
|
+
});
|
|
5296
|
+
}
|
|
5297
|
+
const acc = toolCallsAccumulator.get(idx);
|
|
5298
|
+
if (tc.id) acc.id = tc.id;
|
|
5299
|
+
if (tc.function?.name) acc.function.name = tc.function.name;
|
|
5300
|
+
if (tc.function?.arguments) acc.function.arguments += tc.function.arguments;
|
|
5301
|
+
}
|
|
5302
|
+
}
|
|
5303
|
+
const reasoning = delta?.reasoning_content || delta?.reasoning || "";
|
|
5304
|
+
yield {
|
|
5305
|
+
delta: delta?.content || "",
|
|
5306
|
+
reasoning,
|
|
5307
|
+
tool_calls: choice.finish_reason === "tool_calls" ? Array.from(toolCallsAccumulator.values()) : void 0,
|
|
5308
|
+
finish_reason: choice.finish_reason
|
|
5309
|
+
};
|
|
5310
|
+
}
|
|
5311
|
+
if (toolCallsAccumulator.size > 0) {
|
|
5312
|
+
yield {
|
|
5313
|
+
delta: "",
|
|
5314
|
+
tool_calls: Array.from(toolCallsAccumulator.values()),
|
|
5315
|
+
finish_reason: "tool_calls"
|
|
5316
|
+
};
|
|
5317
|
+
}
|
|
5318
|
+
}
|
|
5021
5319
|
/**
|
|
5022
5320
|
* Retorna o modelo padrão configurado
|
|
5023
5321
|
*/
|
|
@@ -5599,41 +5897,52 @@ var Agent = class {
|
|
|
5599
5897
|
import { useState as useState4, useEffect as useEffect4, memo as memo5 } from "react";
|
|
5600
5898
|
import { Box as Box7, Text as Text7 } from "ink";
|
|
5601
5899
|
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
5602
|
-
var WorkingTimerComponent = ({ taskName, taskStatus }) => {
|
|
5603
|
-
const [
|
|
5604
|
-
const [
|
|
5900
|
+
var WorkingTimerComponent = ({ eventBus: eventBus2, taskName, taskStatus }) => {
|
|
5901
|
+
const [currentAction, setCurrentAction] = useState4("Thinking...");
|
|
5902
|
+
const [shinePosition, setShinePosition] = useState4(0);
|
|
5903
|
+
const [dots, setDots] = useState4("");
|
|
5605
5904
|
useEffect4(() => {
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5905
|
+
if (!eventBus2) return;
|
|
5906
|
+
const handleActionStatus = (data) => {
|
|
5907
|
+
if (data.action) {
|
|
5908
|
+
setCurrentAction(data.action);
|
|
5909
|
+
}
|
|
5910
|
+
};
|
|
5911
|
+
eventBus2.on("action_status", handleActionStatus);
|
|
5912
|
+
return () => {
|
|
5913
|
+
eventBus2.off("action_status", handleActionStatus);
|
|
5914
|
+
};
|
|
5915
|
+
}, [eventBus2]);
|
|
5916
|
+
useEffect4(() => {
|
|
5917
|
+
const shineTimer = setInterval(() => {
|
|
5918
|
+
setShinePosition((prev) => (prev + 1) % 30);
|
|
5919
|
+
}, 75);
|
|
5920
|
+
return () => clearInterval(shineTimer);
|
|
5610
5921
|
}, []);
|
|
5611
5922
|
useEffect4(() => {
|
|
5612
|
-
const
|
|
5613
|
-
|
|
5614
|
-
},
|
|
5615
|
-
return () => clearInterval(
|
|
5923
|
+
const dotsTimer = setInterval(() => {
|
|
5924
|
+
setDots((prev) => prev.length >= 3 ? "" : prev + ".");
|
|
5925
|
+
}, 500);
|
|
5926
|
+
return () => clearInterval(dotsTimer);
|
|
5616
5927
|
}, []);
|
|
5617
|
-
const
|
|
5618
|
-
const
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5928
|
+
const displayAction = taskStatus || currentAction;
|
|
5929
|
+
const renderShineText = (text) => {
|
|
5930
|
+
const chars = text.split("");
|
|
5931
|
+
const textLen = text.length;
|
|
5932
|
+
const shineIdx = shinePosition % (textLen + 6);
|
|
5933
|
+
return chars.map((char, i) => {
|
|
5934
|
+
const distance = Math.abs(i - shineIdx);
|
|
5935
|
+
if (distance <= 1) {
|
|
5936
|
+
return /* @__PURE__ */ jsx7(Text7, { color: "white", dimColor: true, children: char }, i);
|
|
5937
|
+
} else {
|
|
5938
|
+
return /* @__PURE__ */ jsx7(Text7, { color: "gray", dimColor: true, children: char }, i);
|
|
5939
|
+
}
|
|
5940
|
+
});
|
|
5622
5941
|
};
|
|
5623
5942
|
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", paddingX: 1, children: [
|
|
5624
|
-
/* @__PURE__ */
|
|
5625
|
-
/* @__PURE__ */ jsx7(Text7, { color: "cyan", children: spinner }),
|
|
5626
|
-
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
5627
|
-
" ",
|
|
5628
|
-
taskStatus || "thinking"
|
|
5629
|
-
] }),
|
|
5630
|
-
/* @__PURE__ */ jsxs7(Text7, { color: "gray", children: [
|
|
5631
|
-
" ",
|
|
5632
|
-
formatTime(seconds)
|
|
5633
|
-
] })
|
|
5634
|
-
] }),
|
|
5943
|
+
/* @__PURE__ */ jsx7(Box7, { children: renderShineText(displayAction) }),
|
|
5635
5944
|
taskName && /* @__PURE__ */ jsx7(Box7, { paddingLeft: 2, children: /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
5636
|
-
"
|
|
5945
|
+
"\u203A ",
|
|
5637
5946
|
taskName
|
|
5638
5947
|
] }) })
|
|
5639
5948
|
] });
|
|
@@ -6566,14 +6875,60 @@ var ReasoningDisplayComponent = ({
|
|
|
6566
6875
|
const lines = reasoning.split("\n");
|
|
6567
6876
|
const displayText = isExpanded ? reasoning : lines.slice(0, maxLines).join("\n") + (lines.length > maxLines ? "..." : "");
|
|
6568
6877
|
return /* @__PURE__ */ jsxs14(Box15, { flexDirection: "column", paddingX: 1, marginBottom: 1, marginTop: 1, children: [
|
|
6569
|
-
/* @__PURE__ */ jsx15(Box15, {
|
|
6878
|
+
/* @__PURE__ */ jsx15(Box15, {}),
|
|
6570
6879
|
/* @__PURE__ */ jsx15(Box15, { paddingLeft: 2, flexDirection: "column", children: displayText.split("\n").map((line, i) => /* @__PURE__ */ jsx15(Text14, { color: "gray", dimColor: true, children: line }, i)) })
|
|
6571
6880
|
] });
|
|
6572
6881
|
};
|
|
6573
6882
|
var ReasoningDisplay = memo9(ReasoningDisplayComponent);
|
|
6574
6883
|
|
|
6884
|
+
// src/app/ui/components/StreamingText.tsx
|
|
6885
|
+
import { useState as useState6, useEffect as useEffect5, useRef as useRef4, memo as memo10 } from "react";
|
|
6886
|
+
import { Box as Box16, Text as Text15 } from "ink";
|
|
6887
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
6888
|
+
var StreamingTextComponent = ({ eventBus: eventBus2, onReasoningComplete }) => {
|
|
6889
|
+
const [reasoning, setReasoning] = useState6("");
|
|
6890
|
+
const [isStreaming, setIsStreaming] = useState6(false);
|
|
6891
|
+
const reasoningRef = useRef4("");
|
|
6892
|
+
useEffect5(() => {
|
|
6893
|
+
const handleStart = () => {
|
|
6894
|
+
setReasoning("");
|
|
6895
|
+
reasoningRef.current = "";
|
|
6896
|
+
setIsStreaming(true);
|
|
6897
|
+
};
|
|
6898
|
+
const handleReasoningChunk = (data) => {
|
|
6899
|
+
if (data.delta) {
|
|
6900
|
+
reasoningRef.current += data.delta;
|
|
6901
|
+
setReasoning(reasoningRef.current);
|
|
6902
|
+
}
|
|
6903
|
+
};
|
|
6904
|
+
const handleEnd = () => {
|
|
6905
|
+
setIsStreaming(false);
|
|
6906
|
+
const finalReasoning = reasoningRef.current;
|
|
6907
|
+
if (finalReasoning && onReasoningComplete) {
|
|
6908
|
+
onReasoningComplete(finalReasoning);
|
|
6909
|
+
}
|
|
6910
|
+
setReasoning("");
|
|
6911
|
+
reasoningRef.current = "";
|
|
6912
|
+
};
|
|
6913
|
+
eventBus2.on("stream_start", handleStart);
|
|
6914
|
+
eventBus2.on("stream_reasoning_chunk", handleReasoningChunk);
|
|
6915
|
+
eventBus2.on("stream_end", handleEnd);
|
|
6916
|
+
return () => {
|
|
6917
|
+
eventBus2.off("stream_start", handleStart);
|
|
6918
|
+
eventBus2.off("stream_reasoning_chunk", handleReasoningChunk);
|
|
6919
|
+
eventBus2.off("stream_end", handleEnd);
|
|
6920
|
+
};
|
|
6921
|
+
}, [eventBus2, onReasoningComplete]);
|
|
6922
|
+
if (!isStreaming || !reasoning) {
|
|
6923
|
+
return null;
|
|
6924
|
+
}
|
|
6925
|
+
const lines = reasoning.split("\n");
|
|
6926
|
+
return /* @__PURE__ */ jsx16(Box16, { flexDirection: "column", paddingX: 1, marginBottom: 1, marginTop: 1, children: /* @__PURE__ */ jsx16(Box16, { paddingLeft: 2, flexDirection: "column", children: lines.map((line, i) => /* @__PURE__ */ jsx16(Text15, { color: "gray", dimColor: true, children: line }, i)) }) });
|
|
6927
|
+
};
|
|
6928
|
+
var StreamingText = memo10(StreamingTextComponent);
|
|
6929
|
+
|
|
6575
6930
|
// src/app/ui/App.tsx
|
|
6576
|
-
import { jsx as
|
|
6931
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
6577
6932
|
var SAFE_AUTO_APPROVE_TOOLS = [
|
|
6578
6933
|
// Comunicação/UI
|
|
6579
6934
|
"message",
|
|
@@ -6591,28 +6946,28 @@ var SAFE_AUTO_APPROVE_TOOLS = [
|
|
|
6591
6946
|
"command_status"
|
|
6592
6947
|
];
|
|
6593
6948
|
var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
6594
|
-
const agentInstance =
|
|
6595
|
-
const [history, setHistory] =
|
|
6596
|
-
const [statusMessage, setStatusMessage] =
|
|
6949
|
+
const agentInstance = useRef5(null);
|
|
6950
|
+
const [history, setHistory] = useState7([]);
|
|
6951
|
+
const [statusMessage, setStatusMessage] = useState7(
|
|
6597
6952
|
"Initializing agent..."
|
|
6598
6953
|
);
|
|
6599
|
-
const [toolsCount, setToolsCount] =
|
|
6600
|
-
const [mcpStatus, setMcpStatus] =
|
|
6954
|
+
const [toolsCount, setToolsCount] = useState7(null);
|
|
6955
|
+
const [mcpStatus, setMcpStatus] = useState7(
|
|
6601
6956
|
"connecting"
|
|
6602
6957
|
);
|
|
6603
|
-
const [isProcessing, setIsProcessing] =
|
|
6604
|
-
const [pendingConfirmation, setPendingConfirmation] =
|
|
6958
|
+
const [isProcessing, setIsProcessing] = useState7(true);
|
|
6959
|
+
const [pendingConfirmation, setPendingConfirmation] = useState7(
|
|
6605
6960
|
null
|
|
6606
6961
|
);
|
|
6607
|
-
const [confirmationPreview, setConfirmationPreview] =
|
|
6962
|
+
const [confirmationPreview, setConfirmationPreview] = useState7(
|
|
6608
6963
|
null
|
|
6609
6964
|
);
|
|
6610
|
-
const [isInitAgentActive, setIsInitAgentActive] =
|
|
6611
|
-
const alwaysAcceptList =
|
|
6965
|
+
const [isInitAgentActive, setIsInitAgentActive] = useState7(false);
|
|
6966
|
+
const alwaysAcceptList = useRef5([]);
|
|
6612
6967
|
const workdir = process.cwd();
|
|
6613
|
-
const updateCheckRan =
|
|
6614
|
-
const sessionStartTime =
|
|
6615
|
-
const [toolCallCount, setToolCallCount] =
|
|
6968
|
+
const updateCheckRan = useRef5(false);
|
|
6969
|
+
const sessionStartTime = useRef5(Date.now());
|
|
6970
|
+
const [toolCallCount, setToolCallCount] = useState7(0);
|
|
6616
6971
|
const handleInterrupt = useCallback2(() => {
|
|
6617
6972
|
if (!isProcessing) return;
|
|
6618
6973
|
eventBus2.emit("user_interrupt");
|
|
@@ -6621,7 +6976,7 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
6621
6976
|
...prev,
|
|
6622
6977
|
{
|
|
6623
6978
|
id: prev.length,
|
|
6624
|
-
component: /* @__PURE__ */
|
|
6979
|
+
component: /* @__PURE__ */ jsx17(Text16, { color: "yellow", children: "-- Task cancelled by dev. --" })
|
|
6625
6980
|
}
|
|
6626
6981
|
]);
|
|
6627
6982
|
}, [isProcessing, eventBus2]);
|
|
@@ -6645,11 +7000,11 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
6645
7000
|
...prev,
|
|
6646
7001
|
{
|
|
6647
7002
|
id: prev.length,
|
|
6648
|
-
component: /* @__PURE__ */
|
|
7003
|
+
component: /* @__PURE__ */ jsx17(Box17, { marginBottom: 1, children: /* @__PURE__ */ jsx17(Text16, { color: "white", dimColor: true, children: text }) })
|
|
6649
7004
|
},
|
|
6650
7005
|
{
|
|
6651
7006
|
id: prev.length + 1,
|
|
6652
|
-
component: /* @__PURE__ */
|
|
7007
|
+
component: /* @__PURE__ */ jsx17(
|
|
6653
7008
|
SlashCommands_default,
|
|
6654
7009
|
{
|
|
6655
7010
|
input: text,
|
|
@@ -6671,9 +7026,9 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
6671
7026
|
...prev,
|
|
6672
7027
|
{
|
|
6673
7028
|
id: prev.length,
|
|
6674
|
-
component: /* @__PURE__ */ jsxs15(
|
|
6675
|
-
/* @__PURE__ */
|
|
6676
|
-
/* @__PURE__ */
|
|
7029
|
+
component: /* @__PURE__ */ jsxs15(Box17, { marginBottom: 1, children: [
|
|
7030
|
+
/* @__PURE__ */ jsx17(Text16, { color: "white", bold: true, children: "$ " }),
|
|
7031
|
+
/* @__PURE__ */ jsx17(Text16, { color: "white", children: command })
|
|
6677
7032
|
] })
|
|
6678
7033
|
}
|
|
6679
7034
|
]);
|
|
@@ -6692,7 +7047,7 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
6692
7047
|
...prev,
|
|
6693
7048
|
{
|
|
6694
7049
|
id: prev.length,
|
|
6695
|
-
component: /* @__PURE__ */ jsxs15(
|
|
7050
|
+
component: /* @__PURE__ */ jsxs15(Text16, { color: "red", children: [
|
|
6696
7051
|
"Failed to execute: ",
|
|
6697
7052
|
result.error || result.message
|
|
6698
7053
|
] })
|
|
@@ -6705,7 +7060,7 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
6705
7060
|
...prev,
|
|
6706
7061
|
{
|
|
6707
7062
|
id: prev.length,
|
|
6708
|
-
component: /* @__PURE__ */ jsxs15(
|
|
7063
|
+
component: /* @__PURE__ */ jsxs15(Text16, { color: "red", children: [
|
|
6709
7064
|
"Error: ",
|
|
6710
7065
|
err.message
|
|
6711
7066
|
] })
|
|
@@ -6724,8 +7079,8 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
6724
7079
|
id: prev.length,
|
|
6725
7080
|
component: (
|
|
6726
7081
|
// Uma única Box para o espaçamento
|
|
6727
|
-
/* @__PURE__ */
|
|
6728
|
-
/* @__PURE__ */ jsxs15(
|
|
7082
|
+
/* @__PURE__ */ jsx17(Box17, { marginBottom: 1, children: /* @__PURE__ */ jsxs15(Text16, { color: "white", dimColor: true, children: [
|
|
7083
|
+
/* @__PURE__ */ jsxs15(Text16, { color: "white", children: [
|
|
6729
7084
|
">",
|
|
6730
7085
|
" "
|
|
6731
7086
|
] }),
|
|
@@ -6759,8 +7114,8 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
6759
7114
|
},
|
|
6760
7115
|
[]
|
|
6761
7116
|
);
|
|
6762
|
-
|
|
6763
|
-
setHistory([{ id: 0, component: /* @__PURE__ */
|
|
7117
|
+
useEffect6(() => {
|
|
7118
|
+
setHistory([{ id: 0, component: /* @__PURE__ */ jsx17(Header, { sessionId: sessionId2, workdir }) }]);
|
|
6764
7119
|
const initializeAgent = async () => {
|
|
6765
7120
|
try {
|
|
6766
7121
|
agentInstance.current = new Agent(sessionId2, eventBus2);
|
|
@@ -6826,7 +7181,7 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
6826
7181
|
...prev,
|
|
6827
7182
|
{
|
|
6828
7183
|
id: prev.length,
|
|
6829
|
-
component: /* @__PURE__ */
|
|
7184
|
+
component: /* @__PURE__ */ jsx17(UpdateNotice_default, { message: msg })
|
|
6830
7185
|
}
|
|
6831
7186
|
]);
|
|
6832
7187
|
}
|
|
@@ -6840,10 +7195,10 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
6840
7195
|
}
|
|
6841
7196
|
let newComponent = null;
|
|
6842
7197
|
if (parsed.type === "debug") {
|
|
6843
|
-
newComponent = /* @__PURE__ */
|
|
7198
|
+
newComponent = /* @__PURE__ */ jsx17(Text16, { color: "gray", children: parsed.message });
|
|
6844
7199
|
} else if (parsed.type === "protocol_violation") {
|
|
6845
7200
|
newComponent = /* @__PURE__ */ jsxs15(
|
|
6846
|
-
|
|
7201
|
+
Box17,
|
|
6847
7202
|
{
|
|
6848
7203
|
borderStyle: "round",
|
|
6849
7204
|
borderColor: "yellow",
|
|
@@ -6851,14 +7206,14 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
6851
7206
|
marginBottom: 1,
|
|
6852
7207
|
paddingX: 1,
|
|
6853
7208
|
children: [
|
|
6854
|
-
/* @__PURE__ */
|
|
6855
|
-
/* @__PURE__ */
|
|
6856
|
-
/* @__PURE__ */
|
|
7209
|
+
/* @__PURE__ */ jsx17(Text16, { color: "yellow", bold: true, children: "Protocol Violation" }),
|
|
7210
|
+
/* @__PURE__ */ jsx17(Text16, { color: "gray", children: parsed.content }),
|
|
7211
|
+
/* @__PURE__ */ jsx17(Text16, { color: "yellow", children: parsed.message })
|
|
6857
7212
|
]
|
|
6858
7213
|
}
|
|
6859
7214
|
);
|
|
6860
7215
|
} else if (parsed.type === "error") {
|
|
6861
|
-
newComponent = /* @__PURE__ */
|
|
7216
|
+
newComponent = /* @__PURE__ */ jsx17(
|
|
6862
7217
|
ErrorMessage_default,
|
|
6863
7218
|
{
|
|
6864
7219
|
message: parsed.message,
|
|
@@ -6868,7 +7223,7 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
6868
7223
|
);
|
|
6869
7224
|
} else if (parsed.type === "tool_call") {
|
|
6870
7225
|
const nextId2 = history.length;
|
|
6871
|
-
newComponent = /* @__PURE__ */
|
|
7226
|
+
newComponent = /* @__PURE__ */ jsx17(
|
|
6872
7227
|
ToolCallDisplay,
|
|
6873
7228
|
{
|
|
6874
7229
|
toolName: parsed.tool_name,
|
|
@@ -6877,7 +7232,7 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
6877
7232
|
}
|
|
6878
7233
|
);
|
|
6879
7234
|
} else if (parsed.type === "tool_result") {
|
|
6880
|
-
newComponent = /* @__PURE__ */
|
|
7235
|
+
newComponent = /* @__PURE__ */ jsx17(
|
|
6881
7236
|
ToolResultDisplay,
|
|
6882
7237
|
{
|
|
6883
7238
|
toolName: parsed.tool_name,
|
|
@@ -6885,17 +7240,17 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
6885
7240
|
}
|
|
6886
7241
|
);
|
|
6887
7242
|
} else if (parsed.type === "user_overlay") {
|
|
6888
|
-
newComponent = /* @__PURE__ */
|
|
6889
|
-
/* @__PURE__ */ jsxs15(
|
|
7243
|
+
newComponent = /* @__PURE__ */ jsx17(Box17, { marginBottom: 1, children: /* @__PURE__ */ jsxs15(Text16, { color: "gray", children: [
|
|
7244
|
+
/* @__PURE__ */ jsxs15(Text16, { color: "magenta", children: [
|
|
6890
7245
|
">",
|
|
6891
7246
|
" "
|
|
6892
7247
|
] }),
|
|
6893
7248
|
parsed.payload
|
|
6894
7249
|
] }) });
|
|
6895
7250
|
} else if (parsed.type === "reasoning") {
|
|
6896
|
-
newComponent = /* @__PURE__ */
|
|
7251
|
+
newComponent = /* @__PURE__ */ jsx17(ReasoningDisplay, { reasoning: parsed.content });
|
|
6897
7252
|
} else if (parsed.type === "log") {
|
|
6898
|
-
newComponent = /* @__PURE__ */ jsxs15(
|
|
7253
|
+
newComponent = /* @__PURE__ */ jsxs15(Text16, { color: "gray", children: [
|
|
6899
7254
|
"\u2139\uFE0F ",
|
|
6900
7255
|
parsed.message,
|
|
6901
7256
|
parsed.payload ? `: ${parsed.payload}` : ""
|
|
@@ -6928,7 +7283,7 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
6928
7283
|
return;
|
|
6929
7284
|
}
|
|
6930
7285
|
if (pendingConfirmation) {
|
|
6931
|
-
return /* @__PURE__ */
|
|
7286
|
+
return /* @__PURE__ */ jsx17(
|
|
6932
7287
|
ConfirmationPrompt,
|
|
6933
7288
|
{
|
|
6934
7289
|
toolCalls: pendingConfirmation,
|
|
@@ -6940,9 +7295,9 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
6940
7295
|
}
|
|
6941
7296
|
);
|
|
6942
7297
|
}
|
|
6943
|
-
return /* @__PURE__ */ jsxs15(
|
|
6944
|
-
isProcessing && !pendingConfirmation && /* @__PURE__ */
|
|
6945
|
-
/* @__PURE__ */
|
|
7298
|
+
return /* @__PURE__ */ jsxs15(Box17, { flexDirection: "column", children: [
|
|
7299
|
+
isProcessing && !pendingConfirmation && /* @__PURE__ */ jsx17(WorkingTimer, { eventBus: eventBus2 }),
|
|
7300
|
+
/* @__PURE__ */ jsx17(
|
|
6946
7301
|
InputPrompt,
|
|
6947
7302
|
{
|
|
6948
7303
|
onSubmit: handleSubmit,
|
|
@@ -6953,12 +7308,29 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
6953
7308
|
)
|
|
6954
7309
|
] });
|
|
6955
7310
|
};
|
|
6956
|
-
return /* @__PURE__ */ jsxs15(
|
|
6957
|
-
/* @__PURE__ */
|
|
7311
|
+
return /* @__PURE__ */ jsxs15(Box17, { flexDirection: "column", children: [
|
|
7312
|
+
/* @__PURE__ */ jsx17(Static, { items: history, children: (item) => /* @__PURE__ */ jsx17(Box17, { children: item.component }, item.id) }),
|
|
7313
|
+
/* @__PURE__ */ jsx17(
|
|
7314
|
+
StreamingText,
|
|
7315
|
+
{
|
|
7316
|
+
eventBus: eventBus2,
|
|
7317
|
+
onReasoningComplete: (reasoning) => {
|
|
7318
|
+
if (reasoning) {
|
|
7319
|
+
setHistory((prev) => [
|
|
7320
|
+
...prev,
|
|
7321
|
+
{
|
|
7322
|
+
id: prev.length,
|
|
7323
|
+
component: /* @__PURE__ */ jsx17(ReasoningDisplay, { reasoning })
|
|
7324
|
+
}
|
|
7325
|
+
]);
|
|
7326
|
+
}
|
|
7327
|
+
}
|
|
7328
|
+
}
|
|
7329
|
+
),
|
|
6958
7330
|
renderInteractiveComponent()
|
|
6959
7331
|
] });
|
|
6960
7332
|
};
|
|
6961
|
-
var App =
|
|
7333
|
+
var App = memo11(AppComponent);
|
|
6962
7334
|
var App_default = App;
|
|
6963
7335
|
|
|
6964
7336
|
// src/app/ui/utils/terminalTitle.ts
|
|
@@ -7025,4 +7397,4 @@ var props = {
|
|
|
7025
7397
|
eventBus,
|
|
7026
7398
|
sessionId
|
|
7027
7399
|
};
|
|
7028
|
-
render(
|
|
7400
|
+
render(React11.createElement(App_default, props));
|