@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 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(/&nbsp;/gi, " ").replace(/&amp;/gi, "&").replace(/&lt;/gi, "<").replace(/&gt;/gi, ">").replace(/&quot;/gi, '"').replace(/&#39;/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, disabled }) {
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 (disabled || !submittedValue.trim())
30279
+ if (!submittedValue.trim())
30080
30280
  return;
30081
- onSubmit(submittedValue);
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: disabled,
30089
- children: "\u276F "
30090
- }, undefined, false, undefined, this),
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: disabled ? "" : "Type a message..."
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
- currentToolCall && /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
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
- " | Ctrl+C to ",
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() || isProcessing)
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
- disabled: isProcessing
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.6");
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=F294B9F3A80B4E7C64756E2164756E21
30913
+ //# debugId=43BB59ABD8BF8C1564756E2164756E21