@cogcoin/client 1.1.0 → 1.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/bitcoind/client/sync-engine.js +1 -1
- package/dist/bitcoind/indexer-daemon-main.js +2 -11
- package/dist/bitcoind/indexer-daemon.js +26 -4
- package/dist/bitcoind/indexer-monitor.js +5 -1
- package/dist/bitcoind/progress/controller.js +4 -1
- package/dist/bitcoind/progress/follow-scene.js +7 -1
- package/dist/cli/context.d.ts +0 -1
- package/dist/cli/context.js +2 -23
- package/dist/package-version.d.ts +1 -0
- package/dist/package-version.js +17 -0
- package/dist/wallet/mining/control.js +18 -3
- package/dist/wallet/mining/runner.d.ts +116 -1
- package/dist/wallet/mining/runner.js +372 -110
- package/dist/wallet/mining/sentences.js +52 -7
- package/dist/wallet/mining/visualizer.d.ts +1 -0
- package/dist/wallet/mining/visualizer.js +13 -0
- package/dist/wallet/read/context.js +5 -1
- package/package.json +1 -1
|
@@ -18,6 +18,14 @@ function createBuiltInProviderNotFoundError(options) {
|
|
|
18
18
|
: `${providerLabel} returned HTTP 404 for model "${options.model}". The configured model override may be invalid. Rerun \`cogcoin mine setup\` to clear or correct it.`;
|
|
19
19
|
return new MiningProviderRequestError("not-found", message);
|
|
20
20
|
}
|
|
21
|
+
function createBuiltInProviderTimeoutError(options) {
|
|
22
|
+
const providerName = options.provider === "anthropic" ? "Anthropic" : "OpenAI";
|
|
23
|
+
const seconds = Number.isInteger(options.timeoutMs / 1_000)
|
|
24
|
+
? String(options.timeoutMs / 1_000)
|
|
25
|
+
: (options.timeoutMs / 1_000).toFixed(1);
|
|
26
|
+
const unit = seconds === "1" ? "second" : "seconds";
|
|
27
|
+
return new MiningProviderRequestError("unavailable", `The built-in ${providerName} mining provider timed out after ${seconds} ${unit}.`);
|
|
28
|
+
}
|
|
21
29
|
function buildSystemPrompt(extraPrompt) {
|
|
22
30
|
const lines = [
|
|
23
31
|
"You are helping generate candidate Cogcoin mining sentences.",
|
|
@@ -70,12 +78,39 @@ function parseProviderJsonResponse(options) {
|
|
|
70
78
|
}
|
|
71
79
|
}
|
|
72
80
|
function createProviderSignal(signal, timeoutMs) {
|
|
73
|
-
const
|
|
74
|
-
|
|
81
|
+
const controller = new AbortController();
|
|
82
|
+
let didTimeout = false;
|
|
83
|
+
const timer = setTimeout(() => {
|
|
84
|
+
didTimeout = true;
|
|
85
|
+
controller.abort(new DOMException("The operation was aborted due to timeout", "TimeoutError"));
|
|
86
|
+
}, timeoutMs);
|
|
87
|
+
timer.unref?.();
|
|
88
|
+
const handleAbort = () => {
|
|
89
|
+
controller.abort(signal?.reason);
|
|
90
|
+
};
|
|
91
|
+
if (signal !== undefined) {
|
|
92
|
+
if (signal.aborted) {
|
|
93
|
+
handleAbort();
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
signal.addEventListener("abort", handleAbort, { once: true });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
signal: controller.signal,
|
|
101
|
+
didTimeout() {
|
|
102
|
+
return didTimeout;
|
|
103
|
+
},
|
|
104
|
+
dispose() {
|
|
105
|
+
clearTimeout(timer);
|
|
106
|
+
signal?.removeEventListener("abort", handleAbort);
|
|
107
|
+
},
|
|
108
|
+
};
|
|
75
109
|
}
|
|
76
110
|
async function requestBuiltInSentences(options) {
|
|
77
111
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
78
|
-
const
|
|
112
|
+
const timeoutMs = Math.min(MINING_BUILTIN_TIMEOUT_MS, options.request.limits.timeoutMs);
|
|
113
|
+
const providerSignal = createProviderSignal(options.signal, timeoutMs);
|
|
79
114
|
try {
|
|
80
115
|
if (options.provider === "openai") {
|
|
81
116
|
const { effectiveModel: model, usingDefaultModel } = resolveBuiltInProviderModel(options.provider, options.modelOverride);
|
|
@@ -98,7 +133,7 @@ async function requestBuiltInSentences(options) {
|
|
|
98
133
|
},
|
|
99
134
|
],
|
|
100
135
|
}),
|
|
101
|
-
signal: providerSignal,
|
|
136
|
+
signal: providerSignal.signal,
|
|
102
137
|
});
|
|
103
138
|
if (response.status === 401 || response.status === 403) {
|
|
104
139
|
throw new MiningProviderRequestError("auth-error", "The built-in OpenAI mining provider rejected the configured API key.");
|
|
@@ -145,7 +180,7 @@ async function requestBuiltInSentences(options) {
|
|
|
145
180
|
},
|
|
146
181
|
],
|
|
147
182
|
}),
|
|
148
|
-
signal: providerSignal,
|
|
183
|
+
signal: providerSignal.signal,
|
|
149
184
|
});
|
|
150
185
|
if (response.status === 401 || response.status === 403) {
|
|
151
186
|
throw new MiningProviderRequestError("auth-error", "The built-in Anthropic mining provider rejected the configured API key.");
|
|
@@ -177,11 +212,21 @@ async function requestBuiltInSentences(options) {
|
|
|
177
212
|
if (error instanceof MiningProviderRequestError) {
|
|
178
213
|
throw error;
|
|
179
214
|
}
|
|
180
|
-
if (
|
|
181
|
-
throw
|
|
215
|
+
if (providerSignal.didTimeout()) {
|
|
216
|
+
throw createBuiltInProviderTimeoutError({
|
|
217
|
+
provider: options.provider,
|
|
218
|
+
timeoutMs,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
if (error instanceof Error
|
|
222
|
+
&& (error.name === "AbortError" || error.name === "TimeoutError")) {
|
|
223
|
+
throw error;
|
|
182
224
|
}
|
|
183
225
|
throw new MiningProviderRequestError("unavailable", error instanceof Error ? error.message : String(error));
|
|
184
226
|
}
|
|
227
|
+
finally {
|
|
228
|
+
providerSignal.dispose();
|
|
229
|
+
}
|
|
185
230
|
}
|
|
186
231
|
function extractOpenAiText(payload) {
|
|
187
232
|
if (payload !== null && typeof payload === "object") {
|
|
@@ -30,6 +30,7 @@ export interface MiningFollowVisualizerState {
|
|
|
30
30
|
settledBoardEntries: MiningSentenceBoardEntry[];
|
|
31
31
|
provisionalRequiredWords: readonly string[];
|
|
32
32
|
provisionalEntry: MiningProvisionalSentenceEntry;
|
|
33
|
+
provisionalBroadcastTxid: string | null;
|
|
33
34
|
latestSentence: string | null;
|
|
34
35
|
latestTxid: string | null;
|
|
35
36
|
recentWin: MiningRecentWinSummary | null;
|
|
@@ -133,6 +133,16 @@ function formatRequiredWordsLine(words) {
|
|
|
133
133
|
}
|
|
134
134
|
return `Required words: ${words.map((word) => word.toUpperCase()).join(", ")}`;
|
|
135
135
|
}
|
|
136
|
+
function formatProvisionalTxLinkLine(entry, txid) {
|
|
137
|
+
if (entry.domainName === null || entry.sentence === null || txid === null) {
|
|
138
|
+
return "";
|
|
139
|
+
}
|
|
140
|
+
const normalizedTxid = normalizeInlineText(txid);
|
|
141
|
+
if (normalizedTxid.length === 0) {
|
|
142
|
+
return "";
|
|
143
|
+
}
|
|
144
|
+
return `View at: https://mempool.space/tx/${normalizedTxid}`;
|
|
145
|
+
}
|
|
136
146
|
function formatProvisionalSentenceRow(entry, requiredWords) {
|
|
137
147
|
if (entry.domainName === null || entry.sentence === null) {
|
|
138
148
|
return ["", "", ""];
|
|
@@ -151,6 +161,7 @@ export function createEmptyMiningFollowVisualizerState() {
|
|
|
151
161
|
domainName: null,
|
|
152
162
|
sentence: null,
|
|
153
163
|
},
|
|
164
|
+
provisionalBroadcastTxid: null,
|
|
154
165
|
latestSentence: null,
|
|
155
166
|
latestTxid: null,
|
|
156
167
|
recentWin: null,
|
|
@@ -173,6 +184,7 @@ function cloneMiningFollowVisualizerState(state) {
|
|
|
173
184
|
provisionalEntry: {
|
|
174
185
|
...state.provisionalEntry,
|
|
175
186
|
},
|
|
187
|
+
provisionalBroadcastTxid: state.provisionalBroadcastTxid,
|
|
176
188
|
recentWin: state.recentWin === null
|
|
177
189
|
? null
|
|
178
190
|
: {
|
|
@@ -375,6 +387,7 @@ export class MiningFollowVisualizer {
|
|
|
375
387
|
: formatSentenceRow(entry);
|
|
376
388
|
}).flat(),
|
|
377
389
|
"----------",
|
|
390
|
+
formatProvisionalTxLinkLine(uiState.provisionalEntry, uiState.provisionalBroadcastTxid),
|
|
378
391
|
formatRequiredWordsLine(uiState.provisionalRequiredWords),
|
|
379
392
|
...formatProvisionalSentenceRow(uiState.provisionalEntry, uiState.provisionalRequiredWords),
|
|
380
393
|
],
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { access, constants } from "node:fs/promises";
|
|
2
2
|
import { deserializeIndexerState, loadBundledGenesisParameters } from "@cogcoin/indexer";
|
|
3
|
+
import { readPackageVersionFromDisk } from "../../package-version.js";
|
|
3
4
|
import { attachOrStartIndexerDaemon, INDEXER_DAEMON_BACKGROUND_FOLLOW_RECOVERY_FAILED, probeIndexerDaemon, readObservedIndexerDaemonStatus, readSnapshotWithRetry, } from "../../bitcoind/indexer-daemon.js";
|
|
4
5
|
import { createRpcClient } from "../../bitcoind/node.js";
|
|
5
6
|
import { UNINITIALIZED_WALLET_ROOT_ID } from "../../bitcoind/service-paths.js";
|
|
@@ -495,6 +496,9 @@ async function readFundingSpendableSats(options) {
|
|
|
495
496
|
}
|
|
496
497
|
}
|
|
497
498
|
export async function openWalletReadContext(options) {
|
|
499
|
+
const expectedIndexerBinaryVersion = options.expectedIndexerBinaryVersion === undefined
|
|
500
|
+
? await readPackageVersionFromDisk()
|
|
501
|
+
: options.expectedIndexerBinaryVersion;
|
|
498
502
|
const startupTimeoutMs = options.startupTimeoutMs ?? DEFAULT_SERVICE_START_TIMEOUT_MS;
|
|
499
503
|
const now = options.now ?? Date.now();
|
|
500
504
|
const localState = await inspectWalletLocalState({
|
|
@@ -545,7 +549,7 @@ export async function openWalletReadContext(options) {
|
|
|
545
549
|
walletRootId,
|
|
546
550
|
startupTimeoutMs,
|
|
547
551
|
ensureBackgroundFollow: true,
|
|
548
|
-
expectedBinaryVersion:
|
|
552
|
+
expectedBinaryVersion: expectedIndexerBinaryVersion,
|
|
549
553
|
});
|
|
550
554
|
}
|
|
551
555
|
else {
|
package/package.json
CHANGED