norns-sdk 0.1.0 → 0.2.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.
- package/CHANGELOG.md +10 -0
- package/dist/index.cjs +62 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +62 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -626,6 +626,12 @@ interface LlmTask {
|
|
|
626
626
|
summary?: string | null;
|
|
627
627
|
date?: string | null;
|
|
628
628
|
messages?: NeutralMessage[];
|
|
629
|
+
/** In place of `messages` once this worker holds the run's history (see HistoryCache). */
|
|
630
|
+
messages_delta?: {
|
|
631
|
+
base_count: number;
|
|
632
|
+
drop: number;
|
|
633
|
+
append: NeutralMessage[];
|
|
634
|
+
};
|
|
629
635
|
tools?: NeutralTool[];
|
|
630
636
|
context_policy?: unknown;
|
|
631
637
|
max_tokens?: number | null;
|
package/dist/index.d.ts
CHANGED
|
@@ -626,6 +626,12 @@ interface LlmTask {
|
|
|
626
626
|
summary?: string | null;
|
|
627
627
|
date?: string | null;
|
|
628
628
|
messages?: NeutralMessage[];
|
|
629
|
+
/** In place of `messages` once this worker holds the run's history (see HistoryCache). */
|
|
630
|
+
messages_delta?: {
|
|
631
|
+
base_count: number;
|
|
632
|
+
drop: number;
|
|
633
|
+
append: NeutralMessage[];
|
|
634
|
+
};
|
|
629
635
|
tools?: NeutralTool[];
|
|
630
636
|
context_policy?: unknown;
|
|
631
637
|
max_tokens?: number | null;
|
package/dist/index.js
CHANGED
|
@@ -1113,6 +1113,51 @@ function neutralUsage(usage) {
|
|
|
1113
1113
|
return out;
|
|
1114
1114
|
}
|
|
1115
1115
|
|
|
1116
|
+
// src/history-cache.ts
|
|
1117
|
+
var HistoryCache = class {
|
|
1118
|
+
#runs = /* @__PURE__ */ new Map();
|
|
1119
|
+
#maxRuns;
|
|
1120
|
+
constructor(maxRuns = 256) {
|
|
1121
|
+
this.#maxRuns = maxRuns;
|
|
1122
|
+
}
|
|
1123
|
+
/** The task with `messages` filled in, or `undefined` on a miss. */
|
|
1124
|
+
resolve(task) {
|
|
1125
|
+
if (task.purpose === "compact") return task;
|
|
1126
|
+
const runId = task.run_id;
|
|
1127
|
+
const delta = task.messages_delta;
|
|
1128
|
+
if (delta === void 0) {
|
|
1129
|
+
if (runId !== void 0 && Array.isArray(task.messages)) this.#remember(runId, task.messages);
|
|
1130
|
+
return task;
|
|
1131
|
+
}
|
|
1132
|
+
const previous = runId === void 0 ? void 0 : this.#runs.get(runId);
|
|
1133
|
+
if (runId === void 0 || previous === void 0 || previous.length !== delta.base_count) {
|
|
1134
|
+
return void 0;
|
|
1135
|
+
}
|
|
1136
|
+
const messages = [...previous.slice(delta.drop), ...delta.append];
|
|
1137
|
+
this.#remember(runId, messages);
|
|
1138
|
+
const resolved = { ...task, messages };
|
|
1139
|
+
delete resolved.messages_delta;
|
|
1140
|
+
return resolved;
|
|
1141
|
+
}
|
|
1142
|
+
/** Forget everything: a new connection gets the full history anyway. */
|
|
1143
|
+
clear() {
|
|
1144
|
+
this.#runs.clear();
|
|
1145
|
+
}
|
|
1146
|
+
/** How many runs are held; for tests. */
|
|
1147
|
+
get size() {
|
|
1148
|
+
return this.#runs.size;
|
|
1149
|
+
}
|
|
1150
|
+
#remember(runId, messages) {
|
|
1151
|
+
this.#runs.delete(runId);
|
|
1152
|
+
this.#runs.set(runId, messages);
|
|
1153
|
+
while (this.#runs.size > this.#maxRuns) {
|
|
1154
|
+
const oldest = this.#runs.keys().next().value;
|
|
1155
|
+
if (oldest === void 0) break;
|
|
1156
|
+
this.#runs.delete(oldest);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
};
|
|
1160
|
+
|
|
1116
1161
|
// src/worker.ts
|
|
1117
1162
|
var TOPIC = "worker:lobby";
|
|
1118
1163
|
var NornsWorker = class {
|
|
@@ -1133,6 +1178,7 @@ var NornsWorker = class {
|
|
|
1133
1178
|
#client;
|
|
1134
1179
|
#resolveModel;
|
|
1135
1180
|
#inFlight = /* @__PURE__ */ new Set();
|
|
1181
|
+
#history = new HistoryCache();
|
|
1136
1182
|
#state = "idle";
|
|
1137
1183
|
#socket;
|
|
1138
1184
|
#channel;
|
|
@@ -1225,7 +1271,10 @@ var NornsWorker = class {
|
|
|
1225
1271
|
...this.#socketOptions
|
|
1226
1272
|
});
|
|
1227
1273
|
this.#socket = socket;
|
|
1228
|
-
socket.onOpen(() =>
|
|
1274
|
+
socket.onOpen(() => {
|
|
1275
|
+
this.#logger.info(`Connected to ${this.url}`);
|
|
1276
|
+
this.#history.clear();
|
|
1277
|
+
});
|
|
1229
1278
|
socket.onError((err) => {
|
|
1230
1279
|
if (this.#state === "starting" || this.#state === "running") {
|
|
1231
1280
|
this.#logger.warn(`Connection error (${errorMessage(err)}); retrying`);
|
|
@@ -1284,7 +1333,10 @@ var NornsWorker = class {
|
|
|
1284
1333
|
const params = {
|
|
1285
1334
|
worker_id: this.workerId,
|
|
1286
1335
|
tools: [...this.#tools.values()].map(toolRegistration),
|
|
1287
|
-
capabilities: this.#capabilities
|
|
1336
|
+
capabilities: this.#capabilities,
|
|
1337
|
+
// This worker keeps the history it was last sent per run, so Norns may
|
|
1338
|
+
// send later steps as the change only (HistoryCache).
|
|
1339
|
+
features: ["message_cache"]
|
|
1288
1340
|
};
|
|
1289
1341
|
if (this.gard !== void 0) {
|
|
1290
1342
|
params.gard = this.gard;
|
|
@@ -1413,7 +1465,14 @@ var NornsWorker = class {
|
|
|
1413
1465
|
(resp) => this.#logger.warn(`Server rejected result for ${taskId}: ${errorMessage(resp)}`)
|
|
1414
1466
|
);
|
|
1415
1467
|
}
|
|
1416
|
-
async #runLlm(
|
|
1468
|
+
async #runLlm(received, signal) {
|
|
1469
|
+
const task = this.#history.resolve(received);
|
|
1470
|
+
if (task === void 0) {
|
|
1471
|
+
this.#logger.info(
|
|
1472
|
+
"LLM task arrived as a delta on an unknown base; asking for the full history"
|
|
1473
|
+
);
|
|
1474
|
+
return { status: "error", error: "message_cache_miss" };
|
|
1475
|
+
}
|
|
1417
1476
|
const model = task.model ?? "?";
|
|
1418
1477
|
const tools = task.tools ?? [];
|
|
1419
1478
|
this.#logger.info(
|