@genkaku/dsh-runtime 0.1.0 → 0.1.2

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/dist/runtime.d.ts CHANGED
@@ -53,6 +53,10 @@ export interface Config {
53
53
  spawnOllama: boolean;
54
54
  /** local Ollama base URL */
55
55
  ollamaHost: string;
56
+ /** Offer every local model at the default price when the catalog is empty. */
57
+ autoCatalog: boolean;
58
+ /** 6-decimal USDC per hour for auto-listed models. */
59
+ defaultPricePerHour: string;
56
60
  }
57
61
  /** Validated plugin configuration. */
58
62
  export declare const Config: z<Schemastery.ObjectS<NoInfer<{
@@ -78,6 +82,14 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
78
82
  sessionsServed: z<number, number, "defined">;
79
83
  maxConcurrent: z<number, number, "plain">;
80
84
  }>>[], "defined">;
85
+ /**
86
+ * When the catalog is empty, offer every model Ollama already has at
87
+ * `defaultPricePerHour`. Without this a fresh worker starts with nothing on
88
+ * the board, which reads as "the plugin does nothing".
89
+ */
90
+ autoCatalog: z<boolean, boolean, "defined">;
91
+ /** 6-decimal USDC per hour used by autoCatalog entries. Default 6 USDC. */
92
+ defaultPricePerHour: z<string, string, "defined">;
81
93
  listen: z<string[], string[], "defined">;
82
94
  publishAddress: z<boolean, boolean, "defined">;
83
95
  workerName: z<string, string, "defined">;
@@ -106,6 +118,14 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
106
118
  sessionsServed: z<number, number, "defined">;
107
119
  maxConcurrent: z<number, number, "plain">;
108
120
  }>>[], "defined">;
121
+ /**
122
+ * When the catalog is empty, offer every model Ollama already has at
123
+ * `defaultPricePerHour`. Without this a fresh worker starts with nothing on
124
+ * the board, which reads as "the plugin does nothing".
125
+ */
126
+ autoCatalog: z<boolean, boolean, "defined">;
127
+ /** 6-decimal USDC per hour used by autoCatalog entries. Default 6 USDC. */
128
+ defaultPricePerHour: z<string, string, "defined">;
109
129
  listen: z<string[], string[], "defined">;
110
130
  publishAddress: z<boolean, boolean, "defined">;
111
131
  workerName: z<string, string, "defined">;
