opencrowd 0.11.0 → 0.11.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/bundle/opencrowd.js +9 -15
- package/package.json +1 -1
package/bundle/opencrowd.js
CHANGED
|
@@ -16724,7 +16724,7 @@ function maxShellTimeoutMs(env = process.env) {
|
|
|
16724
16724
|
}
|
|
16725
16725
|
return Math.min(SHELL_TIMEOUT_CEILING_MS, requested);
|
|
16726
16726
|
}
|
|
16727
|
-
async function runShell(state, command, cwd = state.
|
|
16727
|
+
async function runShell(state, command, cwd = state.sessionDir, timeoutMs = 1e4, options = {}) {
|
|
16728
16728
|
if (!state.shellEnabled) {
|
|
16729
16729
|
throw new Error("shell tool is disabled for this session");
|
|
16730
16730
|
}
|
|
@@ -16838,13 +16838,7 @@ function cleanupProcessGroup(child, detached) {
|
|
|
16838
16838
|
signalProcessGroup(child, detached, "SIGTERM");
|
|
16839
16839
|
}
|
|
16840
16840
|
function resolveShellCwd(state, cwd) {
|
|
16841
|
-
|
|
16842
|
-
return resolve3(cwd);
|
|
16843
|
-
}
|
|
16844
|
-
if (cwd === "artifacts" || cwd.startsWith("artifacts/")) {
|
|
16845
|
-
return resolve3(join7(state.sessionDir, cwd));
|
|
16846
|
-
}
|
|
16847
|
-
return resolve3(state.workspaceRoot, cwd);
|
|
16841
|
+
return isAbsolute2(cwd) ? resolve3(cwd) : resolve3(join7(state.sessionDir, cwd));
|
|
16848
16842
|
}
|
|
16849
16843
|
function minimalEnv() {
|
|
16850
16844
|
return {
|
|
@@ -16916,7 +16910,7 @@ function toolParameters(name) {
|
|
|
16916
16910
|
case "run_shell":
|
|
16917
16911
|
return objectSchema({
|
|
16918
16912
|
command: stringSchema("Shell command."),
|
|
16919
|
-
cwd: stringSchema("Working directory
|
|
16913
|
+
cwd: stringSchema("Working directory, relative to the session directory (the default). Relative paths in the command resolve from here, so artifacts/<name> is the same file save_file writes and the user receives."),
|
|
16920
16914
|
timeout_ms: integerSchema(`Timeout in milliseconds (default 10000, maximum ${maxShellTimeoutMs()}). Pass the real time a long build or download needs; the command is killed at the timeout.`)
|
|
16921
16915
|
}, ["command"]);
|
|
16922
16916
|
case "spawn_subagent":
|
|
@@ -17095,7 +17089,7 @@ async function executeTool(name, args, context) {
|
|
|
17095
17089
|
return ok(await listArtifacts(context.session, optionalString(args.prefix, "prefix") ?? ""));
|
|
17096
17090
|
case "run_shell": {
|
|
17097
17091
|
context.onProgress?.({ type: "running_shell", message: "Running gated shell command" });
|
|
17098
|
-
const result = await runShell(context.session, requiredString(args.command, "command"), optionalString(args.cwd, "cwd") ?? context.session.
|
|
17092
|
+
const result = await runShell(context.session, requiredString(args.command, "command"), optionalString(args.cwd, "cwd") ?? context.session.sessionDir, shellTimeoutMs(args.timeout_ms), { signal: context.signal });
|
|
17099
17093
|
if (result.timed_out || result.exit_code !== 0)
|
|
17100
17094
|
return {
|
|
17101
17095
|
ok: false,
|
|
@@ -59014,8 +59008,8 @@ async function compactContext(session, messages, options) {
|
|
|
59014
59008
|
const dir = await containedPath(session.sessionDir, join13("context", digest));
|
|
59015
59009
|
const path3 = join13(dir, "transcript.jsonl");
|
|
59016
59010
|
await atomicWrite(path3, raw);
|
|
59017
|
-
const archivePath = relative3(session.
|
|
59018
|
-
const ref = (index2) => `${relative3(session.
|
|
59011
|
+
const archivePath = relative3(session.sessionDir, path3).split("\\").join("/");
|
|
59012
|
+
const ref = (index2) => `${relative3(session.sessionDir, dir).split("\\").join("/")}/message-${index2 + 1}.txt`;
|
|
59019
59013
|
const externalize = async (message, index2) => {
|
|
59020
59014
|
await atomicWrite(join13(dir, `message-${index2 + 1}.txt`), messages[index2].content);
|
|
59021
59015
|
return `[Full ${message.role} message saved verbatim to ${ref(index2)}. Use rg/grep and sed/head/tail to read relevant portions before proceeding; do not load the entire file.]`;
|
|
@@ -82486,7 +82480,7 @@ async function runAgentTaskDetailed(session, task, options = {}) {
|
|
|
82486
82480
|
if (options.hosted)
|
|
82487
82481
|
systemPromptParts.push("You operate this service for its owner. Inference and paid tools debit its USDC wallet. When authorized to build or sell a service, take concrete steps within the owner's configured scope and budget. Ask only for missing information or permissions that materially block progress. Report actual costs and outcomes. Financial sustainability is the owner's business objective; respect their stop controls.", "You are a continuous autonomous agent, not a turn-based assistant. Maintain unfinished goals, promised follow-ups, recurring work, and conditions worth monitoring. When future work would clearly help, proactively create a persistent automation instead of waiting for the owner to say schedule. Use a one-time automation for a future reminder or follow-up and a cron automation for monitoring, recurring reports, or maintenance. It runs in this same conversation. Never create duplicates or noisy schedules, and always tell the owner exactly what you created, its timezone, and next run.", "Before finishing a substantive task, consider whether a follow-up, reminder, monitoring loop, recurring report, or maintenance check would materially advance the owner's goal; create one when the need is clear, but do not schedule ordinary one-off work.", "Financial state: the current hosted financial snapshot is authoritative; historical local session budget figures are not wallet balances and may omit inference spending. Wallet balance, pending payment holds, settled inference spend, settled service spend, and remaining run budget are separate. When the snapshot lists wallet networks, each network's balance is separate: a payment on a network needs that network's available balance. Report the wallet to the owner as one total, mentioning the per-network split only when it matters. Spending totals cover only the identified current run. A budget limit does not supply funds. An unavailable balance is unknown, not zero. The snapshot before a model call excludes that call's eventual charge; never claim a response was free or that you spent nothing merely because no paid tool ran. Use get_budget_status or get_wallet_status for refreshed financial state. Respect approval mode and per-call limits; over-limit requests require the owner's approval.");
|
|
82488
82482
|
if (options.hosted)
|
|
82489
|
-
systemPromptParts.push("Files you produce:
|
|
82483
|
+
systemPromptParts.push("Files you produce: only the artifacts/ directory of this session reaches the owner. save_file writes there; anything you write elsewhere is scratch they never see. The owner sees each file at its path without that prefix, so artifacts/generated/report.pdf is generated/report.pdf to them. Name a produced file in your final message by exactly that path as plain text and nothing else \u2014 the owner's interface turns it into a working download and preview link. Never invent a download URL, a sandbox: link, a /mnt/data path, or any other path the owner cannot open, and never claim a file exists before you have verified it.");
|
|
82490
82484
|
if (options.dynamicTools) {
|
|
82491
82485
|
systemPromptParts.push("When the local computer is not the right environment, or after one clear local capability failure, buy external capability: find_paid_service to discover, inspect_paid_service to see the exact schema/price/reputation, call_paid_service to execute through the enforced purchase lifecycle, and review_paid_service for the required review after every confirmed paid call (success or failure). The same review tool accepts unpaid experiences; review relevant free results or failed attempts without inventing payment evidence. Distinguish provider faults from local errors and uncertain failures.", `Choosing a service: find_paid_service with a short capability query (for example "web search" or "object storage", not the task's subject) searches every catalog (AgentCash, Coinbase's x402 catalog, the MPP catalog and CrowdCode's reviews) across Base, Solana and Tempo and returns services you can pay, ranked best first by CrowdCode: quality (score and verified reviews), then effective price on the service's best network, including about $0.03 to move USDC between your own networks when that network's balance is short, then your balance there. Prefer the highest-ranked service that fits the task, whatever its network; a better or cheaper service on Solana or Tempo beats a Base default. When the chosen service is marked transfer_needed, move USDC between your own networks first if you have a tool for that; otherwise tell the user which network needs funds. When the ranking is unavailable, compare candidates yourself with inspect_paid_service (reputation, price and network) against your per-network balances.`, ...options.hosted ? [
|
|
82492
82486
|
"You can use new services without prior CrowdCode reviews. Payable: x402 USDC on Base or Solana and MPP USDC.e on Tempo; the hosted gateway pays the cheapest offered network your balance on that network covers. Other networks, including Monad, are not payable here. Payments stay within the user's configured limits; over-limit quotes request approval. Use read_service for authenticated job polling and never resubmit a pending generation job.",
|
|
@@ -82500,13 +82494,13 @@ async function runAgentTaskDetailed(session, task, options = {}) {
|
|
|
82500
82494
|
systemPromptParts.push("Hosting: you can publish paid HTTP services with deploy_service. Write the entry module with save_file (for example service/index.js) as an ES module with `export default { async fetch(request, env) { ... } }`, with no imports and no npm packages; the Workers runtime provides fetch, Request, Response, URL and crypto.", "The platform enforces payment before your handler runs, so your code only implements the route logic. Vault secrets you list in `secrets` arrive as env.NAME placeholders that are swapped for the real value only on outbound requests to `allowed_hosts`; never log, hash locally, or return a secret, and never build URLs to hosts you did not declare.", "After deploy_service succeeds, report the public URL, the price, and how to call each route.");
|
|
82501
82495
|
}
|
|
82502
82496
|
if (hostedTools.includes("request_secret")) {
|
|
82503
|
-
systemPromptParts.push("Secrets: call request_secret with action=list whenever you need to inspect this agent's available vault secret titles and statuses; values are never returned. When a service needs a new key or token, call it with action=create, a SCREAMING_SNAKE_CASE name, the hosts it may be sent to, and a one-sentence reason. The user adds the value in their own UI; never ask them to paste a secret into chat and never expect to see it. If a requested secret is active, list its name in deploy_service `secrets` and read it as env.NAME; if requested, tell the user what to add and continue or finish without it.");
|
|
82497
|
+
systemPromptParts.push("Buy the capability before asking for the owner's credentials: sending email, SMS or a phone call, publishing, storage, data lookups and similar capabilities are usually purchasable, and you have a wallet. When the task needs one, search for a payable service with find_paid_service and pay for it yourself rather than requesting a personal API key, token or password the owner must go and create. Ask for a secret only when the work genuinely needs the owner's own account or identity \u2014 posting as them, reading their mailbox or calendar, or acting inside a service they already pay for \u2014 or when no payable service covers it, and say which you are doing and why. Never end a run on a secret request while a service you could have paid for would have finished the task.", "Secrets: call request_secret with action=list whenever you need to inspect this agent's available vault secret titles and statuses; values are never returned. When a service needs a new key or token, call it with action=create, a SCREAMING_SNAKE_CASE name, the hosts it may be sent to, and a one-sentence reason. The user adds the value in their own UI; never ask them to paste a secret into chat and never expect to see it. If a requested secret is active, list its name in deploy_service `secrets` and read it as env.NAME; if requested, tell the user what to add and continue or finish without it.");
|
|
82504
82498
|
}
|
|
82505
82499
|
if (hostedTools.includes("vault_request")) {
|
|
82506
82500
|
systemPromptParts.push("Using secrets from chat: call vault_request to send one HTTPS request with a vault secret injected, writing {{SECRET_NAME}} where the value belongs (for example an authorization header). The platform substitutes the real value only for hosts the user approved for that secret, refreshes OAuth tokens automatically, and never returns the value to you. If it reports that a host needs approval, tell the user to allow it in the Vault tab and stop; never look for paid third-party services to do what an approved secret already lets you do. To upload a file (an image or video you rendered with run_shell, where ffmpeg is installed), pass body_artifact with its path under artifacts/ and, for multipart APIs, body_field plus form_fields; files over an API's chunk limit can be split with run_shell first.");
|
|
82507
82501
|
}
|
|
82508
82502
|
if (options.hosted && hostedTools.includes("run_shell")) {
|
|
82509
|
-
systemPromptParts.push("Tooling: ffmpeg, python3 with pip and venv, node and npm are installed; the system image is read-only, but `pip install --user <package>` and `npm install` persist on this machine's volume between runs, so install once and reuse.", "Heavy toolchains: this machine's CPU, memory and disk come from the agent's compute tier, and a multi-gigabyte toolchain needs the heavy tier. Measure before installing one (`df -h \"$HOME\"`, `free -m`, `nproc`) and compare the numbers with what it needs. Install it under `$HOME`: that is the persistent volume and is excluded from the per-run workspace backup, while the session workspace is archived after every run with a 25 MB cap. Give a long download or compile the time it really needs through run_shell `timeout_ms` instead of accepting the 10 s default, redirect build logs to a file under `$HOME` and tail it rather than printing everything, and re-check free space between steps. `No space left on device` or an OOM kill twice means the tier is too small, not that the command was wrong: stop retrying, and tell the owner exactly which limit you hit, how much you need, and that they can switch this agent to the heavy compute tier from Machine in the agent menu (which also raises the shell timeout).", 'Lean 4 and Mathlib, when a task asks for machine-checked proofs: install elan into `$HOME` (`ELAN_HOME="$HOME/.elan" curl -fsSL https://elan.lean-lang.org/elan-init.sh | sh -s -- -y --default-toolchain none`, then source `$HOME/.elan/env`), create or clone the project under `$HOME` so `lake-manifest.json` pins the toolchain, and always run `lake exe cache get` to fetch prebuilt `.olean` files before `lake build` \u2014 compiling Mathlib from source is not viable here. Expect roughly 2 GB for the toolchain, 10 GB for the Mathlib cache, several minutes for `cache get`, and a few GB of memory to elaborate one file that imports Mathlib. Report the compiler\'s real output; a file containing `sorry` is not a proof.', "Resource recovery: before installing large ML dependencies, check available memory, disk space and Python version. A killed install or OOM is a failed approach, not the end of the task. Inspect partial installs and preserve user files, then choose a materially lighter backend or an external service within the user's budget. Verify package metadata: optional extras add dependencies and do not remove default ones; never invent an extra such as basic-pitch[tflite]. For audio-to-MIDI, prefer a verified TFLite or ONNX inference setup in an isolated venv over full TensorFlow; test on a short audio segment before processing the whole file. If no viable path remains, report the concrete blocker and useful artifacts. Do not claim success until the output has been checked.");
|
|
82503
|
+
systemPromptParts.push("Delivering files: run_shell starts in the session directory, so a command that writes artifacts/<name> produces exactly the file save_file would write and the user receives. Treat anything you write elsewhere as scratch the user will not see. Write every deliverable under artifacts/ with its final name before you finish, and name those paths in your answer.", "Tooling: ffmpeg, python3 with pip and venv, node and npm are installed; the system image is read-only, but `pip install --user <package>` and `npm install` persist on this machine's volume between runs, so install once and reuse.", "Heavy toolchains: this machine's CPU, memory and disk come from the agent's compute tier, and a multi-gigabyte toolchain needs the heavy tier. Measure before installing one (`df -h \"$HOME\"`, `free -m`, `nproc`) and compare the numbers with what it needs. Install it under `$HOME`: that is the persistent volume and is excluded from the per-run workspace backup, while the session workspace is archived after every run with a 25 MB cap. Give a long download or compile the time it really needs through run_shell `timeout_ms` instead of accepting the 10 s default, redirect build logs to a file under `$HOME` and tail it rather than printing everything, and re-check free space between steps. `No space left on device` or an OOM kill twice means the tier is too small, not that the command was wrong: stop retrying, and tell the owner exactly which limit you hit, how much you need, and that they can switch this agent to the heavy compute tier from Machine in the agent menu (which also raises the shell timeout).", 'Lean 4 and Mathlib, when a task asks for machine-checked proofs: install elan into `$HOME` (`ELAN_HOME="$HOME/.elan" curl -fsSL https://elan.lean-lang.org/elan-init.sh | sh -s -- -y --default-toolchain none`, then source `$HOME/.elan/env`), create or clone the project under `$HOME` so `lake-manifest.json` pins the toolchain, and always run `lake exe cache get` to fetch prebuilt `.olean` files before `lake build` \u2014 compiling Mathlib from source is not viable here. Expect roughly 2 GB for the toolchain, 10 GB for the Mathlib cache, several minutes for `cache get`, and a few GB of memory to elaborate one file that imports Mathlib. Report the compiler\'s real output; a file containing `sorry` is not a proof.', "Resource recovery: before installing large ML dependencies, check available memory, disk space and Python version. A killed install or OOM is a failed approach, not the end of the task. Inspect partial installs and preserve user files, then choose a materially lighter backend or an external service within the user's budget. Verify package metadata: optional extras add dependencies and do not remove default ones; never invent an extra such as basic-pitch[tflite]. For audio-to-MIDI, prefer a verified TFLite or ONNX inference setup in an isolated venv over full TensorFlow; test on a short audio segment before processing the whole file. If no viable path remains, report the concrete blocker and useful artifacts. Do not claim success until the output has been checked.");
|
|
82510
82504
|
}
|
|
82511
82505
|
systemPromptParts.push("End by calling complete_session with a concise final message.");
|
|
82512
82506
|
if (options.subagent) {
|
package/package.json
CHANGED