opencrowd 0.13.4 → 0.14.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.
- package/bundle/opencrowd.js +20 -11
- package/package.json +1 -1
package/bundle/opencrowd.js
CHANGED
|
@@ -16885,13 +16885,13 @@ function toolDescription(name) {
|
|
|
16885
16885
|
case "complete_session":
|
|
16886
16886
|
return "Finish the agent run and present a concise final answer.";
|
|
16887
16887
|
case "deploy_service":
|
|
16888
|
-
return "Deploy a paid HTTP service you wrote to
|
|
16888
|
+
return "Deploy a paid HTTP service you wrote to CrowdCode hosting. The entry file is an ES module saved with save_file that exports default { async fetch(request, env) }. Buyers pay per call with x402/MPP and the money goes to this agent's wallet. Fixed price: price_usd. Per-request price: pricing {mode:\"quote\",min_usd,max_usd} and also export quote(request, env), which runs before payment and returns { price_usd } or a 4xx Response to refuse; fetch then runs after payment with env.CROWDCODE.max_charge_atomic and may set response header x-crowdcode-charge-usd to settle less (upto). Optional headers: x-crowdcode-upstream-cost-usd (for margin), x-crowdcode-upstream-balance-usd (triggers top-ups), x-crowdcode-topup: required (refill and retry once). Vault secrets in `secrets` are env.NAME placeholders substituted only on requests to `allowed_hosts`; `raw_secrets` lets code read a value once the owner approves it for this code. `signers` gives env.NAME as a fresh Sign-In-With-X header signed by this agent's wallet for one approved URL. `topup` keeps a prepaid upstream balance refilled from this agent's wallet. Signers, topup and raw_secrets wait for the owner's approval in the services tab. Redeploying a slug updates it in place.";
|
|
16889
16889
|
case "request_secret":
|
|
16890
|
-
return "Use action=list first when you need to see this agent's vault secret titles and statuses (values are never exposed). Use action=create to ask the user to add a named API key or token to the encrypted vault. The user enters the value in their own UI; never ask them to paste a secret into chat.
|
|
16890
|
+
return "Use action=list first when you need to see this agent's vault secret titles and statuses (values are never exposed). Use action=create to ask the user to add a named API key or token to the encrypted vault. The user enters the value in their own UI; never ask them to paste a secret into chat. Use action=store to save a credential you obtained yourself (for example an API key from a sign-up) with name, value, allowed_hosts and reason: it is write-only, you can never read it back, and it cannot replace a secret the user added. Prefer vault_request capture when the key arrives in an API response, so you never see it. Reference an active secret by name in deploy_service `secrets` and read it in service code as env.NAME, or as {{NAME}} in vault_request; the real value is substituted only on requests to allowed_hosts.";
|
|
16891
16891
|
case "vault_request":
|
|
16892
|
-
return "Send one HTTPS request to an external API with vault secrets injected by the platform. Write {{SECRET_NAME}} anywhere in the url, headers, or body and the real value is substituted at the network boundary, only for hosts the user approved for that secret; you never see the value and the response is blocked if it echoes one. Use it to call APIs on the user's behalf (for example posting to X with an OAuth token). The body is a string (JSON, form encoding, or text), or a workspace file up to 25 MB via body_artifact (sent raw, or as one multipart/form-data file part when body_field is set, with form_fields alongside). Returns the status, content-type, and the response body text (truncated at 64 KB). Check request_secret action=list for available secret names first.";
|
|
16892
|
+
return "Send one HTTPS request to an external API with vault secrets injected by the platform. Write {{SECRET_NAME}} anywhere in the url, headers, or body and the real value is substituted at the network boundary, only for hosts the user approved for that secret; you never see the value and the response is blocked if it echoes one. Use it to call APIs on the user's behalf (for example posting to X with an OAuth token). The body is a string (JSON, form encoding, or text), or a workspace file up to 25 MB via body_artifact (sent raw, or as one multipart/form-data file part when body_field is set, with form_fields alongside). Returns the status, content-type, and the response body text (truncated at 64 KB). Check request_secret action=list for available secret names first. Set capture {name, json_path or header} to store a credential from the response (such as the api_key a sign-up returns) in the vault: you get {{NAME}} back in place of the value, usable on the host that issued it.";
|
|
16893
16893
|
case "automations":
|
|
16894
|
-
return "Create, list, update, pause, resume, run now, or delete persistent automations for this hosted agent. Use create proactively when the user's goal clearly needs a future follow-up, reminder, monitoring loop, recurring report, or maintenance task. Automations run in this same conversation. Never create duplicates or hide a schedule from the user.";
|
|
16894
|
+
return "Create, list, update, pause, resume, run now, or delete persistent automations for this hosted agent. Use create proactively when the user's goal clearly needs a future follow-up, reminder, monitoring loop, recurring report, or maintenance task. Automations run in this same conversation. A schedule runs at most every 15 minutes; each run spends at most run_budget_usd (default 0.25) and the schedule at most daily_cap_usd (default 1) per 24 hours. Anything more often than hourly or above $1 a day waits for the owner's approval in the Schedules tab; tell the user. Never create duplicates or hide a schedule from the user.";
|
|
16895
16895
|
}
|
|
16896
16896
|
}
|
|
16897
16897
|
function toolParameters(name) {
|
|
@@ -16934,7 +16934,12 @@ function toolParameters(name) {
|
|
|
16934
16934
|
slug: stringSchema("URL-safe identifier, lowercase letters, digits and dashes, 3-40 characters. Stable across redeploys."),
|
|
16935
16935
|
name: stringSchema("Human-readable service name shown to buyers."),
|
|
16936
16936
|
description: stringSchema("What the service does and returns; used by buyers and discovery search. One or two sentences."),
|
|
16937
|
-
price_usd: stringSchema('
|
|
16937
|
+
price_usd: stringSchema('Fixed price per paid call in USD, for example "0.001". Minimum 0.0001. Omit when pricing.mode is quote.'),
|
|
16938
|
+
pricing: { type: "object", description: 'Per-request pricing: { mode: "quote", min_usd, max_usd }. The module must export quote(request, env). Omit for a fixed price_usd.', additionalProperties: true },
|
|
16939
|
+
networks: { type: "array", description: 'Networks to sell on: base, solana, tempo. Default: all enabled. Use ["base"] when the service pays its costs on Base.', items: stringSchema("Network key.") },
|
|
16940
|
+
signers: { type: "array", description: `Sign-In-With-X as this agent's wallet: [{ name: "VENICE_SIWX", url: "https://api.example.com/v1/chat", statement?: "Sign in to Example" }]. env.NAME is a placeholder for a fresh signed header, valid only for that exact URL; send it as SIGN-IN-WITH-X. The URL's host must be in allowed_hosts. Needs owner approval.`, items: { type: "object", additionalProperties: true } },
|
|
16941
|
+
topup: { type: "object", description: "Prepaid upstream balance kept refilled from this agent's wallet: { url (x402 top-up endpoint), balance_url? (with {address}), balance_field? (e.g. data.balanceUsd), refill_below_usd, amount_usd }. Needs owner approval; the owner sets limits.", additionalProperties: true },
|
|
16942
|
+
raw_secrets: { type: "array", description: "Vault secrets the code must read as values (HMAC signing, OAuth 1.0a). Off until the owner approves them for this exact code; prefer `secrets` placeholders.", items: stringSchema("Vault secret name.") },
|
|
16938
16943
|
entry: stringSchema("Artifact path of the entry module saved with save_file, for example service/index.js."),
|
|
16939
16944
|
routes: {
|
|
16940
16945
|
type: "array",
|
|
@@ -16949,10 +16954,11 @@ function toolParameters(name) {
|
|
|
16949
16954
|
},
|
|
16950
16955
|
secrets: { type: "array", description: "Names of vault secrets the service needs as env vars.", items: stringSchema("Vault secret name.") },
|
|
16951
16956
|
allowed_hosts: { type: "array", description: "Upstream hostnames the service is allowed to call, for example api.coingecko.com. Any other outbound host is blocked.", items: stringSchema("Hostname.") }
|
|
16952
|
-
}, ["slug", "name", "description", "
|
|
16957
|
+
}, ["slug", "name", "description", "entry", "routes"]);
|
|
16953
16958
|
case "request_secret":
|
|
16954
16959
|
return objectSchema({
|
|
16955
|
-
action: { type: "string", description: "list to inspect secret titles/statuses; create to
|
|
16960
|
+
action: { type: "string", description: "list to inspect secret titles/statuses; create to ask the user for a secret; store to save one you obtained yourself." },
|
|
16961
|
+
value: stringSchema("store only: the credential to save. It is write-only from here on."),
|
|
16956
16962
|
name: { type: "string", pattern: "^[A-Z][A-Z0-9_]{1,63}$", description: "Secret name in SCREAMING_SNAKE_CASE, for example OPENAI_API_KEY. This is the env var name your service reads." },
|
|
16957
16963
|
allowed_hosts: { type: "array", description: "Hostnames the secret may be sent to, for example api.openai.com. The vault only substitutes the real value on requests to these hosts.", items: stringSchema("Hostname.") },
|
|
16958
16964
|
reason: stringSchema("One short sentence shown to the user explaining why the secret is needed.")
|
|
@@ -16966,7 +16972,8 @@ function toolParameters(name) {
|
|
|
16966
16972
|
body_artifact: stringSchema("Workspace file to send as the body, as a path under artifacts/ (for example demos/clip.part00). Up to 25 MB; the file is uploaded first."),
|
|
16967
16973
|
body_field: stringSchema("When set, the file is sent as a multipart/form-data part with this field name (for example media) instead of raw bytes."),
|
|
16968
16974
|
form_fields: { type: "object", description: 'Extra multipart text fields sent with the file, for example { "segment_index": "0" }.', additionalProperties: { type: "string" } },
|
|
16969
|
-
reason: stringSchema("One short sentence shown to the user describing what this request does.")
|
|
16975
|
+
reason: stringSchema("One short sentence shown to the user describing what this request does."),
|
|
16976
|
+
capture: { type: "object", description: "Store a credential from the response in the vault: { name, json_path (e.g. data.api_key) or header, allowed_hosts? }. The value is replaced by {{NAME}} in what you receive.", additionalProperties: true }
|
|
16970
16977
|
}, ["url"]);
|
|
16971
16978
|
case "automations":
|
|
16972
16979
|
return automationSchema({ action: { type: "string", description: "create, list, update, pause, resume, run, or delete." }, automation_id: stringSchema("Automation ID, except for create and list.") }, ["action"]);
|
|
@@ -17023,7 +17030,9 @@ function automationSchema(extra, required3 = []) {
|
|
|
17023
17030
|
atTime: stringSchema("ISO 8601 timestamp for a one-time schedule."),
|
|
17024
17031
|
cronExpression: stringSchema("Five-field cron expression, for example 50 19 * * 3."),
|
|
17025
17032
|
timezone: stringSchema("IANA timezone, for example America/Los_Angeles."),
|
|
17026
|
-
model: stringSchema("Optional model ID.")
|
|
17033
|
+
model: stringSchema("Optional model ID."),
|
|
17034
|
+
run_budget_usd: stringSchema(`Most one run may spend in USD, default "0.25"; at most the owner's per-query budget.`),
|
|
17035
|
+
daily_cap_usd: stringSchema(`Most this schedule may spend per 24 hours in USD, default "1". Above 1 needs the owner's approval.`)
|
|
17027
17036
|
}, required3);
|
|
17028
17037
|
}
|
|
17029
17038
|
function objectSchema(properties, required3 = []) {
|
|
@@ -82555,10 +82564,10 @@ async function runAgentTaskDetailed(session, task, options = {}) {
|
|
|
82555
82564
|
}
|
|
82556
82565
|
const hostedTools = options.hosted ? options.tools ?? TOOL_NAMES : [];
|
|
82557
82566
|
if (hostedTools.includes("deploy_service")) {
|
|
82558
|
-
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,
|
|
82567
|
+
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.", `When a call's cost depends on the request (tokens, minutes, rows), use pricing {mode: "quote"} with a quote(request, env) export that refuses impossible requests before payment, and report what was used with x-crowdcode-charge-usd. When the service resells an upstream that needs a wallet signature or a prepaid balance, declare signers and topup instead of asking for keys; the owner approves them in the services tab.`, "After deploy_service succeeds, report the public URL, the price, how to call each route, and anything still waiting for the owner's approval.");
|
|
82559
82568
|
}
|
|
82560
82569
|
if (hostedTools.includes("request_secret")) {
|
|
82561
|
-
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.");
|
|
82570
|
+
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. When you obtain a credential yourself, such as the API key a sign-up returns, keep it: vault_request with capture stores it straight from the response without you seeing it, and request_secret action=store saves one you already hold. Never write a credential into chat, files or code.");
|
|
82562
82571
|
}
|
|
82563
82572
|
if (hostedTools.includes("vault_request")) {
|
|
82564
82573
|
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.");
|
package/package.json
CHANGED