@hasna/oldpal 0.1.6 → 0.1.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/dist/index.js +404 -22
- package/dist/index.js.map +10 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -29187,6 +29187,194 @@ class FilesystemTools {
|
|
|
29187
29187
|
};
|
|
29188
29188
|
}
|
|
29189
29189
|
|
|
29190
|
+
// packages/core/src/tools/web.ts
|
|
29191
|
+
class WebFetchTool {
|
|
29192
|
+
static tool = {
|
|
29193
|
+
name: "web_fetch",
|
|
29194
|
+
description: "Fetch content from a URL and return the text content. Useful for reading web pages, documentation, API responses, etc.",
|
|
29195
|
+
parameters: {
|
|
29196
|
+
type: "object",
|
|
29197
|
+
properties: {
|
|
29198
|
+
url: {
|
|
29199
|
+
type: "string",
|
|
29200
|
+
description: "The URL to fetch content from"
|
|
29201
|
+
},
|
|
29202
|
+
extract_type: {
|
|
29203
|
+
type: "string",
|
|
29204
|
+
description: 'What to extract: "text" for readable text, "html" for raw HTML, "json" for JSON response',
|
|
29205
|
+
enum: ["text", "html", "json"],
|
|
29206
|
+
default: "text"
|
|
29207
|
+
},
|
|
29208
|
+
timeout: {
|
|
29209
|
+
type: "number",
|
|
29210
|
+
description: "Timeout in milliseconds (default: 30000)"
|
|
29211
|
+
}
|
|
29212
|
+
},
|
|
29213
|
+
required: ["url"]
|
|
29214
|
+
}
|
|
29215
|
+
};
|
|
29216
|
+
static executor = async (input) => {
|
|
29217
|
+
const url = input.url;
|
|
29218
|
+
const extractType = input.extract_type || "text";
|
|
29219
|
+
const timeout = input.timeout || 30000;
|
|
29220
|
+
try {
|
|
29221
|
+
const parsedUrl = new URL(url);
|
|
29222
|
+
const hostname = parsedUrl.hostname;
|
|
29223
|
+
if (hostname === "localhost" || hostname === "127.0.0.1" || hostname.startsWith("192.168.") || hostname.startsWith("10.") || hostname.startsWith("172.")) {
|
|
29224
|
+
return "Error: Cannot fetch from local/private network addresses for security reasons";
|
|
29225
|
+
}
|
|
29226
|
+
const controller = new AbortController;
|
|
29227
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
29228
|
+
const response = await fetch(url, {
|
|
29229
|
+
signal: controller.signal,
|
|
29230
|
+
headers: {
|
|
29231
|
+
"User-Agent": "oldpal/1.0 (AI Assistant)",
|
|
29232
|
+
Accept: extractType === "json" ? "application/json" : "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
|
29233
|
+
}
|
|
29234
|
+
});
|
|
29235
|
+
clearTimeout(timeoutId);
|
|
29236
|
+
if (!response.ok) {
|
|
29237
|
+
return `Error: HTTP ${response.status} ${response.statusText}`;
|
|
29238
|
+
}
|
|
29239
|
+
const contentType = response.headers.get("content-type") || "";
|
|
29240
|
+
if (extractType === "json") {
|
|
29241
|
+
try {
|
|
29242
|
+
const json = await response.json();
|
|
29243
|
+
return JSON.stringify(json, null, 2);
|
|
29244
|
+
} catch {
|
|
29245
|
+
return "Error: Response is not valid JSON";
|
|
29246
|
+
}
|
|
29247
|
+
}
|
|
29248
|
+
const html = await response.text();
|
|
29249
|
+
if (extractType === "html") {
|
|
29250
|
+
const maxLength2 = 50000;
|
|
29251
|
+
if (html.length > maxLength2) {
|
|
29252
|
+
return html.slice(0, maxLength2) + `
|
|
29253
|
+
|
|
29254
|
+
[Content truncated...]`;
|
|
29255
|
+
}
|
|
29256
|
+
return html;
|
|
29257
|
+
}
|
|
29258
|
+
const text = extractReadableText(html);
|
|
29259
|
+
const maxLength = 30000;
|
|
29260
|
+
if (text.length > maxLength) {
|
|
29261
|
+
return text.slice(0, maxLength) + `
|
|
29262
|
+
|
|
29263
|
+
[Content truncated...]`;
|
|
29264
|
+
}
|
|
29265
|
+
return text || "No readable content found on page";
|
|
29266
|
+
} catch (error) {
|
|
29267
|
+
if (error instanceof Error) {
|
|
29268
|
+
if (error.name === "AbortError") {
|
|
29269
|
+
return `Error: Request timed out after ${timeout}ms`;
|
|
29270
|
+
}
|
|
29271
|
+
return `Error: ${error.message}`;
|
|
29272
|
+
}
|
|
29273
|
+
return `Error: ${String(error)}`;
|
|
29274
|
+
}
|
|
29275
|
+
};
|
|
29276
|
+
}
|
|
29277
|
+
|
|
29278
|
+
class WebSearchTool {
|
|
29279
|
+
static tool = {
|
|
29280
|
+
name: "web_search",
|
|
29281
|
+
description: "Search the web using DuckDuckGo and return results. Useful for finding current information, documentation, news, etc.",
|
|
29282
|
+
parameters: {
|
|
29283
|
+
type: "object",
|
|
29284
|
+
properties: {
|
|
29285
|
+
query: {
|
|
29286
|
+
type: "string",
|
|
29287
|
+
description: "The search query"
|
|
29288
|
+
},
|
|
29289
|
+
max_results: {
|
|
29290
|
+
type: "number",
|
|
29291
|
+
description: "Maximum number of results to return (default: 5, max: 10)"
|
|
29292
|
+
}
|
|
29293
|
+
},
|
|
29294
|
+
required: ["query"]
|
|
29295
|
+
}
|
|
29296
|
+
};
|
|
29297
|
+
static executor = async (input) => {
|
|
29298
|
+
const query = input.query;
|
|
29299
|
+
const maxResults = Math.min(input.max_results || 5, 10);
|
|
29300
|
+
try {
|
|
29301
|
+
const searchUrl = `https://html.duckduckgo.com/html/?q=${encodeURIComponent(query)}`;
|
|
29302
|
+
const response = await fetch(searchUrl, {
|
|
29303
|
+
headers: {
|
|
29304
|
+
"User-Agent": "oldpal/1.0 (AI Assistant)",
|
|
29305
|
+
Accept: "text/html"
|
|
29306
|
+
}
|
|
29307
|
+
});
|
|
29308
|
+
if (!response.ok) {
|
|
29309
|
+
return `Error: Search request failed with HTTP ${response.status}`;
|
|
29310
|
+
}
|
|
29311
|
+
const html = await response.text();
|
|
29312
|
+
const results = parseDuckDuckGoResults(html, maxResults);
|
|
29313
|
+
if (results.length === 0) {
|
|
29314
|
+
return `No results found for "${query}"`;
|
|
29315
|
+
}
|
|
29316
|
+
let output = `Search results for "${query}":
|
|
29317
|
+
|
|
29318
|
+
`;
|
|
29319
|
+
for (let i = 0;i < results.length; i++) {
|
|
29320
|
+
const r = results[i];
|
|
29321
|
+
output += `${i + 1}. ${r.title}
|
|
29322
|
+
`;
|
|
29323
|
+
output += ` ${r.url}
|
|
29324
|
+
`;
|
|
29325
|
+
if (r.snippet) {
|
|
29326
|
+
output += ` ${r.snippet}
|
|
29327
|
+
`;
|
|
29328
|
+
}
|
|
29329
|
+
output += `
|
|
29330
|
+
`;
|
|
29331
|
+
}
|
|
29332
|
+
return output.trim();
|
|
29333
|
+
} catch (error) {
|
|
29334
|
+
return `Error: ${error instanceof Error ? error.message : String(error)}`;
|
|
29335
|
+
}
|
|
29336
|
+
};
|
|
29337
|
+
}
|
|
29338
|
+
function extractReadableText(html) {
|
|
29339
|
+
let text = html.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "").replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "").replace(/<noscript[^>]*>[\s\S]*?<\/noscript>/gi, "").replace(/<nav[^>]*>[\s\S]*?<\/nav>/gi, "").replace(/<footer[^>]*>[\s\S]*?<\/footer>/gi, "").replace(/<header[^>]*>[\s\S]*?<\/header>/gi, "");
|
|
29340
|
+
text = text.replace(/<\/?(p|div|br|h[1-6]|li|tr|blockquote)[^>]*>/gi, `
|
|
29341
|
+
`).replace(/<\/?[^>]+>/g, " ").replace(/ /gi, " ").replace(/&/gi, "&").replace(/</gi, "<").replace(/>/gi, ">").replace(/"/gi, '"').replace(/'/gi, "'").replace(/\s+/g, " ").replace(/\n\s*\n/g, `
|
|
29342
|
+
|
|
29343
|
+
`).trim();
|
|
29344
|
+
return text;
|
|
29345
|
+
}
|
|
29346
|
+
function parseDuckDuckGoResults(html, maxResults) {
|
|
29347
|
+
const results = [];
|
|
29348
|
+
const resultRegex = /<a[^>]*class="result__a"[^>]*href="([^"]*)"[^>]*>([^<]*)<\/a>[\s\S]*?<a[^>]*class="result__snippet"[^>]*>([^<]*)/gi;
|
|
29349
|
+
let match;
|
|
29350
|
+
while ((match = resultRegex.exec(html)) !== null && results.length < maxResults) {
|
|
29351
|
+
const url = decodeURIComponent(match[1].replace(/\/l\/\?uddg=/, "").split("&")[0]);
|
|
29352
|
+
const title = match[2].trim();
|
|
29353
|
+
const snippet = match[3].trim().replace(/&[^;]+;/g, " ");
|
|
29354
|
+
if (url && title && !url.startsWith("//duckduckgo.com")) {
|
|
29355
|
+
results.push({ title, url, snippet });
|
|
29356
|
+
}
|
|
29357
|
+
}
|
|
29358
|
+
if (results.length === 0) {
|
|
29359
|
+
const simpleRegex = /<a[^>]*href="(https?:\/\/[^"]+)"[^>]*class="[^"]*result[^"]*"[^>]*>([^<]+)/gi;
|
|
29360
|
+
while ((match = simpleRegex.exec(html)) !== null && results.length < maxResults) {
|
|
29361
|
+
const url = match[1];
|
|
29362
|
+
const title = match[2].trim();
|
|
29363
|
+
if (url && title) {
|
|
29364
|
+
results.push({ title, url, snippet: "" });
|
|
29365
|
+
}
|
|
29366
|
+
}
|
|
29367
|
+
}
|
|
29368
|
+
return results;
|
|
29369
|
+
}
|
|
29370
|
+
|
|
29371
|
+
class WebTools {
|
|
29372
|
+
static registerAll(registry) {
|
|
29373
|
+
registry.register(WebFetchTool.tool, WebFetchTool.executor);
|
|
29374
|
+
registry.register(WebSearchTool.tool, WebSearchTool.executor);
|
|
29375
|
+
}
|
|
29376
|
+
}
|
|
29377
|
+
|
|
29190
29378
|
// packages/core/src/skills/loader.ts
|
|
29191
29379
|
import { join as join3 } from "path";
|
|
29192
29380
|
import { homedir as homedir2 } from "os";
|
|
@@ -29605,6 +29793,7 @@ class AgentLoop {
|
|
|
29605
29793
|
this.llmClient = await createLLMClient(this.config.llm);
|
|
29606
29794
|
this.toolRegistry.register(BashTool.tool, BashTool.executor);
|
|
29607
29795
|
FilesystemTools.registerAll(this.toolRegistry);
|
|
29796
|
+
WebTools.registerAll(this.toolRegistry);
|
|
29608
29797
|
await this.connectorBridge.discover(this.config.connectors);
|
|
29609
29798
|
this.connectorBridge.registerAll(this.toolRegistry);
|
|
29610
29799
|
await this.skillLoader.loadAll(this.cwd);
|
|
@@ -30073,26 +30262,50 @@ var build_default = TextInput;
|
|
|
30073
30262
|
|
|
30074
30263
|
// packages/terminal/src/components/Input.tsx
|
|
30075
30264
|
var jsx_dev_runtime = __toESM(require_jsx_dev_runtime(), 1);
|
|
30076
|
-
function Input({ onSubmit,
|
|
30265
|
+
function Input({ onSubmit, isProcessing, queueLength = 0 }) {
|
|
30077
30266
|
const [value, setValue] = import_react23.useState("");
|
|
30267
|
+
use_input_default((input, key) => {
|
|
30268
|
+
if (!value.trim())
|
|
30269
|
+
return;
|
|
30270
|
+
if ((key.shift || key.ctrl) && key.return) {
|
|
30271
|
+
onSubmit(value, "interrupt");
|
|
30272
|
+
setValue("");
|
|
30273
|
+
} else if (key.meta && key.return) {
|
|
30274
|
+
onSubmit(value, "queue");
|
|
30275
|
+
setValue("");
|
|
30276
|
+
}
|
|
30277
|
+
});
|
|
30078
30278
|
const handleSubmit = (submittedValue) => {
|
|
30079
|
-
if (
|
|
30279
|
+
if (!submittedValue.trim())
|
|
30080
30280
|
return;
|
|
30081
|
-
|
|
30281
|
+
if (isProcessing) {
|
|
30282
|
+
onSubmit(submittedValue, "queue");
|
|
30283
|
+
} else {
|
|
30284
|
+
onSubmit(submittedValue, "normal");
|
|
30285
|
+
}
|
|
30082
30286
|
setValue("");
|
|
30083
30287
|
};
|
|
30288
|
+
let prompt = "\u276F";
|
|
30289
|
+
let placeholder = "Type a message...";
|
|
30290
|
+
if (isProcessing) {
|
|
30291
|
+
prompt = "\u22EF";
|
|
30292
|
+
placeholder = queueLength > 0 ? "Type to queue another..." : "Type to queue (Enter) or interrupt (Shift+Enter)...";
|
|
30293
|
+
}
|
|
30084
30294
|
return /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
30085
30295
|
marginTop: 1,
|
|
30086
30296
|
children: [
|
|
30087
30297
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
30088
|
-
dimColor:
|
|
30089
|
-
children:
|
|
30090
|
-
|
|
30298
|
+
dimColor: isProcessing,
|
|
30299
|
+
children: [
|
|
30300
|
+
prompt,
|
|
30301
|
+
" "
|
|
30302
|
+
]
|
|
30303
|
+
}, undefined, true, undefined, this),
|
|
30091
30304
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(build_default, {
|
|
30092
30305
|
value,
|
|
30093
30306
|
onChange: setValue,
|
|
30094
30307
|
onSubmit: handleSubmit,
|
|
30095
|
-
placeholder
|
|
30308
|
+
placeholder
|
|
30096
30309
|
}, undefined, false, undefined, this)
|
|
30097
30310
|
]
|
|
30098
30311
|
}, undefined, true, undefined, this);
|
|
@@ -30134,7 +30347,7 @@ function parseMarkdown(text) {
|
|
|
30134
30347
|
|
|
30135
30348
|
// packages/terminal/src/components/Messages.tsx
|
|
30136
30349
|
var jsx_dev_runtime3 = __toESM(require_jsx_dev_runtime(), 1);
|
|
30137
|
-
function Messages4({ messages, currentResponse, currentToolCall, lastToolResult }) {
|
|
30350
|
+
function Messages4({ messages, currentResponse, currentToolCall, lastToolResult, activityLog = [] }) {
|
|
30138
30351
|
const visibleMessages = messages.slice(-15);
|
|
30139
30352
|
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
|
|
30140
30353
|
flexDirection: "column",
|
|
@@ -30142,7 +30355,37 @@ function Messages4({ messages, currentResponse, currentToolCall, lastToolResult
|
|
|
30142
30355
|
visibleMessages.map((message) => /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(MessageBubble, {
|
|
30143
30356
|
message
|
|
30144
30357
|
}, message.id, false, undefined, this)),
|
|
30145
|
-
|
|
30358
|
+
activityLog.map((entry) => {
|
|
30359
|
+
if (entry.type === "tool_call" && entry.toolCall) {
|
|
30360
|
+
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
|
|
30361
|
+
marginY: 1,
|
|
30362
|
+
children: [
|
|
30363
|
+
/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
|
|
30364
|
+
dimColor: true,
|
|
30365
|
+
children: "\u25D0 "
|
|
30366
|
+
}, undefined, false, undefined, this),
|
|
30367
|
+
/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
|
|
30368
|
+
dimColor: true,
|
|
30369
|
+
children: formatToolCall(entry.toolCall)
|
|
30370
|
+
}, undefined, false, undefined, this)
|
|
30371
|
+
]
|
|
30372
|
+
}, entry.id, true, undefined, this);
|
|
30373
|
+
}
|
|
30374
|
+
if (entry.type === "tool_result" && entry.toolResult) {
|
|
30375
|
+
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
|
|
30376
|
+
marginLeft: 2,
|
|
30377
|
+
children: /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
|
|
30378
|
+
dimColor: true,
|
|
30379
|
+
children: [
|
|
30380
|
+
"\u2192 ",
|
|
30381
|
+
truncate(entry.toolResult.content, 100)
|
|
30382
|
+
]
|
|
30383
|
+
}, undefined, true, undefined, this)
|
|
30384
|
+
}, entry.id, false, undefined, this);
|
|
30385
|
+
}
|
|
30386
|
+
return null;
|
|
30387
|
+
}),
|
|
30388
|
+
currentToolCall && !activityLog.some((e) => e.toolCall?.id === currentToolCall.id) && /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
|
|
30146
30389
|
marginY: 1,
|
|
30147
30390
|
children: [
|
|
30148
30391
|
/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
|
|
@@ -30155,7 +30398,7 @@ function Messages4({ messages, currentResponse, currentToolCall, lastToolResult
|
|
|
30155
30398
|
}, undefined, false, undefined, this)
|
|
30156
30399
|
]
|
|
30157
30400
|
}, undefined, true, undefined, this),
|
|
30158
|
-
lastToolResult && /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
|
|
30401
|
+
lastToolResult && !activityLog.some((e) => e.toolResult?.toolCallId === lastToolResult.toolCallId) && /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
|
|
30159
30402
|
marginY: 1,
|
|
30160
30403
|
marginLeft: 2,
|
|
30161
30404
|
children: /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
|
|
@@ -30273,9 +30516,10 @@ function truncate(text, maxLength) {
|
|
|
30273
30516
|
|
|
30274
30517
|
// packages/terminal/src/components/Status.tsx
|
|
30275
30518
|
var jsx_dev_runtime4 = __toESM(require_jsx_dev_runtime(), 1);
|
|
30276
|
-
function Status({ isProcessing, cwd: cwd2 }) {
|
|
30519
|
+
function Status({ isProcessing, cwd: cwd2, queueLength = 0 }) {
|
|
30277
30520
|
const maxCwdLength = 50;
|
|
30278
30521
|
const displayCwd = cwd2.length > maxCwdLength ? "..." + cwd2.slice(-(maxCwdLength - 3)) : cwd2;
|
|
30522
|
+
const queueInfo = queueLength > 0 ? ` | ${queueLength} queued` : "";
|
|
30279
30523
|
return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
|
|
30280
30524
|
marginTop: 1,
|
|
30281
30525
|
borderStyle: "single",
|
|
@@ -30293,11 +30537,15 @@ function Status({ isProcessing, cwd: cwd2 }) {
|
|
|
30293
30537
|
dimColor: !isProcessing,
|
|
30294
30538
|
children: isProcessing ? "\u25CF processing" : "\u25CF ready"
|
|
30295
30539
|
}, undefined, false, undefined, this),
|
|
30540
|
+
/* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
|
|
30541
|
+
dimColor: true,
|
|
30542
|
+
children: queueInfo
|
|
30543
|
+
}, undefined, false, undefined, this),
|
|
30296
30544
|
/* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
|
|
30297
30545
|
dimColor: true,
|
|
30298
30546
|
children: [
|
|
30299
|
-
" |
|
|
30300
|
-
isProcessing ? "stop" : "exit"
|
|
30547
|
+
" | ",
|
|
30548
|
+
isProcessing ? "Esc to stop" : "Ctrl+C to exit"
|
|
30301
30549
|
]
|
|
30302
30550
|
}, undefined, true, undefined, this)
|
|
30303
30551
|
]
|
|
@@ -30361,37 +30609,90 @@ function App2({ cwd: cwd2 }) {
|
|
|
30361
30609
|
const [isProcessing, setIsProcessing] = import_react25.useState(false);
|
|
30362
30610
|
const [isInitializing, setIsInitializing] = import_react25.useState(true);
|
|
30363
30611
|
const [error, setError] = import_react25.useState(null);
|
|
30612
|
+
const [messageQueue, setMessageQueue] = import_react25.useState([]);
|
|
30613
|
+
const [activityLog, setActivityLog] = import_react25.useState([]);
|
|
30364
30614
|
const responseRef = import_react25.useRef("");
|
|
30615
|
+
const clientRef = import_react25.useRef(null);
|
|
30616
|
+
const toolCallsRef = import_react25.useRef([]);
|
|
30617
|
+
const toolResultsRef = import_react25.useRef([]);
|
|
30618
|
+
const processQueue = import_react25.useCallback(async () => {
|
|
30619
|
+
if (!clientRef.current || messageQueue.length === 0)
|
|
30620
|
+
return;
|
|
30621
|
+
const nextMessage = messageQueue[0];
|
|
30622
|
+
setMessageQueue((prev) => prev.slice(1));
|
|
30623
|
+
const userMessage = {
|
|
30624
|
+
id: generateId(),
|
|
30625
|
+
role: "user",
|
|
30626
|
+
content: nextMessage,
|
|
30627
|
+
timestamp: now()
|
|
30628
|
+
};
|
|
30629
|
+
setMessages((prev) => [...prev, userMessage]);
|
|
30630
|
+
setCurrentResponse("");
|
|
30631
|
+
responseRef.current = "";
|
|
30632
|
+
toolCallsRef.current = [];
|
|
30633
|
+
toolResultsRef.current = [];
|
|
30634
|
+
setError(null);
|
|
30635
|
+
setCurrentToolCall(undefined);
|
|
30636
|
+
setLastToolResult(undefined);
|
|
30637
|
+
setActivityLog([]);
|
|
30638
|
+
setIsProcessing(true);
|
|
30639
|
+
await clientRef.current.send(nextMessage);
|
|
30640
|
+
}, [messageQueue]);
|
|
30365
30641
|
import_react25.useEffect(() => {
|
|
30366
30642
|
const initClient = async () => {
|
|
30367
30643
|
try {
|
|
30368
30644
|
const newClient = new EmbeddedClient(cwd2);
|
|
30645
|
+
clientRef.current = newClient;
|
|
30369
30646
|
newClient.onChunk((chunk) => {
|
|
30370
30647
|
if (chunk.type === "text" && chunk.content) {
|
|
30371
30648
|
responseRef.current += chunk.content;
|
|
30372
30649
|
setCurrentResponse(responseRef.current);
|
|
30373
30650
|
} else if (chunk.type === "tool_use" && chunk.toolCall) {
|
|
30651
|
+
toolCallsRef.current.push(chunk.toolCall);
|
|
30652
|
+
setActivityLog((prev) => [
|
|
30653
|
+
...prev,
|
|
30654
|
+
{
|
|
30655
|
+
id: generateId(),
|
|
30656
|
+
type: "tool_call",
|
|
30657
|
+
toolCall: chunk.toolCall,
|
|
30658
|
+
timestamp: now()
|
|
30659
|
+
}
|
|
30660
|
+
]);
|
|
30374
30661
|
setCurrentToolCall(chunk.toolCall);
|
|
30375
30662
|
setLastToolResult(undefined);
|
|
30376
30663
|
} else if (chunk.type === "tool_result" && chunk.toolResult) {
|
|
30664
|
+
toolResultsRef.current.push(chunk.toolResult);
|
|
30665
|
+
setActivityLog((prev) => [
|
|
30666
|
+
...prev,
|
|
30667
|
+
{
|
|
30668
|
+
id: generateId(),
|
|
30669
|
+
type: "tool_result",
|
|
30670
|
+
toolResult: chunk.toolResult,
|
|
30671
|
+
timestamp: now()
|
|
30672
|
+
}
|
|
30673
|
+
]);
|
|
30377
30674
|
setLastToolResult(chunk.toolResult);
|
|
30378
30675
|
setCurrentToolCall(undefined);
|
|
30379
30676
|
} else if (chunk.type === "error" && chunk.error) {
|
|
30380
30677
|
setError(chunk.error);
|
|
30381
30678
|
setIsProcessing(false);
|
|
30382
30679
|
} else if (chunk.type === "done") {
|
|
30383
|
-
if (responseRef.current) {
|
|
30680
|
+
if (responseRef.current || toolCallsRef.current.length > 0) {
|
|
30384
30681
|
setMessages((prev) => [
|
|
30385
30682
|
...prev,
|
|
30386
30683
|
{
|
|
30387
30684
|
id: generateId(),
|
|
30388
30685
|
role: "assistant",
|
|
30389
30686
|
content: responseRef.current,
|
|
30390
|
-
timestamp: now()
|
|
30687
|
+
timestamp: now(),
|
|
30688
|
+
toolCalls: toolCallsRef.current.length > 0 ? [...toolCallsRef.current] : undefined,
|
|
30689
|
+
toolResults: toolResultsRef.current.length > 0 ? [...toolResultsRef.current] : undefined
|
|
30391
30690
|
}
|
|
30392
30691
|
]);
|
|
30393
30692
|
setCurrentResponse("");
|
|
30394
30693
|
responseRef.current = "";
|
|
30694
|
+
toolCallsRef.current = [];
|
|
30695
|
+
toolResultsRef.current = [];
|
|
30395
30696
|
}
|
|
30396
30697
|
setCurrentToolCall(undefined);
|
|
30397
30698
|
setLastToolResult(undefined);
|
|
@@ -30412,20 +30713,83 @@ function App2({ cwd: cwd2 }) {
|
|
|
30412
30713
|
};
|
|
30413
30714
|
initClient();
|
|
30414
30715
|
}, [cwd2]);
|
|
30716
|
+
import_react25.useEffect(() => {
|
|
30717
|
+
if (!isProcessing && messageQueue.length > 0) {
|
|
30718
|
+
processQueue();
|
|
30719
|
+
}
|
|
30720
|
+
}, [isProcessing, messageQueue.length, processQueue]);
|
|
30415
30721
|
use_input_default((input, key) => {
|
|
30416
30722
|
if (key.ctrl && input === "c") {
|
|
30417
30723
|
if (isProcessing && client) {
|
|
30418
30724
|
client.stop();
|
|
30725
|
+
if (responseRef.current) {
|
|
30726
|
+
setMessages((prev) => [
|
|
30727
|
+
...prev,
|
|
30728
|
+
{
|
|
30729
|
+
id: generateId(),
|
|
30730
|
+
role: "assistant",
|
|
30731
|
+
content: responseRef.current + `
|
|
30732
|
+
|
|
30733
|
+
[stopped]`,
|
|
30734
|
+
timestamp: now()
|
|
30735
|
+
}
|
|
30736
|
+
]);
|
|
30737
|
+
setCurrentResponse("");
|
|
30738
|
+
responseRef.current = "";
|
|
30739
|
+
}
|
|
30419
30740
|
setIsProcessing(false);
|
|
30420
30741
|
} else {
|
|
30421
30742
|
exit();
|
|
30422
30743
|
}
|
|
30423
30744
|
}
|
|
30745
|
+
if (key.escape && isProcessing && client) {
|
|
30746
|
+
client.stop();
|
|
30747
|
+
if (responseRef.current) {
|
|
30748
|
+
setMessages((prev) => [
|
|
30749
|
+
...prev,
|
|
30750
|
+
{
|
|
30751
|
+
id: generateId(),
|
|
30752
|
+
role: "assistant",
|
|
30753
|
+
content: responseRef.current + `
|
|
30754
|
+
|
|
30755
|
+
[stopped]`,
|
|
30756
|
+
timestamp: now()
|
|
30757
|
+
}
|
|
30758
|
+
]);
|
|
30759
|
+
setCurrentResponse("");
|
|
30760
|
+
responseRef.current = "";
|
|
30761
|
+
}
|
|
30762
|
+
setIsProcessing(false);
|
|
30763
|
+
}
|
|
30424
30764
|
});
|
|
30425
|
-
const handleSubmit = import_react25.useCallback(async (input) => {
|
|
30426
|
-
if (!client || !input.trim()
|
|
30765
|
+
const handleSubmit = import_react25.useCallback(async (input, mode = "normal") => {
|
|
30766
|
+
if (!client || !input.trim())
|
|
30427
30767
|
return;
|
|
30428
30768
|
const trimmedInput = input.trim();
|
|
30769
|
+
if (mode === "queue" || isProcessing && mode === "normal") {
|
|
30770
|
+
setMessageQueue((prev) => [...prev, trimmedInput]);
|
|
30771
|
+
return;
|
|
30772
|
+
}
|
|
30773
|
+
if (mode === "interrupt" && isProcessing) {
|
|
30774
|
+
client.stop();
|
|
30775
|
+
if (responseRef.current) {
|
|
30776
|
+
setMessages((prev) => [
|
|
30777
|
+
...prev,
|
|
30778
|
+
{
|
|
30779
|
+
id: generateId(),
|
|
30780
|
+
role: "assistant",
|
|
30781
|
+
content: responseRef.current + `
|
|
30782
|
+
|
|
30783
|
+
[interrupted]`,
|
|
30784
|
+
timestamp: now()
|
|
30785
|
+
}
|
|
30786
|
+
]);
|
|
30787
|
+
}
|
|
30788
|
+
setCurrentResponse("");
|
|
30789
|
+
responseRef.current = "";
|
|
30790
|
+
setIsProcessing(false);
|
|
30791
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
30792
|
+
}
|
|
30429
30793
|
const userMessage = {
|
|
30430
30794
|
id: generateId(),
|
|
30431
30795
|
role: "user",
|
|
@@ -30435,9 +30799,12 @@ function App2({ cwd: cwd2 }) {
|
|
|
30435
30799
|
setMessages((prev) => [...prev, userMessage]);
|
|
30436
30800
|
setCurrentResponse("");
|
|
30437
30801
|
responseRef.current = "";
|
|
30802
|
+
toolCallsRef.current = [];
|
|
30803
|
+
toolResultsRef.current = [];
|
|
30438
30804
|
setError(null);
|
|
30439
30805
|
setCurrentToolCall(undefined);
|
|
30440
30806
|
setLastToolResult(undefined);
|
|
30807
|
+
setActivityLog([]);
|
|
30441
30808
|
setIsProcessing(true);
|
|
30442
30809
|
await client.send(trimmedInput);
|
|
30443
30810
|
}, [client, isProcessing]);
|
|
@@ -30458,7 +30825,20 @@ function App2({ cwd: cwd2 }) {
|
|
|
30458
30825
|
messages,
|
|
30459
30826
|
currentResponse: isProcessing ? currentResponse : undefined,
|
|
30460
30827
|
currentToolCall,
|
|
30461
|
-
lastToolResult
|
|
30828
|
+
lastToolResult,
|
|
30829
|
+
activityLog: isProcessing ? activityLog : []
|
|
30830
|
+
}, undefined, false, undefined, this),
|
|
30831
|
+
messageQueue.length > 0 && /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
|
|
30832
|
+
marginY: 1,
|
|
30833
|
+
children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
|
|
30834
|
+
dimColor: true,
|
|
30835
|
+
children: [
|
|
30836
|
+
messageQueue.length,
|
|
30837
|
+
" message",
|
|
30838
|
+
messageQueue.length > 1 ? "s" : "",
|
|
30839
|
+
" queued"
|
|
30840
|
+
]
|
|
30841
|
+
}, undefined, true, undefined, this)
|
|
30462
30842
|
}, undefined, false, undefined, this),
|
|
30463
30843
|
error && /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
|
|
30464
30844
|
marginY: 1,
|
|
@@ -30478,11 +30858,13 @@ function App2({ cwd: cwd2 }) {
|
|
|
30478
30858
|
}, undefined, false, undefined, this),
|
|
30479
30859
|
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Input, {
|
|
30480
30860
|
onSubmit: handleSubmit,
|
|
30481
|
-
|
|
30861
|
+
isProcessing,
|
|
30862
|
+
queueLength: messageQueue.length
|
|
30482
30863
|
}, undefined, false, undefined, this),
|
|
30483
30864
|
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Status, {
|
|
30484
30865
|
isProcessing,
|
|
30485
|
-
cwd: cwd2
|
|
30866
|
+
cwd: cwd2,
|
|
30867
|
+
queueLength: messageQueue.length
|
|
30486
30868
|
}, undefined, false, undefined, this)
|
|
30487
30869
|
]
|
|
30488
30870
|
}, undefined, true, undefined, this);
|
|
@@ -30497,7 +30879,7 @@ var options = {
|
|
|
30497
30879
|
help: args.includes("--help") || args.includes("-h")
|
|
30498
30880
|
};
|
|
30499
30881
|
if (options.version) {
|
|
30500
|
-
console.log("oldpal v0.1.
|
|
30882
|
+
console.log("oldpal v0.1.8");
|
|
30501
30883
|
process.exit(0);
|
|
30502
30884
|
}
|
|
30503
30885
|
if (options.help) {
|
|
@@ -30528,4 +30910,4 @@ waitUntilExit().then(() => {
|
|
|
30528
30910
|
process.exit(0);
|
|
30529
30911
|
});
|
|
30530
30912
|
|
|
30531
|
-
//# debugId=
|
|
30913
|
+
//# debugId=43BB59ABD8BF8C1564756E2164756E21
|