@genkaku/protocol 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/dist/bridge.d.ts +46 -0
- package/dist/bridge.d.ts.map +1 -0
- package/dist/bridge.js +609 -0
- package/dist/capabilities.d.ts +50 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +66 -0
- package/dist/capabilities.test.d.ts +2 -0
- package/dist/capabilities.test.d.ts.map +1 -0
- package/dist/capabilities.test.js +39 -0
- package/dist/chain.d.ts +496 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +763 -0
- package/dist/credit.d.ts +35 -0
- package/dist/credit.d.ts.map +1 -0
- package/dist/credit.js +112 -0
- package/dist/dial.d.ts +51 -0
- package/dist/dial.d.ts.map +1 -0
- package/dist/dial.js +287 -0
- package/dist/directory.d.ts +39 -0
- package/dist/directory.d.ts.map +1 -0
- package/dist/directory.js +149 -0
- package/dist/discovery.d.ts +20 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +58 -0
- package/dist/hello.d.ts +14 -0
- package/dist/hello.d.ts.map +1 -0
- package/dist/hello.js +42 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/keys.d.ts +30 -0
- package/dist/keys.d.ts.map +1 -0
- package/dist/keys.js +126 -0
- package/dist/llmBridge.d.ts +100 -0
- package/dist/llmBridge.d.ts.map +1 -0
- package/dist/llmBridge.js +284 -0
- package/dist/lp.d.ts +31 -0
- package/dist/lp.d.ts.map +1 -0
- package/dist/lp.js +116 -0
- package/dist/modeManager.d.ts +30 -0
- package/dist/modeManager.d.ts.map +1 -0
- package/dist/modeManager.js +81 -0
- package/dist/netconfig.d.ts +11 -0
- package/dist/netconfig.d.ts.map +1 -0
- package/dist/netconfig.js +39 -0
- package/dist/offer.d.ts +89 -0
- package/dist/offer.d.ts.map +1 -0
- package/dist/offer.js +86 -0
- package/dist/offer.test.d.ts +2 -0
- package/dist/offer.test.d.ts.map +1 -0
- package/dist/offer.test.js +33 -0
- package/dist/ollama.d.ts +53 -0
- package/dist/ollama.d.ts.map +1 -0
- package/dist/ollama.js +162 -0
- package/dist/p2pNode.d.ts +52 -0
- package/dist/p2pNode.d.ts.map +1 -0
- package/dist/p2pNode.js +454 -0
- package/dist/paywall.d.ts +30 -0
- package/dist/paywall.d.ts.map +1 -0
- package/dist/paywall.js +84 -0
- package/dist/publishOptIn.d.ts +15 -0
- package/dist/publishOptIn.d.ts.map +1 -0
- package/dist/publishOptIn.js +34 -0
- package/dist/receipts.d.ts +61 -0
- package/dist/receipts.d.ts.map +1 -0
- package/dist/receipts.js +135 -0
- package/dist/registry.d.ts +19 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +50 -0
- package/dist/rpc.d.ts +24 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +143 -0
- package/dist/status.d.ts +56 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +354 -0
- package/dist/userSession.d.ts +77 -0
- package/dist/userSession.d.ts.map +1 -0
- package/dist/userSession.js +132 -0
- package/dist/workerSession.d.ts +87 -0
- package/dist/workerSession.d.ts.map +1 -0
- package/dist/workerSession.js +97 -0
- package/dist/workerSession.test.d.ts +2 -0
- package/dist/workerSession.test.d.ts.map +1 -0
- package/dist/workerSession.test.js +49 -0
- package/package.json +56 -3
- package/README.md +0 -3
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// GENKAKU: worker session service (mode B/C).
|
|
2
|
+
// One metered worker session: /genkaku/open handshake → stream completion from
|
|
3
|
+
// the local source → token frames out. Settle wiring is P4.4; the receipt side
|
|
4
|
+
// is validated at session end against the receipts the client piped in.
|
|
5
|
+
export function createWorkerSession(envelope, deps) {
|
|
6
|
+
const sessionId = envelope.jobId;
|
|
7
|
+
let tokens = 0;
|
|
8
|
+
let aborted = false;
|
|
9
|
+
return {
|
|
10
|
+
sessionId,
|
|
11
|
+
tokens: () => tokens,
|
|
12
|
+
abort() { aborted = true; },
|
|
13
|
+
async run() {
|
|
14
|
+
const mode = deps.modeManager.current();
|
|
15
|
+
if (!mode.sharingActive) {
|
|
16
|
+
deps.emit({ type: 'session-error', message: 'worker listeners not installed (mode guard)' });
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
deps.emit({ type: 'session-open', sessionId, escrowId: envelope.escrowId, model: envelope.model });
|
|
20
|
+
// Receipts stream IN while the session runs (client pays on a timer in
|
|
21
|
+
// P4.3 time-billing). Each arrival must be strictly increasing — the
|
|
22
|
+
// ledger rejects stale/non-increasing offers (P2 §3).
|
|
23
|
+
let lastSeq = 0;
|
|
24
|
+
const checkReceipts = () => {
|
|
25
|
+
const latest = deps.latestReceipt();
|
|
26
|
+
if (latest == null || latest.seq <= lastSeq) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const verdict = deps.ledger.offer(sessionId, latest.seq, latest.amount);
|
|
30
|
+
if (verdict.accepted) {
|
|
31
|
+
deps.emit({ type: 'receipt-accepted', seq: latest.seq, amount: latest.amount });
|
|
32
|
+
}
|
|
33
|
+
lastSeq = latest.seq;
|
|
34
|
+
};
|
|
35
|
+
checkReceipts();
|
|
36
|
+
const req = {
|
|
37
|
+
model: envelope.model,
|
|
38
|
+
prompt: envelope.prompt,
|
|
39
|
+
system: envelope.system,
|
|
40
|
+
maxTokens: envelope.maxTokens,
|
|
41
|
+
};
|
|
42
|
+
const chat = envelope.proto === 'open/1' ? envelope : null;
|
|
43
|
+
try {
|
|
44
|
+
if (chat != null) {
|
|
45
|
+
if (deps.chatSource == null) {
|
|
46
|
+
throw new Error('worker cannot serve open/1: no chat source configured');
|
|
47
|
+
}
|
|
48
|
+
await deps.chatSource.streamChat({
|
|
49
|
+
model: chat.model,
|
|
50
|
+
messages: chat.messages,
|
|
51
|
+
...(chat.tools === undefined ? {} : { tools: chat.tools }),
|
|
52
|
+
...(chat.maxTokens === undefined ? {} : { maxTokens: chat.maxTokens }),
|
|
53
|
+
}, (event) => {
|
|
54
|
+
if (aborted) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (event.type === 'text') {
|
|
58
|
+
tokens += 1;
|
|
59
|
+
deps.emit({ type: 'token-count', tokens });
|
|
60
|
+
deps.onDelta(event.text);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
deps.onToolCall?.({
|
|
64
|
+
index: event.index,
|
|
65
|
+
id: event.id ?? `call_${event.index}`,
|
|
66
|
+
name: event.name ?? '',
|
|
67
|
+
argumentsDelta: event.argumentsDelta,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
checkReceipts();
|
|
71
|
+
}, deps.abortSignal ?? undefined);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
await deps.source.stream(req, (delta) => {
|
|
75
|
+
if (aborted) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
tokens += 1; // one delta ≈ one token frame from the local source
|
|
79
|
+
deps.emit({ type: 'token-count', tokens });
|
|
80
|
+
deps.onDelta(delta);
|
|
81
|
+
checkReceipts();
|
|
82
|
+
}, deps.abortSignal ?? undefined);
|
|
83
|
+
}
|
|
84
|
+
deps.emit({ type: 'session-end', sessionId, tokens });
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
if (aborted) {
|
|
88
|
+
deps.emit({ type: 'session-end', sessionId, tokens });
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
deps.emit({ type: 'session-error', message: err instanceof Error ? err.message : String(err) });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=workerSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workerSession.test.d.ts","sourceRoot":"","sources":["../src/workerSession.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { test } from 'node:test';
|
|
3
|
+
import { createWorkerSession } from "./workerSession.js";
|
|
4
|
+
const envelope = {
|
|
5
|
+
proto: 'open/1',
|
|
6
|
+
jobId: 'j1',
|
|
7
|
+
escrowId: '0',
|
|
8
|
+
model: 'm',
|
|
9
|
+
prompt: 'hi',
|
|
10
|
+
clientPeer: 'peer',
|
|
11
|
+
messages: [{ role: 'user', content: 'hi' }],
|
|
12
|
+
tools: [{ name: 'read', description: 'read a file', parameters: {} }],
|
|
13
|
+
};
|
|
14
|
+
test('an open/1 session serves chat and relays tool calls', async () => {
|
|
15
|
+
const text = [];
|
|
16
|
+
const calls = [];
|
|
17
|
+
const session = createWorkerSession(envelope, {
|
|
18
|
+
modeManager: { current: () => ({ sharingActive: true }) },
|
|
19
|
+
source: { stream: async () => ({ promptTokens: 0, completionTokens: 0, model: 'm' }) },
|
|
20
|
+
chatSource: {
|
|
21
|
+
async streamChat(_req, onEvent) {
|
|
22
|
+
onEvent({ type: 'text', text: 'let me look' });
|
|
23
|
+
onEvent({ type: 'tool-call', index: 0, name: 'read', argumentsDelta: '{"path":"a"}' });
|
|
24
|
+
return { completionTokens: 3, model: 'm' };
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
ledger: { offer: () => ({ accepted: true }) },
|
|
28
|
+
emit: () => { },
|
|
29
|
+
onDelta: delta => text.push(delta),
|
|
30
|
+
onToolCall: call => calls.push(call),
|
|
31
|
+
latestReceipt: () => null,
|
|
32
|
+
});
|
|
33
|
+
await session.run();
|
|
34
|
+
assert.deepEqual(text, ['let me look']);
|
|
35
|
+
assert.deepEqual(calls, [{ index: 0, id: 'call_0', name: 'read', argumentsDelta: '{"path":"a"}' }]);
|
|
36
|
+
});
|
|
37
|
+
test('an open/1 session without a chat source fails loudly instead of answering empty', async () => {
|
|
38
|
+
const session = createWorkerSession(envelope, {
|
|
39
|
+
modeManager: { current: () => ({ sharingActive: true }) },
|
|
40
|
+
source: { stream: async () => ({ promptTokens: 0, completionTokens: 0, model: 'm' }) },
|
|
41
|
+
ledger: { offer: () => ({ accepted: true }) },
|
|
42
|
+
emit: () => { },
|
|
43
|
+
onDelta: () => { },
|
|
44
|
+
latestReceipt: () => null,
|
|
45
|
+
});
|
|
46
|
+
await session.run();
|
|
47
|
+
assert.equal(session.tokens(), 0);
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=workerSession.test.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genkaku/protocol",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "GenKaKu protocol core: on-chain worker directory, USDC escrow billing, libp2p transport, Ollama lifecycle",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./package.json": "./package.json"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist/**/*.js",
|
|
18
|
+
"dist/**/*.d.ts",
|
|
19
|
+
"dist/**/*.d.ts.map",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@chainsafe/libp2p-noise": "15.1.2",
|
|
25
|
+
"@chainsafe/libp2p-yamux": "6.0.2",
|
|
26
|
+
"@libp2p/crypto": "4.1.9",
|
|
27
|
+
"@libp2p/identify": "2.1.5",
|
|
28
|
+
"@libp2p/peer-id-factory": "4.2.4",
|
|
29
|
+
"@libp2p/tcp": "9.1.6",
|
|
30
|
+
"@multiformats/multiaddr": "12.5.1",
|
|
31
|
+
"libp2p": "1.9.4",
|
|
32
|
+
"viem": "2.57.16"
|
|
33
|
+
},
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/mlaimail77/genkaku-plugin.git",
|
|
37
|
+
"directory": "packages/protocol"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"author": "GenKaKu Labs",
|
|
43
|
+
"homepage": "https://staging.genkaku.app",
|
|
44
|
+
"keywords": [
|
|
45
|
+
"deepseek-harness",
|
|
46
|
+
"dsh",
|
|
47
|
+
"dsh-plugin",
|
|
48
|
+
"p2p",
|
|
49
|
+
"libp2p",
|
|
50
|
+
"ollama",
|
|
51
|
+
"usdc",
|
|
52
|
+
"base"
|
|
53
|
+
],
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsc -p tsconfig.json",
|
|
56
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
57
|
+
"test": "tsc -p tsconfig.json && node --test dist/*.test.js"
|
|
58
|
+
}
|
|
6
59
|
}
|
package/README.md
DELETED