@@ -133,9 +153,13 @@ export declare function defineGenkakuPlugin(options: {
133
153
  pluginName: string;
134
154
  settingsNs: string;
135
155
  role?: RoleMode;
156
+ /** Extra cordis services the adapter half needs (e.g. `llm`). */
157
+ injectExtra?: readonly string[];
158
+ /** Runs once the runtime is up; where an adapter registers its own services. */
159
+ onStarted?: (ctx: Context, config: Config) => void;
136
160
  }): {
137
161
  name: string;
138
- inject: readonly ["settings"];
162
+ inject: readonly string[];
139
163
  Config: z<Schemastery.ObjectS<NoInfer<{
140
164
  mode: z<"user" | "localPlusSharing" | "workerDedicated", "user" | "localPlusSharing" | "workerDedicated", "volatile-defined">;
141
165
  env: z<"base-sepolia" | "base", "base-sepolia" | "base", "defined">;
@@ -159,6 +183,14 @@ export declare function defineGenkakuPlugin(options: {
159
183
  sessionsServed: z<number, number, "defined">;
160
184
  maxConcurrent: z<number, number, "plain">;
161
185
  }>>[], "defined">;
186
+ /**
187
+ * When the catalog is empty, offer every model Ollama already has at
188
+ * `defaultPricePerHour`. Without this a fresh worker starts with nothing on
189
+ * the board, which reads as "the plugin does nothing".
190
+ */
191
+ autoCatalog: z<boolean, boolean, "defined">;
192
+ /** 6-decimal USDC per hour used by autoCatalog entries. Default 6 USDC. */
193
+ defaultPricePerHour: z<string, string, "defined">;
162
194
  listen: z<string[], string[], "defined">;
163
195
  publishAddress: z<boolean, boolean, "defined">;
164
196
  workerName: z<string, string, "defined">;
@@ -187,6 +219,14 @@ export declare function defineGenkakuPlugin(options: {
187
219
  sessionsServed: z<number, number, "defined">;
188
220
  maxConcurrent: z<number, number, "plain">;
189
221
  }>>[], "defined">;
222
+ /**
223
+ * When the catalog is empty, offer every model Ollama already has at
224
+ * `defaultPricePerHour`. Without this a fresh worker starts with nothing on
225
+ * the board, which reads as "the plugin does nothing".
226
+ */
227
+ autoCatalog: z<boolean, boolean, "defined">;
228
+ /** 6-decimal USDC per hour used by autoCatalog entries. Default 6 USDC. */
229
+ defaultPricePerHour: z<string, string, "defined">;
190
230
  listen: z<string[], string[], "defined">;
191
231
  publishAddress: z<boolean, boolean, "defined">;
192
232
  workerName: z<string, string, "defined">;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
package/dist/runtime.js CHANGED
@@ -12,7 +12,7 @@ import { advertiseWorker, deactivateWorker, hasPublicAddr, locatorOf, publicClie
12
12
  import { fetchSeedPeers } from '@genkaku/protocol';
13
13
  import { loadDirectory, syncDirectory, workerAddrs } from '@genkaku/protocol';
14
14
  import { createKeyVault } from '@genkaku/protocol';
15
- import { createOllamaSource } from '@genkaku/protocol';
15
+ import { announceToSeed, createOllamaChatSource, createOllamaSource, probeModels } from '@genkaku/protocol';
16
16
  import { createOllamaSupervisor } from '@genkaku/protocol';
17
17
  import { ModeManager } from '@genkaku/protocol';
18
18
  import { probeRpc } from '@genkaku/protocol';
@@ -45,6 +45,14 @@ export const Config = z.object({
45
45
  paywall: z.boolean().default(true),
46
46
  keyDir: z.string().min(1).default(join(homedir(), '.dsh', 'genkaku')),
47
47
  catalog: z.array(catalogEntry).default([]),
48
+ /**
49
+ * When the catalog is empty, offer every model Ollama already has at
50
+ * `defaultPricePerHour`. Without this a fresh worker starts with nothing on
51
+ * the board, which reads as "the plugin does nothing".
52
+ */
53
+ autoCatalog: z.boolean().default(true),
54
+ /** 6-decimal USDC per hour used by autoCatalog entries. Default 6 USDC. */
55
+ defaultPricePerHour: z.string().pattern(/^\d+$/).default('6000000'),
48
56
  // IPv4 and IPv6 need separate binds (a /ip6/::/ bind is v6-only), and a
49
57
  // global IPv6 address means a directly dialable worker with no NAT at all —
50
58
  // the cheapest way for a dorm/public-wifi peer to be reachable (P4.9j).
@@ -72,7 +80,7 @@ export const Config = z.object({
72
80
  * @param options.role - serving or consuming; overrides any stored mode.
73
81
  */
74
82
  export function defineGenkakuPlugin(options) {
75
- const { pluginName, settingsNs, role } = options;
83
+ const { pluginName, settingsNs, role, injectExtra = [], onStarted } = options;
76
84
  async function apply(ctx, config) {
77
85
  ctx.inject(['settings'], (child) => { child.effect(() => child.settings.configure({ auto: false }, ctx.fiber)); });
78
86
  const log = ctx.logger(pluginName);
@@ -102,8 +110,14 @@ export function defineGenkakuPlugin(options) {
102
110
  // Startup is complete, so the disposer body stays synchronous: it returns
103
111
  // the async teardown for Cordis to await at unload.
104
112
  ctx.effect(() => () => runtime.dispose(), `${pluginName}: bridge and sidecar lifecycle`);
113
+ onStarted?.(ctx, config);
105
114
  }
106
- return { name: pluginName, inject: ['settings'], Config, apply };
115
+ return {
116
+ name: pluginName,
117
+ inject: ['settings', ...injectExtra],
118
+ Config,
119
+ apply,
120
+ };
107
121
  }
108
122
  /** Owns the running halves so the mode starter and teardown share one state. */
109
123
  export class GenkakuRuntime {
@@ -351,6 +365,28 @@ export class GenkakuRuntime {
351
365
  const workerKey = this.vault.workerKey();
352
366
  const workerWallet = this.vault.addresses().worker;
353
367
  let workerCatalog = loadCatalog(this.keyDir, this.config.catalog, this.log);
368
+ // First run: an empty board looks broken to the person who just installed
369
+ // the plugin. Advertise what Ollama already has, at a stated default price,
370
+ // and let the panel adjust it afterwards.
371
+ if (workerCatalog.length === 0 && this.config.autoCatalog) {
372
+ try {
373
+ const profiles = await probeModels(this.config.ollamaHost);
374
+ workerCatalog = profiles.map(profile => ({
375
+ model: profile.model,
376
+ pricePerHour: this.config.defaultPricePerHour,
377
+ }));
378
+ if (workerCatalog.length > 0) {
379
+ persistCatalog(this.keyDir, workerCatalog, this.log);
380
+ this.log.info('catalog: empty — auto-listed %d local model(s) at %s per hour', workerCatalog.length, this.config.defaultPricePerHour);
381
+ }
382
+ else {
383
+ this.log.warn('catalog: empty and Ollama has no models; run `ollama pull` to serve one');
384
+ }
385
+ }
386
+ catch (error) {
387
+ this.log.warn('catalog: auto-list failed (%s) — set catalog in settings', error instanceof Error ? error.message : String(error));
388
+ }
389
+ }
354
390
  const paywall = this.config.paywall
355
391
  ? createPaywall({
356
392
  publicC: publicClientFor(this.config.env),
@@ -366,6 +402,8 @@ export class GenkakuRuntime {
366
402
  paywall,
367
403
  modeManager: this.modeManager,
368
404
  source: createOllamaSource(this.config.ollamaHost),
405
+ // Serves open/1 sessions: chat messages plus tool schemas.
406
+ chatSource: createOllamaChatSource(this.config.ollamaHost),
369
407
  listen: this.config.listen,
370
408
  catalog: catalogOf(this.config.workerName, workerCatalog),
371
409
  workerKey,
@@ -431,6 +469,22 @@ export class GenkakuRuntime {
431
469
  };
432
470
  this.startAdvertiseWatch();
433
471
  this.log.info('worker %s listening on %s', sidecar.peerIdStr(), sidecar.peerAddrs().join(', '));
472
+ // Announce to the configured seeds so a cold client can find this worker
473
+ // without already knowing its multiaddr.
474
+ if (HARDCODED_SEEDS.length > 0) {
475
+ for (const seed of HARDCODED_SEEDS) {
476
+ void announceToSeed(sidecar.node, seed, sidecar.peerAddrs())
477
+ .then((ok) => {
478
+ if (ok)
479
+ this.log.info('announced to seed %s', seed);
480
+ else
481
+ this.log.warn('seed %s did not accept the announcement', seed);
482
+ })
483
+ .catch((error) => {
484
+ this.log.warn('announce to %s failed (%s)', seed, error instanceof Error ? error.message : String(error));
485
+ });
486
+ }
487
+ }
434
488
  this.log.info('worker dashboard at %s', this.statusServer.url);
435
489
  this.stop = sidecar.stop;
436
490
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genkaku/dsh-runtime",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "DeepSeek Harness adapter layer for the GenKaKu protocol runtime",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -23,7 +23,7 @@
23
23
  "dependencies": {
24
24
  "@deepseek-ai/cosmokit": "1.9.0",
25
25
  "@deepseek-ai/schemastery": "^3.19.0",
26
- "@genkaku/protocol": "0.1.0"
26
+ "@genkaku/protocol": "0.1.2"
27
27
  },
28
28
  "peerDependencies": {
29
29
  "@deepseek-ai/cordis": "^4.1.0",