omnicall-agent 0.1.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 (3) hide show
  1. package/README.md +55 -0
  2. package/index.js +136 -0
  3. package/package.json +31 -0
package/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # omnicall-agent
2
+
3
+ **An autonomous AI agent in ~150 lines — with no API keys.** The brain (248 LLMs) and the tools (live web search) are one keyless, pay-per-call endpoint: [Omnicall](https://omnicall.gocreativeai.com). Pay per call in USDC via x402 on Base/Solana, or with a `gck_` credit key. It runs **free out of the box**.
4
+
5
+ ```bash
6
+ npx omnicall-agent "What is the x402 protocol and who is building on it?"
7
+ ```
8
+
9
+ That's it — no OpenAI key, no Anthropic key, no signup. The agent picks a model, searches the web when it needs facts, and answers.
10
+
11
+ ## Why this exists
12
+
13
+ Most "agent starter kits" make you sign up for an LLM provider, paste a key, add a billing card, then wire up a separate search API with *its* key. **omnicall-agent needs none of that.** One endpoint gives an agent every model plus tools, and it pays per call — so you can ship an autonomous agent with zero accounts and pay only for what it actually does.
14
+
15
+ ## Two modes
16
+
17
+ | Mode | Setup | What you get |
18
+ |------|-------|--------------|
19
+ | **Free** | nothing | Single-shot answer on the free tier. Instant. |
20
+ | **Agentic** | `OMNICALL_KEY` | Full reason→search→verify loop over 248 premium models + live web search. |
21
+
22
+ ```bash
23
+ # Free — runs immediately
24
+ npx omnicall-agent "Summarize the latest on agent payments"
25
+
26
+ # Agentic — unlock tools + premium models with a credit key (or x402 wallet)
27
+ export OMNICALL_KEY=gck_your_key # get one at https://omnicall.gocreativeai.com
28
+ npx omnicall-agent "Research USDC stablecoin volume trends and cite sources"
29
+ ```
30
+
31
+ ### Environment
32
+
33
+ | Var | Default | Purpose |
34
+ |-----|---------|---------|
35
+ | `OMNICALL_KEY` | _(none)_ | `gck_` credit key or x402-funded key. Unlocks the agentic loop. |
36
+ | `OMNICALL_MODEL` | `auto` | Model id. `auto` routes to the cheapest capable model. |
37
+ | `OMNICALL_URL` | `https://omnicall.gocreativeai.com` | Gateway base URL. |
38
+
39
+ ## How it works
40
+
41
+ The agent is a simple loop against Omnicall's OpenAI-compatible gateway:
42
+
43
+ 1. Send the goal to a model (`POST /v1/chat/completions`, `model: "auto"`).
44
+ 2. If the model asks to look something up (`SEARCH: <query>`), the agent calls `GET /v1/web/<query>` and feeds the result back.
45
+ 3. Repeat until the model returns a `FINAL:` answer.
46
+
47
+ Every call is metered and paid per-use — no subscription, no idle cost.
48
+
49
+ ## Build your own on the same rails
50
+
51
+ - OpenAI SDK drop-in: `base_url="https://omnicall.gocreativeai.com/v1"`
52
+ - MCP server: `npx -y omnicall-mcp` (or `claude mcp add --transport http omnicall https://omnicall.gocreativeai.com/mcp`)
53
+ - 248 models, image/video/voice/music, and live crypto/markets/web/research — all keyless, all pay-per-call.
54
+
55
+ MIT licensed.
package/index.js ADDED
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env node
2
+ // omnicall-agent — a tiny autonomous research agent that runs entirely on Omnicall.
3
+ // No OpenAI key, no Anthropic key, no signup. The agent's brain (248 LLMs) and its
4
+ // web-search tool are all one keyless, pay-per-call endpoint. Pay per call in USDC
5
+ // via x402, or with a gck_ credit key. Runs free out of the box.
6
+ //
7
+ // npx omnicall-agent "What is the x402 protocol and who uses it?"
8
+ //
9
+ // Optional env:
10
+ // OMNICALL_KEY gck_ credit key (or any x402-funded key) -> unlocks the full
11
+ // agentic loop with live web search + 248 premium models.
12
+ // OMNICALL_MODEL model id (default "auto" -> Omnicall routes to the cheapest capable model)
13
+ // OMNICALL_URL override the gateway (default https://omnicall.gocreativeai.com)
14
+
15
+ const BASE = (process.env.OMNICALL_URL || 'https://omnicall.gocreativeai.com').replace(/\/$/, '');
16
+ const KEY = process.env.OMNICALL_KEY || '';
17
+ const MODEL = process.env.OMNICALL_MODEL || 'auto';
18
+ const MAX_STEPS = 6;
19
+
20
+ const goal = process.argv.slice(2).join(' ').trim();
21
+ if (!goal) {
22
+ console.error('Usage: omnicall-agent "<your question or task>"');
23
+ process.exit(1);
24
+ }
25
+
26
+ const log = (...a) => console.error('\x1b[2m' + a.join(' ') + '\x1b[0m'); // dim, to stderr
27
+
28
+ async function chat(messages) {
29
+ const r = await fetch(`${BASE}/v1/chat/completions`, {
30
+ method: 'POST',
31
+ headers: { 'Content-Type': 'application/json', ...(KEY ? { Authorization: `Bearer ${KEY}` } : {}) },
32
+ body: JSON.stringify({ model: MODEL, messages }),
33
+ });
34
+ if (!r.ok) throw new Error(`gateway ${r.status}: ${(await r.text()).slice(0, 200)}`);
35
+ const j = await r.json();
36
+ return j.choices?.[0]?.message?.content?.trim() || '';
37
+ }
38
+
39
+ // Multi-platform research (web + github + more) condensed into a compact text block.
40
+ async function research(query) {
41
+ try {
42
+ const r = await fetch(`${BASE}/v1/research/${encodeURIComponent(query)}`, {
43
+ headers: KEY ? { Authorization: `Bearer ${KEY}` } : {},
44
+ });
45
+ if (!r.ok) return `(search unavailable: ${r.status})`;
46
+ const j = await r.json();
47
+ const out = [];
48
+ const res = j.results || {};
49
+ const w = res.web || {};
50
+ if (w.answer || w.heading) out.push(`web: ${[w.heading, w.answer].filter(Boolean).join(' — ')}`);
51
+ if (Array.isArray(res.github?.repos)) {
52
+ for (const repo of res.github.repos.slice(0, 5)) {
53
+ out.push(`github: ${repo.name} (${repo.stars}★) — ${repo.description || ''} ${repo.url || ''}`.trim());
54
+ }
55
+ }
56
+ // Fold in any other platform that returned a short answer/title.
57
+ for (const [name, v] of Object.entries(res)) {
58
+ if (name === 'web' || name === 'github' || !v || typeof v !== 'object') continue;
59
+ const snip = v.answer || v.summary || v.title || v.text;
60
+ if (snip) out.push(`${name}: ${String(snip).slice(0, 240)}`);
61
+ }
62
+ return out.length ? out.join('\n').slice(0, 2000) : '(no useful results — answer from your own knowledge)';
63
+ } catch (e) {
64
+ return `(search error: ${e.message})`;
65
+ }
66
+ }
67
+
68
+ // ---- Free, zero-setup mode: single-shot answer on the free tier ----
69
+ async function freeMode() {
70
+ log(`[omnicall-agent] free mode (no key) — answering with the free tier.`);
71
+ const r = await fetch(`${BASE}/v1/ai/free/${encodeURIComponent(goal)}`);
72
+ const j = await r.json();
73
+ console.log('\n' + (j.response || JSON.stringify(j)));
74
+ console.log(
75
+ `\n\x1b[2m— answered free on ${j.model || 'free tier'}. ` +
76
+ `Set OMNICALL_KEY (a gck_ credit key) to unlock live web search + 248 premium models ` +
77
+ `and the full agentic loop. Keyless x402 also works.\x1b[0m`
78
+ );
79
+ }
80
+
81
+ // ---- Full agentic loop: reason + search until done (needs a key) ----
82
+ async function agentMode() {
83
+ log(`[omnicall-agent] agentic mode on ${BASE} (model: ${MODEL}).`);
84
+ const messages = [
85
+ {
86
+ role: 'system',
87
+ content:
88
+ 'You are an autonomous research agent powered by Omnicall. Work step by step toward the user goal. ' +
89
+ 'When you need fresh facts, output ONE line exactly: SEARCH: <query> and nothing else. ' +
90
+ 'You will then receive RESULT: <data>. When you can fully answer, output: FINAL: <answer>. ' +
91
+ 'Prefer to verify with at least one search before a FINAL answer.',
92
+ },
93
+ { role: 'user', content: goal },
94
+ ];
95
+
96
+ let searches = 0;
97
+ const MAX_SEARCHES = 3;
98
+ for (let step = 1; step <= MAX_STEPS; step++) {
99
+ const out = await chat(messages);
100
+ // Strip markdown emphasis/backticks so directives parse even when the model bolds them.
101
+ const clean = out.replace(/[*`]/g, '');
102
+ const searchMatch = clean.match(/SEARCH:\s*(.+)/i);
103
+ const finalMatch = clean.match(/FINAL:\s*([\s\S]+)/i);
104
+
105
+ // Prefer FINAL unless a SEARCH clearly comes first.
106
+ if (finalMatch && (!searchMatch || finalMatch.index <= searchMatch.index)) {
107
+ console.log('\n' + finalMatch[1].trim());
108
+ log(`\n[done in ${step} step(s), ${searches} search(es) — all calls billed per-use on Omnicall]`);
109
+ return;
110
+ }
111
+ if (searchMatch && searches < MAX_SEARCHES) {
112
+ const q = searchMatch[1].trim().replace(/^["']|["']$/g, '');
113
+ searches++;
114
+ log(` → search ${searches}/${MAX_SEARCHES}: ${q}`);
115
+ const result = await research(q);
116
+ messages.push({ role: 'assistant', content: out });
117
+ const nudge =
118
+ searches >= MAX_SEARCHES
119
+ ? ' You have used your last search — answer now with FINAL: <answer>.'
120
+ : '';
121
+ messages.push({ role: 'user', content: `RESULT: ${result}${nudge}` });
122
+ continue;
123
+ }
124
+ // Out of searches, or a plain answer with no directive — wrap up.
125
+ const answer = finalMatch ? finalMatch[1].trim() : clean.replace(/SEARCH:.*/i, '').trim() || out.trim();
126
+ console.log('\n' + answer);
127
+ log(`\n[done in ${step} step(s), ${searches} search(es) — all calls billed per-use on Omnicall]`);
128
+ return;
129
+ }
130
+ log('[reached step limit]');
131
+ }
132
+
133
+ (KEY ? agentMode() : freeMode()).catch((e) => {
134
+ console.error('\x1b[31m' + e.message + '\x1b[0m');
135
+ process.exit(1);
136
+ });
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "omnicall-agent",
3
+ "version": "0.1.0",
4
+ "description": "A tiny autonomous research agent that runs entirely on Omnicall — 248 LLMs + live web search through one keyless, pay-per-call endpoint. No OpenAI/Anthropic key, no signup.",
5
+ "bin": {
6
+ "omnicall-agent": "index.js"
7
+ },
8
+ "type": "commonjs",
9
+ "engines": {
10
+ "node": ">=18"
11
+ },
12
+ "keywords": [
13
+ "ai-agent",
14
+ "autonomous-agent",
15
+ "omnicall",
16
+ "x402",
17
+ "pay-per-call",
18
+ "llm",
19
+ "openai-compatible",
20
+ "agent",
21
+ "keyless",
22
+ "blockrun-alternative"
23
+ ],
24
+ "homepage": "https://omnicall.gocreativeai.com",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/ColinHughes2121/omnicall-agent.git"
28
+ },
29
+ "license": "MIT",
30
+ "author": "GoCreative AI"
31
+ }