clawcompany 0.31.0 → 0.33.0

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.
Files changed (2) hide show
  1. package/dist/index.js +112 -52
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2149,7 +2149,7 @@ import { join } from "path";
2149
2149
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
2150
2150
  function banner() {
2151
2151
  console.log("");
2152
- console.log(" \u{1F99E} ClawCompany v0.31.0");
2152
+ console.log(" \u{1F99E} ClawCompany v0.33.0");
2153
2153
  console.log(" Build for OPC. Every human being is a chairman.");
2154
2154
  console.log("");
2155
2155
  }
@@ -2643,11 +2643,28 @@ var OpenAICompatibleProvider = class _OpenAICompatibleProvider {
2643
2643
  });
2644
2644
  if (!response.ok) {
2645
2645
  const errorBody = await response.text().catch(() => "");
2646
- throw new ProviderError(
2647
- response.status,
2648
- `${this.name} API error ${response.status}: ${errorBody}`,
2649
- this.id
2650
- );
2646
+ const status = response.status;
2647
+ let friendly;
2648
+ switch (true) {
2649
+ case status === 429:
2650
+ friendly = "Rate limited \u2014 too many requests. Please wait and try again.";
2651
+ break;
2652
+ case status === 529:
2653
+ friendly = "Model overloaded \u2014 the API is currently busy. Try again in a moment.";
2654
+ break;
2655
+ case (status === 502 || status === 504):
2656
+ friendly = "Request timeout \u2014 the model took too long to respond. Try a different role or model.";
2657
+ break;
2658
+ case (status === 401 || status === 403):
2659
+ friendly = "Authentication failed \u2014 check your API key.";
2660
+ break;
2661
+ case status === 400:
2662
+ friendly = `Bad request \u2014 this model may not support the current settings. (${errorBody.slice(0, 120)})`;
2663
+ break;
2664
+ default:
2665
+ friendly = `API error ${status}: ${errorBody.slice(0, 200)}`;
2666
+ }
2667
+ throw new ProviderError(status, friendly, this.id);
2651
2668
  }
2652
2669
  let content = "";
2653
2670
  let model = params.model;
