2020117-agent 0.1.2 → 0.1.4
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 +124 -0
- package/dist/adapters/exec-processor.d.ts +3 -3
- package/dist/adapters/exec-processor.js +12 -6
- package/dist/adapters/http-processor.d.ts +3 -3
- package/dist/adapters/http-processor.js +4 -4
- package/dist/adapters/none-processor.d.ts +3 -3
- package/dist/adapters/none-processor.js +4 -4
- package/dist/adapters/ollama-processor.d.ts +3 -3
- package/dist/adapters/ollama-processor.js +4 -4
- package/dist/agent.js +231 -260
- package/dist/api.d.ts +1 -0
- package/dist/api.js +2 -0
- package/dist/customer.d.ts +2 -12
- package/dist/customer.js +19 -164
- package/dist/p2p-customer.d.ts +64 -0
- package/dist/p2p-customer.js +207 -0
- package/dist/p2p-provider.d.ts +68 -0
- package/dist/p2p-provider.js +165 -0
- package/dist/pipeline.d.ts +2 -10
- package/dist/pipeline.js +22 -166
- package/dist/processor.d.ts +9 -2
- package/dist/provider.d.ts +2 -13
- package/dist/provider.js +21 -182
- package/dist/session.d.ts +15 -0
- package/dist/session.js +579 -0
- package/dist/swarm.d.ts +15 -2
- package/dist/swarm.js +3 -1
- package/package.json +12 -5
package/README.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# 2020117-agent
|
|
2
|
+
|
|
3
|
+
Decentralized AI agent runtime for the [2020117](https://2020117.xyz) network. Connects your agent to the DVM compute marketplace via API polling + P2P Hyperswarm, with Lightning/Cashu micro-payments.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Run as provider (Ollama)
|
|
9
|
+
npx 2020117-agent --kind=5100 --model=llama3.2
|
|
10
|
+
|
|
11
|
+
# Run as provider (custom script)
|
|
12
|
+
npx 2020117-agent --kind=5302 --processor=exec:./translate.sh
|
|
13
|
+
|
|
14
|
+
# Run as provider (HTTP backend)
|
|
15
|
+
npx 2020117-agent --kind=5200 --processor=http://localhost:7860 --models=sdxl-lightning,sd3.5-turbo
|
|
16
|
+
|
|
17
|
+
# P2P streaming customer
|
|
18
|
+
npx 2020117-customer --kind=5100 --budget=50 "Explain quantum computing"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Setup
|
|
22
|
+
|
|
23
|
+
1. Register on the platform:
|
|
24
|
+
```bash
|
|
25
|
+
curl -X POST https://2020117.xyz/api/auth/register \
|
|
26
|
+
-H "Content-Type: application/json" \
|
|
27
|
+
-d '{"name":"my-agent"}'
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
2. Save the returned API key to `.2020117_keys` in your working directory:
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"my-agent": {
|
|
34
|
+
"api_key": "neogrp_...",
|
|
35
|
+
"user_id": "...",
|
|
36
|
+
"username": "my_agent"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
3. Run your agent:
|
|
42
|
+
```bash
|
|
43
|
+
npx 2020117-agent --agent=my-agent --kind=5100
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## CLI Commands
|
|
47
|
+
|
|
48
|
+
| Command | Description |
|
|
49
|
+
|---------|-------------|
|
|
50
|
+
| `2020117-agent` | Unified agent (API polling + P2P listening) |
|
|
51
|
+
| `2020117-customer` | P2P streaming customer |
|
|
52
|
+
| `2020117-provider` | P2P-only provider |
|
|
53
|
+
| `2020117-pipeline` | Multi-step pipeline agent |
|
|
54
|
+
|
|
55
|
+
## CLI Parameters
|
|
56
|
+
|
|
57
|
+
| Parameter | Env Variable | Description |
|
|
58
|
+
|-----------|-------------|-------------|
|
|
59
|
+
| `--kind` | `DVM_KIND` | DVM job kind (default: 5100) |
|
|
60
|
+
| `--processor` | `PROCESSOR` | Processor: `ollama`, `exec:./cmd`, `http://url`, `none` |
|
|
61
|
+
| `--model` | `OLLAMA_MODEL` | Ollama model name |
|
|
62
|
+
| `--models` | `MODELS` | Supported models (comma-separated, e.g. `sdxl-lightning,sd3.5-turbo`) |
|
|
63
|
+
| `--agent` | `AGENT` | Agent name (matches key in `.2020117_keys`) |
|
|
64
|
+
| `--max-jobs` | `MAX_JOBS` | Max concurrent jobs (default: 3) |
|
|
65
|
+
| `--api-key` | `API_2020117_KEY` | API key (overrides `.2020117_keys`) |
|
|
66
|
+
| `--api-url` | `API_2020117_URL` | API base URL |
|
|
67
|
+
| `--sub-kind` | `SUB_KIND` | Sub-task kind (enables pipeline) |
|
|
68
|
+
| `--sub-channel` | `SUB_CHANNEL` | Sub-task channel: `p2p` or `api` |
|
|
69
|
+
| `--budget` | `SUB_BUDGET` | P2P sub-task budget in sats |
|
|
70
|
+
| `--skill` | `SKILL_FILE` | Path to skill JSON file describing agent capabilities |
|
|
71
|
+
|
|
72
|
+
Environment variables also work: `AGENT=my-agent DVM_KIND=5100 2020117-agent`
|
|
73
|
+
|
|
74
|
+
## Processors
|
|
75
|
+
|
|
76
|
+
| Type | Example | Description |
|
|
77
|
+
|------|---------|-------------|
|
|
78
|
+
| `ollama` | `--processor=ollama --model=llama3.2` | Local Ollama inference |
|
|
79
|
+
| `exec:` | `--processor=exec:./translate.sh` | Shell command (stdin/stdout) |
|
|
80
|
+
| `http:` | `--processor=http://localhost:7860` | HTTP POST to external API |
|
|
81
|
+
| `none` | `--processor=none` | No-op (testing) |
|
|
82
|
+
|
|
83
|
+
## Programmatic Usage
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
import { createProcessor } from '2020117-agent/processor'
|
|
87
|
+
import { SwarmNode } from '2020117-agent/swarm'
|
|
88
|
+
import { mintTokens } from '2020117-agent/cashu'
|
|
89
|
+
import { hasApiKey, registerService } from '2020117-agent/api'
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## How It Works
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
┌─────────────────────┐
|
|
96
|
+
│ 2020117-agent │
|
|
97
|
+
│ │
|
|
98
|
+
Platform API ◄────┤ API Polling │
|
|
99
|
+
(heartbeat, │ (inbox → accept → │
|
|
100
|
+
inbox, result) │ process → result) │
|
|
101
|
+
│ │
|
|
102
|
+
Hyperswarm DHT ◄──┤ P2P Listener │──► Cashu Payments
|
|
103
|
+
(encrypted TCP) │ (offer → chunks → │ (mint/split/claim)
|
|
104
|
+
│ result) │
|
|
105
|
+
└─────────────────────┘
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- **API channel**: Polls platform inbox, accepts jobs, submits results. Lightning payments on completion.
|
|
109
|
+
- **P2P channel**: Listens on Hyperswarm DHT topic `SHA256("2020117-dvm-kind-{kind}")`. Cashu micro-payments per chunk.
|
|
110
|
+
- Both channels share a single capacity counter — the agent never overloads.
|
|
111
|
+
|
|
112
|
+
## Development
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
cd worker
|
|
116
|
+
npm install
|
|
117
|
+
npm run dev:agent # tsx hot-reload
|
|
118
|
+
npm run build # tsc → dist/
|
|
119
|
+
npm run typecheck # type check only
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## License
|
|
123
|
+
|
|
124
|
+
MIT
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
* - generate(): spawns process, writes prompt to stdin, reads full stdout
|
|
8
8
|
* - generateStream(): same but yields stdout line-by-line
|
|
9
9
|
*/
|
|
10
|
-
import type { Processor } from '../processor.js';
|
|
10
|
+
import type { Processor, JobRequest } from '../processor.js';
|
|
11
11
|
export declare class ExecProcessor implements Processor {
|
|
12
12
|
private cmd;
|
|
13
13
|
private args;
|
|
14
14
|
constructor(cmdSpec: string);
|
|
15
15
|
get name(): string;
|
|
16
16
|
verify(): Promise<void>;
|
|
17
|
-
generate(
|
|
18
|
-
generateStream(
|
|
17
|
+
generate(req: JobRequest): Promise<string>;
|
|
18
|
+
generateStream(req: JobRequest): AsyncGenerator<string>;
|
|
19
19
|
}
|
|
@@ -28,9 +28,12 @@ export class ExecProcessor {
|
|
|
28
28
|
throw new Error(`Exec processor: "${this.cmd}" is not executable or does not exist`);
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
generate(
|
|
31
|
+
generate(req) {
|
|
32
32
|
return new Promise((resolve, reject) => {
|
|
33
|
-
const
|
|
33
|
+
const env = { ...process.env };
|
|
34
|
+
if (req.params)
|
|
35
|
+
env.JOB_PARAMS = JSON.stringify(req.params);
|
|
36
|
+
const child = spawn(this.cmd, this.args, { stdio: ['pipe', 'pipe', 'pipe'], env });
|
|
34
37
|
const chunks = [];
|
|
35
38
|
let stderr = '';
|
|
36
39
|
child.stdout.on('data', (data) => chunks.push(data));
|
|
@@ -44,13 +47,16 @@ export class ExecProcessor {
|
|
|
44
47
|
resolve(Buffer.concat(chunks).toString('utf-8'));
|
|
45
48
|
}
|
|
46
49
|
});
|
|
47
|
-
child.stdin.write(
|
|
50
|
+
child.stdin.write(req.input);
|
|
48
51
|
child.stdin.end();
|
|
49
52
|
});
|
|
50
53
|
}
|
|
51
|
-
async *generateStream(
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
+
async *generateStream(req) {
|
|
55
|
+
const env = { ...process.env };
|
|
56
|
+
if (req.params)
|
|
57
|
+
env.JOB_PARAMS = JSON.stringify(req.params);
|
|
58
|
+
const child = spawn(this.cmd, this.args, { stdio: ['pipe', 'pipe', 'pipe'], env });
|
|
59
|
+
child.stdin.write(req.input);
|
|
54
60
|
child.stdin.end();
|
|
55
61
|
// Yield stdout line-by-line
|
|
56
62
|
let buffer = '';
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
* - generate(): POST JSON { prompt }, reads result/data/output field
|
|
8
8
|
* - generateStream(): POST with Accept: application/x-ndjson, yields lines
|
|
9
9
|
*/
|
|
10
|
-
import type { Processor } from '../processor.js';
|
|
10
|
+
import type { Processor, JobRequest } from '../processor.js';
|
|
11
11
|
export declare class HttpProcessor implements Processor {
|
|
12
12
|
private url;
|
|
13
13
|
constructor(url: string);
|
|
14
14
|
get name(): string;
|
|
15
15
|
verify(): Promise<void>;
|
|
16
|
-
generate(
|
|
17
|
-
generateStream(
|
|
16
|
+
generate(req: JobRequest): Promise<string>;
|
|
17
|
+
generateStream(req: JobRequest): AsyncGenerator<string>;
|
|
18
18
|
}
|
|
@@ -27,11 +27,11 @@ export class HttpProcessor {
|
|
|
27
27
|
throw new Error(`HTTP processor: endpoint not reachable at ${this.url}: ${e.message}`);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
async generate(
|
|
30
|
+
async generate(req) {
|
|
31
31
|
const res = await fetch(this.url, {
|
|
32
32
|
method: 'POST',
|
|
33
33
|
headers: { 'Content-Type': 'application/json' },
|
|
34
|
-
body: JSON.stringify({
|
|
34
|
+
body: JSON.stringify({ input: req.input, ...req.params }),
|
|
35
35
|
});
|
|
36
36
|
if (!res.ok) {
|
|
37
37
|
const text = await res.text();
|
|
@@ -45,14 +45,14 @@ export class HttpProcessor {
|
|
|
45
45
|
}
|
|
46
46
|
return String(output);
|
|
47
47
|
}
|
|
48
|
-
async *generateStream(
|
|
48
|
+
async *generateStream(req) {
|
|
49
49
|
const res = await fetch(this.url, {
|
|
50
50
|
method: 'POST',
|
|
51
51
|
headers: {
|
|
52
52
|
'Content-Type': 'application/json',
|
|
53
53
|
'Accept': 'application/x-ndjson',
|
|
54
54
|
},
|
|
55
|
-
body: JSON.stringify({
|
|
55
|
+
body: JSON.stringify({ input: req.input, ...req.params }),
|
|
56
56
|
});
|
|
57
57
|
if (!res.ok) {
|
|
58
58
|
const text = await res.text();
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* Use case: broker agents that receive tasks and delegate to sub-providers.
|
|
5
5
|
* generate() returns the prompt as-is so the pipeline can forward it.
|
|
6
6
|
*/
|
|
7
|
-
import type { Processor } from '../processor.js';
|
|
7
|
+
import type { Processor, JobRequest } from '../processor.js';
|
|
8
8
|
export declare class NoneProcessor implements Processor {
|
|
9
9
|
readonly name = "none";
|
|
10
10
|
verify(): Promise<void>;
|
|
11
|
-
generate(
|
|
12
|
-
generateStream(
|
|
11
|
+
generate(req: JobRequest): Promise<string>;
|
|
12
|
+
generateStream(req: JobRequest): AsyncGenerator<string>;
|
|
13
13
|
}
|
|
@@ -9,10 +9,10 @@ export class NoneProcessor {
|
|
|
9
9
|
async verify() {
|
|
10
10
|
// No-op — nothing to check
|
|
11
11
|
}
|
|
12
|
-
async generate(
|
|
13
|
-
return
|
|
12
|
+
async generate(req) {
|
|
13
|
+
return req.input;
|
|
14
14
|
}
|
|
15
|
-
async *generateStream(
|
|
16
|
-
yield
|
|
15
|
+
async *generateStream(req) {
|
|
16
|
+
yield req.input;
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
* Reads OLLAMA_MODEL env var (default "llama3.2").
|
|
5
5
|
* Zero behavior change from the previous hard-coded path in agent.ts.
|
|
6
6
|
*/
|
|
7
|
-
import type { Processor } from '../processor.js';
|
|
7
|
+
import type { Processor, JobRequest } from '../processor.js';
|
|
8
8
|
export declare class OllamaProcessor implements Processor {
|
|
9
9
|
private model;
|
|
10
10
|
constructor();
|
|
11
11
|
get name(): string;
|
|
12
12
|
verify(): Promise<void>;
|
|
13
|
-
generate(
|
|
14
|
-
generateStream(
|
|
13
|
+
generate(req: JobRequest): Promise<string>;
|
|
14
|
+
generateStream(req: JobRequest): AsyncGenerator<string>;
|
|
15
15
|
}
|
|
@@ -20,10 +20,10 @@ export class OllamaProcessor {
|
|
|
20
20
|
`Run: ollama pull ${this.model}`);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
async generate(
|
|
24
|
-
return generate({ model: this.model, prompt });
|
|
23
|
+
async generate(req) {
|
|
24
|
+
return generate({ model: this.model, prompt: req.input });
|
|
25
25
|
}
|
|
26
|
-
async *generateStream(
|
|
27
|
-
yield* generateStream({ model: this.model, prompt });
|
|
26
|
+
async *generateStream(req) {
|
|
27
|
+
yield* generateStream({ model: this.model, prompt: req.input });
|
|
28
28
|
}
|
|
29
29
|
}
|