opencrowd 0.16.5 → 0.16.7
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/bundle/opencrowd.js +68 -12
- package/package.json +1 -1
package/bundle/opencrowd.js
CHANGED
|
@@ -15485,6 +15485,12 @@ var init_primitives = __esm({
|
|
|
15485
15485
|
*/
|
|
15486
15486
|
inputPriceUsdPerMillion: external_exports.number().nonnegative().max(1e4).optional(),
|
|
15487
15487
|
cachedInputPriceUsdPerMillion: external_exports.number().nonnegative().max(1e4).optional(),
|
|
15488
|
+
/**
|
|
15489
|
+
* The host offers this model for conversation only: the run advertises no
|
|
15490
|
+
* tools, sends no tool-use instructions, and executes no tool call. For a
|
|
15491
|
+
* model that writes its tool calls as text and makes up their results.
|
|
15492
|
+
*/
|
|
15493
|
+
chatOnly: external_exports.boolean().optional(),
|
|
15488
15494
|
submodel: external_exports.string().min(1).optional()
|
|
15489
15495
|
});
|
|
15490
15496
|
BudgetSchema = external_exports.looseObject({
|
|
@@ -87563,19 +87569,56 @@ var init_runtime2 = __esm({
|
|
|
87563
87569
|
}
|
|
87564
87570
|
});
|
|
87565
87571
|
|
|
87572
|
+
// ../../packages/agent-runtime/dist/chat-only.js
|
|
87573
|
+
function chatOnlyMessages(messages) {
|
|
87574
|
+
return messages.flatMap((message) => {
|
|
87575
|
+
if (message.role === "tool")
|
|
87576
|
+
return [];
|
|
87577
|
+
if (message.role !== "assistant" || !message.toolCalls?.length)
|
|
87578
|
+
return [message];
|
|
87579
|
+
if (!message.content.trim())
|
|
87580
|
+
return [];
|
|
87581
|
+
const { toolCalls: _calls, ...rest } = message;
|
|
87582
|
+
return [rest];
|
|
87583
|
+
});
|
|
87584
|
+
}
|
|
87585
|
+
var CHAT_ONLY_SYSTEM_PROMPT;
|
|
87586
|
+
var init_chat_only = __esm({
|
|
87587
|
+
"../../packages/agent-runtime/dist/chat-only.js"() {
|
|
87588
|
+
"use strict";
|
|
87589
|
+
CHAT_ONLY_SYSTEM_PROMPT = [
|
|
87590
|
+
"You are a hosted CrowdCode agent, talking with your owner.",
|
|
87591
|
+
"This agent runs on a chat-only model: in this chat you have no tools. You cannot run commands or code, read, write or send files, browse or search the web, buy or call paid services, send email or messages, schedule reminders or recurring tasks, or move money.",
|
|
87592
|
+
"Talk with the owner: answer questions, explain, write, brainstorm, and take part in role-play or creative writing when they ask for it, from your own knowledge.",
|
|
87593
|
+
"When the owner asks for something that needs one of those abilities, say plainly that this agent is on a chat-only model and cannot do it, suggest switching this agent to a model that can use tools in the model picker, and offer what you can do in words instead.",
|
|
87594
|
+
"Never pretend to have done such a thing: do not write out a tool or function call, and never invent command output, search results, file contents, prices, or payment, booking or delivery confirmations.",
|
|
87595
|
+
"You cannot check anything live, so say so when an answer depends on current facts."
|
|
87596
|
+
].join(" ") + "\n\n" + [
|
|
87597
|
+
// Last and on its own, because it is the rule the models broke: asked for a
|
|
87598
|
+
// SHA-256, venice-uncensored-role-play said it could not compute one and then
|
|
87599
|
+
// gave "the first 12 characters" anyway, in 3 of 12 tries with the rules
|
|
87600
|
+
// above and 0 of 24 with this one (2026-11-06). "Exact results" alone made
|
|
87601
|
+
// it refuse 17 × 23, hence the last sentence.
|
|
87602
|
+
'Most important rule: you cannot compute a hash, checksum or encoding, or know what a command, a file or a live lookup would return, so never write one down: not a guess, not an example, not "the first few characters".',
|
|
87603
|
+
"Any value you wrote would be made up, and the owner would act on it. Say you cannot produce it, and stop there.",
|
|
87604
|
+
"Ordinary arithmetic and facts you know are fine to answer."
|
|
87605
|
+
].join(" ");
|
|
87606
|
+
}
|
|
87607
|
+
});
|
|
87608
|
+
|
|
87566
87609
|
// ../../packages/agent-runtime/dist/hosted-provider.js
|
|
87567
87610
|
import { request } from "node:http";
|
|
87568
87611
|
import { isAbsolute as isAbsolute3 } from "node:path";
|
|
87569
87612
|
function createHostedProvider(options) {
|
|
87570
87613
|
if (!isAbsolute3(options.socketPath))
|
|
87571
87614
|
throw new Error("Hosted bridge socket must be absolute");
|
|
87572
|
-
const tools = [...OPEN_CROWD_TOOLS.filter((tool) => !["spawn_subagent", "check_subagents"].includes(tool.name)).map((tool) => tool.name === "get_budget_status" ? { ...tool, description: "Read authoritative hosted finances: live USDC wallet balance, settled inference and service spending, pending holds, and remaining authorized budget for this run." } : tool), ...options.extraTools ?? []];
|
|
87615
|
+
const tools = options.chatOnly ? [] : [...OPEN_CROWD_TOOLS.filter((tool) => !["spawn_subagent", "check_subagents"].includes(tool.name)).map((tool) => tool.name === "get_budget_status" ? { ...tool, description: "Read authoritative hosted finances: live USDC wallet balance, settled inference and service spending, pending holds, and remaining authorized budget for this run." } : tool), ...options.extraTools ?? []];
|
|
87573
87616
|
return {
|
|
87574
87617
|
async complete(messages, context) {
|
|
87575
87618
|
const operationId = context?.operationId;
|
|
87576
87619
|
if (!operationId?.startsWith(`${options.runId}:llm:`))
|
|
87577
87620
|
throw new Error("Hosted model operation scope is missing");
|
|
87578
|
-
const body = JSON.stringify({ runId: options.runId, sessionId: options.sessionId, operationId, messages: messages.map(({ contextArchive: _archive, ...message }) => message), tools });
|
|
87621
|
+
const body = JSON.stringify({ runId: options.runId, sessionId: options.sessionId, operationId, messages: (options.chatOnly ? chatOnlyMessages(messages) : messages).map(({ contextArchive: _archive, ...message }) => message), tools });
|
|
87579
87622
|
if (Buffer.byteLength(body) > MODEL_SELLER_REQUEST_MAX_BYTES)
|
|
87580
87623
|
throw new ContextWindowExceeded(`Hosted request is ${Buffer.byteLength(body)} bytes, above the ${MODEL_SELLER_REQUEST_MAX_BYTES} a seller accepts`);
|
|
87581
87624
|
const result = await new Promise((resolve9, reject) => {
|
|
@@ -87754,6 +87797,7 @@ var init_hosted_provider = __esm({
|
|
|
87754
87797
|
init_dist2();
|
|
87755
87798
|
init_dist4();
|
|
87756
87799
|
init_worker();
|
|
87800
|
+
init_chat_only();
|
|
87757
87801
|
HostedRequestError = class extends Error {
|
|
87758
87802
|
code;
|
|
87759
87803
|
status;
|
|
@@ -88905,11 +88949,12 @@ var init_worker = __esm({
|
|
|
88905
88949
|
await beginQuery(session, runId);
|
|
88906
88950
|
await this.emit("run.state", { sessionId: session.sessionId, state: "running" }, runId, run.commandId);
|
|
88907
88951
|
const local = this.options.toolExecutor ?? executeTool;
|
|
88908
|
-
const
|
|
88909
|
-
const
|
|
88952
|
+
const chatOnly = run.start.payload.modelPolicy.chatOnly === true;
|
|
88953
|
+
const hosted = chatOnly ? void 0 : this.options.hostedTools?.(run.start, session);
|
|
88954
|
+
const economy = chatOnly ? void 0 : this.options.economy?.(run.start, session);
|
|
88910
88955
|
const dynamicTools = economy ? hostedDynamicTools(economy) : void 0;
|
|
88911
88956
|
let latestFinancialState = { status: "unavailable", reason: "Hosted financial state has not been read." };
|
|
88912
|
-
const financialState = this.options.financialState ? async () => {
|
|
88957
|
+
const financialState = this.options.financialState && !chatOnly ? async () => {
|
|
88913
88958
|
try {
|
|
88914
88959
|
latestFinancialState = await this.options.financialState(run.start, session);
|
|
88915
88960
|
} catch {
|
|
@@ -89050,6 +89095,7 @@ var init_worker = __esm({
|
|
|
89050
89095
|
signal,
|
|
89051
89096
|
resume: run.checkpoint,
|
|
89052
89097
|
maxTurns: run.start.payload.maxTurns,
|
|
89098
|
+
...chatOnly ? { chatOnly: true } : {},
|
|
89053
89099
|
contextWindowTokens: run.start.payload.modelPolicy.contextWindowTokens,
|
|
89054
89100
|
maxOutputTokens: run.start.payload.modelPolicy.maxOutputTokens,
|
|
89055
89101
|
prices: {
|
|
@@ -89400,8 +89446,8 @@ function wireToolDefinitions(names, extraTools) {
|
|
|
89400
89446
|
];
|
|
89401
89447
|
}
|
|
89402
89448
|
async function runAgentTaskDetailed(session, task, options = {}) {
|
|
89403
|
-
const enabledTools = options.tools ?? (options.hosted ? TOOL_NAMES.filter((name) => !["spawn_subagent", "check_subagents", "get_budget_status"].includes(name)) : TOOL_NAMES.filter((name) => !HOSTED_ONLY_TOOL_NAMES.includes(name) && (options.subagent || name !== "spawn_subagent")));
|
|
89404
|
-
const dynamicDefinitions = options.dynamicTools?.definitions ?? [];
|
|
89449
|
+
const enabledTools = options.chatOnly ? [] : options.tools ?? (options.hosted ? TOOL_NAMES.filter((name) => !["spawn_subagent", "check_subagents", "get_budget_status"].includes(name)) : TOOL_NAMES.filter((name) => !HOSTED_ONLY_TOOL_NAMES.includes(name) && (options.subagent || name !== "spawn_subagent")));
|
|
89450
|
+
const dynamicDefinitions = options.chatOnly ? [] : options.dynamicTools?.definitions ?? [];
|
|
89405
89451
|
const model = options.llm?.catalog?.find((m) => m.id === options.llm?.model);
|
|
89406
89452
|
const limits = contextLimits(options.contextWindowTokens ?? model?.contextWindowTokens, options.maxOutputTokens ?? model?.maxOutputTokens);
|
|
89407
89453
|
const contextState = { ...options.resume?.context };
|
|
@@ -89422,7 +89468,7 @@ async function runAgentTaskDetailed(session, task, options = {}) {
|
|
|
89422
89468
|
throw new Error("no LLM provider configured: pass an explicit provider (tests/demo) or a typed llm runtime");
|
|
89423
89469
|
}
|
|
89424
89470
|
const toolExecutor = options.toolExecutor ?? executeTool;
|
|
89425
|
-
const knowledge = options.capabilityIndex === void 0 && options.knowledge !== false && options.dynamicTools ? await loadKnowledgeTree(session, options.knowledge ?? {}) : void 0;
|
|
89471
|
+
const knowledge = !options.chatOnly && options.capabilityIndex === void 0 && options.knowledge !== false && options.dynamicTools ? await loadKnowledgeTree(session, options.knowledge ?? {}) : void 0;
|
|
89426
89472
|
const capabilityIndex = options.capabilityIndex ?? (knowledge ? renderCapabilityIndex(knowledge.l0) : void 0);
|
|
89427
89473
|
const systemPromptParts = [
|
|
89428
89474
|
options.hosted ? "You are a hosted OpenCrowd agent running in the cloud with your own USDC wallets on Base, Solana and Tempo." : "You are the local OpenCrowd agent, a CLI agent with a USDC wallet running on the user's personal machine.",
|
|
@@ -89461,7 +89507,7 @@ async function runAgentTaskDetailed(session, task, options = {}) {
|
|
|
89461
89507
|
systemPromptParts.push(`Delegation: spawn_subagent runs a cheaper, faster model (${options.subagent.model}${options.subagent.costHint ? `, ${options.subagent.costHint}` : ""}) with local file and shell tools only.`, "Delegate ONLY when you can spawn two or more INDEPENDENT subagents in the same reply \u2014 parallel fan-out is the entire benefit; multiple spawn_subagent calls in one reply run concurrently (2-4 is the sweet spot).", "If the work is one sequential thread where each step depends on the previous result, do it yourself in this main loop: a chain of single subagents is strictly slower than working directly and adds spawn/read overhead on top.", "Give each subagent an objective, expected output format, and clear boundaries so parallel subagents cannot make conflicting decisions; they see none of this conversation, so pass explicit context (file paths, constraints).", "Each subagent's files land under artifacts/subagents/<n>/ and its completion lists what it wrote.", "Suitable subagent work: summarizing, extracting, mechanical edits, or reading specific already-known URLs (subagents can curl free URLs via run_shell); keep planning, paid-service decisions, and final answers in this main loop.", "For web research: first buy one paid web search here in the main loop, then fan the returned URLs out to parallel subagents in a single reply. Never send a subagent off to guess URLs with curl.");
|
|
89462
89508
|
}
|
|
89463
89509
|
const messages = options.resume?.messages ?? [
|
|
89464
|
-
{ role: "system", content: systemPromptParts.join(" ") },
|
|
89510
|
+
{ role: "system", content: options.chatOnly ? CHAT_ONLY_SYSTEM_PROMPT : systemPromptParts.join(" ") },
|
|
89465
89511
|
...options.history ?? [],
|
|
89466
89512
|
{ role: "user", content: task }
|
|
89467
89513
|
];
|
|
@@ -89614,6 +89660,8 @@ async function runAgentTaskDetailed(session, task, options = {}) {
|
|
|
89614
89660
|
}
|
|
89615
89661
|
throw error53;
|
|
89616
89662
|
}
|
|
89663
|
+
if (options.chatOnly && response.toolCalls.length)
|
|
89664
|
+
response = { ...response, toolCalls: [] };
|
|
89617
89665
|
if (!restored?.response && (response.content || response.toolCalls.length > 0)) {
|
|
89618
89666
|
const assistantMessage = assistantMessageFromResponse(isOutputLimitFinishReason(response.finishReason) ? { ...response, toolCalls: [] } : response);
|
|
89619
89667
|
messages.push(assistantMessage);
|
|
@@ -89633,7 +89681,7 @@ ${outputContinuationPrefix}`);
|
|
|
89633
89681
|
outputContinuationNudges += 1;
|
|
89634
89682
|
const nudge = {
|
|
89635
89683
|
role: "user",
|
|
89636
|
-
content: "Your previous response hit the provider output limit. Any tool calls in that response were discarded and did not execute. If you were calling a tool, issue a complete, shorter tool call. Otherwise continue the answer exactly where it stopped. Put only the remaining suffix in complete_session.final_message; OpenCrowd will prepend the saved prefix. Do not repeat completed material."
|
|
89684
|
+
content: options.chatOnly ? "Your previous response hit the provider output limit. Continue the answer exactly where it stopped, without repeating what you already wrote." : "Your previous response hit the provider output limit. Any tool calls in that response were discarded and did not execute. If you were calling a tool, issue a complete, shorter tool call. Otherwise continue the answer exactly where it stopped. Put only the remaining suffix in complete_session.final_message; OpenCrowd will prepend the saved prefix. Do not repeat completed material."
|
|
89637
89685
|
};
|
|
89638
89686
|
messages.push(nudge);
|
|
89639
89687
|
await options.onMessage?.(nudge);
|
|
@@ -89644,7 +89692,7 @@ ${outputContinuationPrefix}`);
|
|
|
89644
89692
|
continue;
|
|
89645
89693
|
const finalMessage = response.content.trim() ? outputContinuationPrefix + response.content : pendingFinalMessage ?? outputContinuationPrefix;
|
|
89646
89694
|
recordFinalMessage(finalMessage);
|
|
89647
|
-
const blocker = await options.completionGate?.(completionNudges > 0);
|
|
89695
|
+
const blocker = options.chatOnly ? void 0 : await options.completionGate?.(completionNudges > 0);
|
|
89648
89696
|
const unanswered = answerNudges < 1 && placeholder();
|
|
89649
89697
|
if (blocker) {
|
|
89650
89698
|
if (completionNudges >= 1) {
|
|
@@ -90415,6 +90463,8 @@ var init_dist6 = __esm({
|
|
|
90415
90463
|
init_hosted_economy();
|
|
90416
90464
|
init_inbox();
|
|
90417
90465
|
init_x402_proxy();
|
|
90466
|
+
init_chat_only();
|
|
90467
|
+
init_chat_only();
|
|
90418
90468
|
init_knowledge();
|
|
90419
90469
|
init_context2();
|
|
90420
90470
|
init_tool_deadlines();
|
|
@@ -90818,7 +90868,13 @@ async function workerCommand(args) {
|
|
|
90818
90868
|
if (args.includes("--demo") === !!socketPath) throw new Error("worker requires exactly one of --demo or --bridge-socket <path>");
|
|
90819
90869
|
const worker = new MachineWorker({
|
|
90820
90870
|
agentHome: home,
|
|
90821
|
-
provider: (run, session, extraTools) => socketPath ? createHostedProvider({
|
|
90871
|
+
provider: (run, session, extraTools) => socketPath ? createHostedProvider({
|
|
90872
|
+
socketPath,
|
|
90873
|
+
runId: run.runId,
|
|
90874
|
+
sessionId: session.sessionId,
|
|
90875
|
+
extraTools,
|
|
90876
|
+
chatOnly: run.payload.modelPolicy.chatOnly === true
|
|
90877
|
+
}) : createWorkerDemoProvider(),
|
|
90822
90878
|
hostedTools: socketPath ? (run, session) => createHostedToolExecutor({ socketPath, runId: run.runId, sessionId: session.sessionId }) : void 0,
|
|
90823
90879
|
economy: socketPath ? (run, session) => createHostedEconomy({ socketPath, runId: run.runId, sessionId: session.sessionId, session }) : void 0,
|
|
90824
90880
|
financialState: socketPath ? (run, session) => readHostedFinancialState({ socketPath, runId: run.runId, sessionId: session.sessionId }) : void 0,
|
package/package.json
CHANGED