open-agents-ai 0.184.4 → 0.184.6
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/README.md +65 -0
- package/dist/index.js +104 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -109,6 +109,7 @@ The agent uses tools autonomously in a loop — reading errors, fixing code, and
|
|
|
109
109
|
- **Task templates** — specialized system prompts and tool recommendations for code, document, analysis, plan tasks
|
|
110
110
|
- **Inference capability scoring** — canirun.ai-style hardware assessment at first launch: memory/compute/speed scores, per-model compatibility matrix, recommended model selection
|
|
111
111
|
- **Auto-install everything** — first-run wizard auto-installs Ollama, curl, Python3, python3-venv with platform-aware package managers (apt, dnf, yum, pacman, apk, zypper, brew)
|
|
112
|
+
- **Sponsored inference** — `/sponsor` walks through a 5-step wizard to share your GPU with the world: select endpoints, choose banner animation (8 presets + AI-generated custom), set header message/links, configure transport (cloudflared/libp2p) + rate limits, and go live. Consumers discover sponsors via `/endpoint sponsor`. Secure proxy relay with per-IP rate limiting, daily token budgets, model allowlist, and concurrent request caps. Sponsor's raw API URL is never exposed. See [Sponsored Inference](#sponsored-inference--share-your-gpu-with-the-world) below
|
|
112
113
|
- **P2P inference network** — `/expose` local models or forward any `/endpoint` (Chutes, Groq, OpenRouter, etc.) through the libp2p P2P mesh. Passthrough mode (`/expose passthrough`) relays upstream API requests; `--loadbalance` distributes rate-limited token budgets across peers. `/expose config` provides an arrow-key menu for all settings. Gateway stats show budget remaining from `x-ratelimit-*` headers. Background daemon persists across OA restarts
|
|
113
114
|
- **P2P mesh networking** — `/p2p` with secret-safe variable placeholders (`{{OA_VAR_*}}`), trust tiers (LOCAL/TEE/VERIFIED/PUBLIC), WebSocket peer mesh, and inference routing with automatic secret redaction/injection
|
|
114
115
|
- **Secret vault** — `/secrets` manages API keys and credentials with AES-256-GCM encrypted persistence; secrets are automatically redacted before sending to untrusted inference peers and re-injected on response
|
|
@@ -1446,6 +1447,70 @@ nexus(action='budget_set', auto_approve_below='0.01') # Auto-approve micropayme
|
|
|
1446
1447
|
- All outbound messages scanned for key material before sending
|
|
1447
1448
|
- Keys NEVER appear in tool output, logs, or LLM context
|
|
1448
1449
|
|
|
1450
|
+
## Sponsored Inference — Share Your GPU With the World
|
|
1451
|
+
|
|
1452
|
+
Anyone running Open Agents can become an inference sponsor — sharing their local models (or forwarded cloud endpoints) with users worldwide through a secure, branded relay.
|
|
1453
|
+
|
|
1454
|
+
### For Sponsors: `/sponsor`
|
|
1455
|
+
|
|
1456
|
+
Run `/sponsor` to walk through the 5-step onboarding wizard:
|
|
1457
|
+
|
|
1458
|
+
```
|
|
1459
|
+
Step 1 → Select endpoints (auto-discovers local Ollama models + configured /endpoints)
|
|
1460
|
+
Step 2 → Choose banner animation (8 presets: wave, pulse, matrix, sparkle, radar, circuit, fire)
|
|
1461
|
+
or generate a custom animation with your local LLM
|
|
1462
|
+
Step 3 → Set header message + clickable link (displayed to consumers during inference)
|
|
1463
|
+
Step 4 → Configure transport (cloudflared tunnel and/or libp2p P2P mesh)
|
|
1464
|
+
+ rate limits (req/min, tokens/day, max concurrent, model allowlist)
|
|
1465
|
+
Step 5 → Review and Go Live
|
|
1466
|
+
```
|
|
1467
|
+
|
|
1468
|
+
**What happens under the hood:**
|
|
1469
|
+
- A secure reverse proxy starts on localhost, forwarding to your backend
|
|
1470
|
+
- Bearer token auth gate — unauthenticated requests rejected
|
|
1471
|
+
- Per-IP sliding window rate limiting + global daily token budget
|
|
1472
|
+
- Model allowlist enforcement (block models you don't want to share)
|
|
1473
|
+
- Token usage tracked from both Ollama and OpenAI response formats
|
|
1474
|
+
- Cloudflared tunnel creates a public HTTPS URL (or libp2p for decentralized relay)
|
|
1475
|
+
- Your raw API endpoint URL is **never exposed** — consumers only see the tunnel URL
|
|
1476
|
+
- Config persists to `.oa/sponsor/config.json` — survives restarts
|
|
1477
|
+
|
|
1478
|
+
**Management:**
|
|
1479
|
+
```bash
|
|
1480
|
+
/sponsor # Dashboard (when active) or wizard (when inactive)
|
|
1481
|
+
/sponsor status # Usage metrics: requests, tokens, active connections, unique users
|
|
1482
|
+
/sponsor pause # Stop serving, keep config
|
|
1483
|
+
/sponsor remove # Retire sponsorship entirely
|
|
1484
|
+
```
|
|
1485
|
+
|
|
1486
|
+
### For Consumers: `/endpoint sponsor`
|
|
1487
|
+
|
|
1488
|
+
Users who need inference can discover and connect to sponsors:
|
|
1489
|
+
|
|
1490
|
+
```bash
|
|
1491
|
+
/endpoint sponsor # Browse available sponsored endpoints
|
|
1492
|
+
# Arrow-key select → auto-configures as active endpoint
|
|
1493
|
+
/endpoint <url> --auth <key> # Direct connection with shared credentials
|
|
1494
|
+
```
|
|
1495
|
+
|
|
1496
|
+
When using sponsored inference, the sponsor's banner animation and message appear in your header area.
|
|
1497
|
+
|
|
1498
|
+
### Architecture
|
|
1499
|
+
|
|
1500
|
+
```
|
|
1501
|
+
Consumer OA ──→ Cloudflared Tunnel ──→ Sponsor Proxy ──→ Ollama/vLLM
|
|
1502
|
+
(HTTPS) (auth + rate limit) (local)
|
|
1503
|
+
│
|
|
1504
|
+
├─ Bearer token gate
|
|
1505
|
+
├─ Per-IP sliding window (N req/min)
|
|
1506
|
+
├─ Daily token budget tracking
|
|
1507
|
+
├─ Model allowlist enforcement
|
|
1508
|
+
├─ Concurrent request cap
|
|
1509
|
+
└─ Response header sanitization
|
|
1510
|
+
```
|
|
1511
|
+
|
|
1512
|
+
The tunnel fix uses debounced restarts with exponential cooldown (10s → 20s → 40s), stopping auto-restart after 3 consecutive failures to prevent Cloudflare rate limiting. Progress indicators emit every 5 seconds during startup, and specific error messages are shown for common failure modes (ENOENT, port conflict, 429, DNS).
|
|
1513
|
+
|
|
1449
1514
|
## Dream Mode — Creative Idle Exploration
|
|
1450
1515
|
|
|
1451
1516
|
When you're not actively tasking the agent, Dream Mode lets it creatively explore your codebase and generate improvement proposals autonomously. The system models real human sleep architecture with four stages per cycle:
|
package/dist/index.js
CHANGED
|
@@ -48801,6 +48801,10 @@ async function handleEndpoint(arg, ctx, local = false) {
|
|
|
48801
48801
|
}
|
|
48802
48802
|
return;
|
|
48803
48803
|
}
|
|
48804
|
+
if (arg === "sponsor" || arg === "sponsored") {
|
|
48805
|
+
await handleSponsoredEndpoint(ctx, local);
|
|
48806
|
+
return;
|
|
48807
|
+
}
|
|
48804
48808
|
const normalizedArg = arg.replace(/\u2014/g, "--").replace(/\u2013/g, "--");
|
|
48805
48809
|
const parts = normalizedArg.split(/\s+/);
|
|
48806
48810
|
const url = parts[0];
|
|
@@ -48961,6 +48965,106 @@ async function handleEndpoint(arg, ctx, local = false) {
|
|
|
48961
48965
|
renderWarning(`Could not verify model availability on ${provider.label}. If inference fails, use /model to switch.`);
|
|
48962
48966
|
}
|
|
48963
48967
|
}
|
|
48968
|
+
async function handleSponsoredEndpoint(ctx, local) {
|
|
48969
|
+
process.stdout.write(`
|
|
48970
|
+
${c2.dim("Scanning for sponsored inference endpoints...")}
|
|
48971
|
+
|
|
48972
|
+
`);
|
|
48973
|
+
const sponsors = [];
|
|
48974
|
+
const gateway = ctx.getExposeGateway?.();
|
|
48975
|
+
if (gateway && gateway.isActive && gateway.tunnelUrl) {
|
|
48976
|
+
sponsors.push({
|
|
48977
|
+
name: "Local Gateway",
|
|
48978
|
+
url: gateway.tunnelUrl,
|
|
48979
|
+
authKey: gateway.authKey,
|
|
48980
|
+
models: [],
|
|
48981
|
+
// would need to probe
|
|
48982
|
+
limits: { rpm: 60, tpd: 1e5 },
|
|
48983
|
+
source: "local"
|
|
48984
|
+
});
|
|
48985
|
+
}
|
|
48986
|
+
const sponsorDir2 = join58(ctx.repoRoot ?? process.cwd(), ".oa", "sponsor");
|
|
48987
|
+
const knownFile = join58(sponsorDir2, "known-sponsors.json");
|
|
48988
|
+
try {
|
|
48989
|
+
if (existsSync42(knownFile)) {
|
|
48990
|
+
const saved = JSON.parse(readFileSync31(knownFile, "utf8"));
|
|
48991
|
+
for (const s of saved) {
|
|
48992
|
+
try {
|
|
48993
|
+
const probe = await fetch(`${s.url}/api/tags`, {
|
|
48994
|
+
headers: s.authKey ? { Authorization: `Bearer ${s.authKey}` } : {},
|
|
48995
|
+
signal: AbortSignal.timeout(5e3)
|
|
48996
|
+
});
|
|
48997
|
+
if (probe.ok) {
|
|
48998
|
+
const data = await probe.json();
|
|
48999
|
+
s.models = (data.models || []).map((m) => m.name);
|
|
49000
|
+
sponsors.push(s);
|
|
49001
|
+
}
|
|
49002
|
+
} catch {
|
|
49003
|
+
}
|
|
49004
|
+
}
|
|
49005
|
+
}
|
|
49006
|
+
} catch {
|
|
49007
|
+
}
|
|
49008
|
+
if (sponsors.length === 0) {
|
|
49009
|
+
renderInfo("No sponsored endpoints found.");
|
|
49010
|
+
renderInfo("");
|
|
49011
|
+
renderInfo("To connect to a sponsor, use:");
|
|
49012
|
+
renderInfo(" /endpoint <tunnel-url> --auth <key>");
|
|
49013
|
+
renderInfo("");
|
|
49014
|
+
renderInfo("Or add a known sponsor URL:");
|
|
49015
|
+
renderInfo(" /endpoint sponsor add <url> --auth <key>");
|
|
49016
|
+
return;
|
|
49017
|
+
}
|
|
49018
|
+
const items = [
|
|
49019
|
+
{ key: "hdr", label: "Available Sponsored Endpoints" }
|
|
49020
|
+
];
|
|
49021
|
+
for (const sp of sponsors) {
|
|
49022
|
+
const modelList = sp.models.length > 0 ? sp.models.slice(0, 3).join(", ") + (sp.models.length > 3 ? ` +${sp.models.length - 3}` : "") : "probing...";
|
|
49023
|
+
items.push({
|
|
49024
|
+
key: sp.url,
|
|
49025
|
+
label: ` ${sp.name} (${sp.source})`,
|
|
49026
|
+
detail: ` Models: ${modelList} | ${sp.limits.rpm} req/min, ${sp.limits.tpd >= 1e3 ? (sp.limits.tpd / 1e3).toFixed(0) + "K" : sp.limits.tpd} tokens/day`
|
|
49027
|
+
});
|
|
49028
|
+
}
|
|
49029
|
+
items.push({ key: "sep", label: "" });
|
|
49030
|
+
items.push({ key: "add", label: " + Add sponsor URL manually..." });
|
|
49031
|
+
if (!ctx.rl) {
|
|
49032
|
+
for (const sp of sponsors) {
|
|
49033
|
+
process.stdout.write(` ${sp.name}: ${sp.url}
|
|
49034
|
+
`);
|
|
49035
|
+
}
|
|
49036
|
+
return;
|
|
49037
|
+
}
|
|
49038
|
+
const result = await tuiSelect({
|
|
49039
|
+
items,
|
|
49040
|
+
title: "Sponsored Endpoints",
|
|
49041
|
+
rl: ctx.rl,
|
|
49042
|
+
skipKeys: ["hdr", "sep"],
|
|
49043
|
+
availableRows: ctx.availableContentRows?.()
|
|
49044
|
+
});
|
|
49045
|
+
if (!result.confirmed || !result.key) {
|
|
49046
|
+
renderInfo("Cancelled.");
|
|
49047
|
+
return;
|
|
49048
|
+
}
|
|
49049
|
+
if (result.key === "add") {
|
|
49050
|
+
renderInfo("Use: /endpoint <tunnel-url> --auth <key>");
|
|
49051
|
+
return;
|
|
49052
|
+
}
|
|
49053
|
+
const selected = sponsors.find((s) => s.url === result.key);
|
|
49054
|
+
if (!selected)
|
|
49055
|
+
return;
|
|
49056
|
+
const endpointArg = selected.authKey ? `${selected.url} --auth ${selected.authKey}` : selected.url;
|
|
49057
|
+
await handleEndpoint(endpointArg, ctx, local);
|
|
49058
|
+
try {
|
|
49059
|
+
mkdirSync18(sponsorDir2, { recursive: true });
|
|
49060
|
+
const existing = existsSync42(knownFile) ? JSON.parse(readFileSync31(knownFile, "utf8")) : [];
|
|
49061
|
+
const updated = existing.filter((s) => s.url !== selected.url);
|
|
49062
|
+
updated.push(selected);
|
|
49063
|
+
writeFileSync19(knownFile, JSON.stringify(updated, null, 2), "utf8");
|
|
49064
|
+
} catch {
|
|
49065
|
+
}
|
|
49066
|
+
renderInfo(`Connected to sponsored endpoint: ${selected.name}`);
|
|
49067
|
+
}
|
|
48964
49068
|
async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
48965
49069
|
process.stdout.write(`
|
|
48966
49070
|
${c2.dim("Detected:")} ${c2.bold("libp2p peer")}
|
package/package.json
CHANGED