@@ -2655,41 +2672,62 @@ var OpenAICompatibleProvider = class _OpenAICompatibleProvider {
2655
2672
  let promptTokens = 0;
2656
2673
  let completionTokens = 0;
2657
2674
  const toolCallBuffers = /* @__PURE__ */ new Map();
2658
- const reader = response.body.getReader();
2659
- const decoder = new TextDecoder();
2660
- let buffer = "";
2661
- while (true) {
2662
- const { done, value } = await reader.read();
2663
- if (done) break;
2664
- buffer += decoder.decode(value, { stream: true });
2665
- const lines = buffer.split("\n");
2666
- buffer = lines.pop() ?? "";
2667
- for (const line of lines) {
2668
- if (!line.startsWith("data: ") || line === "data: [DONE]") continue;
2669
- try {
2670
- const chunk = JSON.parse(line.slice(6));
2671
- const delta = chunk.choices?.[0]?.delta;
2672
- if (delta?.content) content += delta.content;
2673
- if (chunk.model) model = chunk.model;
2674
- const fr = chunk.choices?.[0]?.finish_reason;
2675
- if (fr) finishReason = fr;
2676
- if (delta?.tool_calls) {
2677
- for (const tc of delta.tool_calls) {
2678
- const idx = tc.index ?? 0;
2679
- if (!toolCallBuffers.has(idx)) {
2680
- toolCallBuffers.set(idx, { id: tc.id ?? `call_${idx}`, name: "", args: "" });
2675
+ const contentType = response.headers.get("content-type") ?? "";
2676
+ const isSSE = contentType.includes("text/event-stream");
2677
+ if (!isSSE) {
2678
+ const data = await response.json();
2679
+ content = data.choices?.[0]?.message?.content ?? "";
2680
+ model = data.model ?? params.model;
2681
+ finishReason = data.choices?.[0]?.finish_reason ?? "stop";
2682
+ promptTokens = data.usage?.prompt_tokens ?? 0;
2683
+ completionTokens = data.usage?.completion_tokens ?? 0;
2684
+ const tcList = data.choices?.[0]?.message?.tool_calls;
2685
+ if (tcList?.length) {
2686
+ for (const tc of tcList) {
2687
+ toolCallBuffers.set(toolCallBuffers.size, {
2688
+ id: tc.id,
2689
+ name: tc.function?.name ?? "",
2690
+ args: tc.function?.arguments ?? ""
2691
+ });
2692
+ }
2693
+ }
2694
+ } else {
2695
+ const reader = response.body.getReader();
2696
+ const decoder = new TextDecoder();
2697
+ let buffer = "";
2698
+ while (true) {
2699
+ const { done, value } = await reader.read();
2700
+ if (done) break;
2701
+ buffer += decoder.decode(value, { stream: true });
2702
+ const lines = buffer.split("\n");
2703
+ buffer = lines.pop() ?? "";
2704
+ for (const line of lines) {
2705
+ if (!line.startsWith("data: ") || line === "data: [DONE]") continue;
2706
+ try {
2707
+ const chunk = JSON.parse(line.slice(6));
2708
+ const delta = chunk.choices?.[0]?.delta;
2709
+ if (delta?.content) content += delta.content;
2710
+ if (chunk.model) model = chunk.model;
2711
+ const fr = chunk.choices?.[0]?.finish_reason;
2712
+ if (fr) finishReason = fr;
2713
+ if (delta?.tool_calls) {
2714
+ for (const tc of delta.tool_calls) {
2715
+ const idx = tc.index ?? 0;
2716
+ if (!toolCallBuffers.has(idx)) {
2717
+ toolCallBuffers.set(idx, { id: tc.id ?? `call_${idx}`, name: "", args: "" });
2718
+ }
2719
+ const buf = toolCallBuffers.get(idx);
2720
+ if (tc.id) buf.id = tc.id;
2721
+ if (tc.function?.name) buf.name = tc.function.name;
2722
+ if (tc.function?.arguments) buf.args += tc.function.arguments;
2681
2723
  }
2682
- const buf = toolCallBuffers.get(idx);
2683
- if (tc.id) buf.id = tc.id;
2684
- if (tc.function?.name) buf.name = tc.function.name;
2685
- if (tc.function?.arguments) buf.args += tc.function.arguments;
2686
2724
  }
2725
+ if (chunk.usage) {
2726
+ promptTokens = chunk.usage.prompt_tokens ?? 0;
2727
+ completionTokens = chunk.usage.completion_tokens ?? 0;
2728
+ }
2729
+ } catch {
2687
2730
  }
2688
- if (chunk.usage) {
2689
- promptTokens = chunk.usage.prompt_tokens ?? 0;
2690
- completionTokens = chunk.usage.completion_tokens ?? 0;
2691
- }
2692
- } catch {
2693
2731
  }
2694
2732
  }
2695
2733
  }
@@ -2697,6 +2735,16 @@ var OpenAICompatibleProvider = class _OpenAICompatibleProvider {
2697
2735
  for (const [, buf] of [...toolCallBuffers.entries()].sort((a, b) => a[0] - b[0])) {
2698
2736
  toolCalls.push({ id: buf.id, type: "function", function: { name: buf.name, arguments: buf.args } });
2699
2737
  }
2738
+ const cost = calculateCost(params.model, promptTokens, completionTokens);
2739
+ if (!content && toolCalls.length === 0 && cost === 0) {
2740
+ return {
2741
+ content: "\u26A0\uFE0F No response received from the model. This usually means the API is temporarily unavailable. Try again or switch to a different role.",
2742
+ model,
2743
+ provider: this.id,
2744
+ usage: { inputTokens: 0, outputTokens: 0, cost: 0 },
2745
+ finishReason
2746
+ };
2747
+ }
2700
2748
  return {
2701
2749
  content,
2702
2750
  model,
@@ -2704,7 +2752,7 @@ var OpenAICompatibleProvider = class _OpenAICompatibleProvider {
2704
2752
  usage: {
2705
2753
  inputTokens: promptTokens,
2706
2754
  outputTokens: completionTokens,
2707
- cost: calculateCost(params.model, promptTokens, completionTokens)
2755
+ cost
2708
2756
  },
2709
2757
  toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
2710
2758
  finishReason
@@ -2999,7 +3047,7 @@ function sleep(ms) {
2999
3047
  return new Promise((resolve2) => setTimeout(resolve2, ms));
3000
3048
  }
3001
3049
 
3002
- // ../packages/tools/src/executor.ts
3050
+ // ../packages/tools/src/executor.js
3003
3051
  import { exec } from "child_process";
3004
3052
  import { readFile, writeFile, readdir, unlink } from "fs/promises";
3005
3053
  import { promisify } from "util";
@@ -3111,7 +3159,8 @@ ${text.slice(0, 5e3)}`;
3111
3159
  }
3112
3160
  return raw.slice(0, limit);
3113
3161
  } catch (err) {
3114
- if (err.name === "TimeoutError") return "Error: Request timed out (15s)";
3162
+ if (err.name === "TimeoutError")
3163
+ return "Error: Request timed out (15s)";
3115
3164
  return `Error: ${err.message}`;
3116
3165
  }
3117
3166
  }
@@ -3135,7 +3184,8 @@ ${text.slice(0, 5e3)}`;
3135
3184
  for (let i = 1; i < resultBlocks.length && results.length < limit; i++) {
3136
3185
  const block = resultBlocks[i];
3137
3186
  const prevTail = resultBlocks[i - 1].slice(-300);
3138
- if (prevTail.includes("result--ad")) continue;
3187
+ if (prevTail.includes("result--ad"))
3188
+ continue;
3139
3189
  const titleMatch = block.match(/class="result__a"[^>]*>([^<]+)/);
3140
3190
  const title = titleMatch?.[1]?.replace(/&amp;/g, "&")?.replace(/&quot;/g, '"')?.replace(/&#x27;/g, "'")?.trim() ?? "";
3141
3191
  const urlMatch = block.match(/href="\/\/duckduckgo\.com\/l\/\?[^"]*uddg=([^&"]+)/);
@@ -3165,7 +3215,8 @@ ${text.slice(0, 5e3)}`;
3165
3215
  }
3166
3216
  return output;
3167
3217
  } catch (err) {
3168
- if (err.name === "TimeoutError") return "Error: Search timed out (10s)";
3218
+ if (err.name === "TimeoutError")
3219
+ return "Error: Search timed out (10s)";
3169
3220
  return `Error: ${err.message}`;
3170
3221
  }
3171
3222
  }
@@ -3174,33 +3225,39 @@ ${text.slice(0, 5e3)}`;
3174
3225
  let cmd;
3175
3226
  switch (action) {
3176
3227
  case "open":
3177
- if (!url) return "Error: url is required for open action";
3228
+ if (!url)
3229
+ return "Error: url is required for open action";
3178
3230
  cmd = `browser-use open ${JSON.stringify(url)}`;
3179
3231
  break;
3180
3232
  case "state":
3181
3233
  cmd = "browser-use state --json";
3182
3234
  break;
3183
3235
  case "click":
3184
- if (index === void 0) return "Error: index is required for click action";
3236
+ if (index === void 0)
3237
+ return "Error: index is required for click action";
3185
3238
  cmd = `browser-use click ${index}`;
3186
3239
  break;
3187
3240
  case "type":
3188
- if (!text) return "Error: text is required for type action";
3241
+ if (!text)
3242
+ return "Error: text is required for type action";
3189
3243
  cmd = `browser-use type ${JSON.stringify(text)}`;
3190
3244
  break;
3191
3245
  case "input":
3192
- if (index === void 0 || !text) return "Error: index and text are required for input action";
3246
+ if (index === void 0 || !text)
3247
+ return "Error: index and text are required for input action";
3193
3248
  cmd = `browser-use input ${index} ${JSON.stringify(text)}`;
3194
3249
  break;
3195
3250
  case "screenshot":
3196
3251
  cmd = `browser-use screenshot ${JSON.stringify(path ?? "/tmp/screenshot.png")}`;
3197
3252
  break;
3198
3253
  case "eval":
3199
- if (!code) return "Error: code is required for eval action";
3254
+ if (!code)
3255
+ return "Error: code is required for eval action";
3200
3256
  cmd = `browser-use eval ${JSON.stringify(code)}`;
3201
3257
  break;
3202
3258
  case "scroll":
3203
- if (!direction) return "Error: direction is required for scroll action";
3259
+ if (!direction)
3260
+ return "Error: direction is required for scroll action";
3204
3261
  cmd = `browser-use scroll ${direction}`;
3205
3262
  break;
3206
3263
  case "close":
@@ -3250,17 +3307,20 @@ STDERR: ${stderr}` : "");
3250
3307
  24h Volume: $${vol24h ? (vol24h / 1e9).toFixed(2) + "B" : "N/A"}
3251
3308
  24h Change: ${change24h?.toFixed(2) ?? "N/A"}%`;
3252
3309
  } catch (err) {
3253
- if (err.name === "AbortError") return "Error: Price feed timed out (10s)";
3310
+ if (err.name === "AbortError")
3311
+ return "Error: Price feed timed out (10s)";
3254
3312
  return `Error fetching price: ${err.message}`;
3255
3313
  }
3256
3314
  }
3257
3315
  async execMemorySearch(args) {
3258
3316
  const query = args.query;
3259
- if (!query) return "Error: query is required";
3317
+ if (!query)
3318
+ return "Error: query is required";
3260
3319
  try {
3261
3320
  const res = await fetch("http://localhost:3200/api/memory/search?q=" + encodeURIComponent(query));
3262
3321
  const data = await res.json();
3263
- if (data.totalMatches === 0) return "No matches found for: " + query;
3322
+ if (data.totalMatches === 0)
3323
+ return "No matches found for: " + query;
3264
3324
  let result = `Found ${data.totalMatches} matches:
3265
3325
 
3266
3326
  `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawcompany",
3
- "version": "0.31.0",
3
+ "version": "0.33.0",
4
4
  "description": "Build for OPC. Every human being is a chairman. AI company infrastructure — one key, 9 roles, 4 models.",
5
5
  "type": "module",
6
6
  "bin": { "clawcompany": "dist/index.js" },