@dan-ai-studio/dshopencodego 0.1.74 → 0.1.76
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/lib/index.js +68 -45
- package/lib/types/config.d.ts +14 -0
- package/lib/types/index.d.ts +1 -1
- package/package.json +25 -25
package/lib/index.js
CHANGED
|
@@ -73672,7 +73672,7 @@ import dc from "node:diagnostics_channel";
|
|
|
73672
73672
|
import { credentialRef } from "@deepseek-ai/dsh-credentials";
|
|
73673
73673
|
import { launchEnvironmentOf } from "@deepseek-ai/dsh-launch-environment";
|
|
73674
73674
|
import * as llm2 from "@deepseek-ai/dsh-llm";
|
|
73675
|
-
import { LlmError as
|
|
73675
|
+
import { LlmError as LlmError13 } from "@deepseek-ai/dsh-llm";
|
|
73676
73676
|
|
|
73677
73677
|
// src/adapter.ts
|
|
73678
73678
|
init_models();
|
|
@@ -73682,7 +73682,7 @@ import {
|
|
|
73682
73682
|
contentHasImage as contentHasImage2,
|
|
73683
73683
|
isTokenDelta,
|
|
73684
73684
|
LlmAdapter,
|
|
73685
|
-
LlmError as
|
|
73685
|
+
LlmError as LlmError9,
|
|
73686
73686
|
ReasoningEffortId,
|
|
73687
73687
|
resolveRetryPolicy
|
|
73688
73688
|
} from "@deepseek-ai/dsh-llm";
|
|
@@ -74973,7 +74973,7 @@ async function discoverCatalogModels(catalog, signal) {
|
|
|
74973
74973
|
}
|
|
74974
74974
|
|
|
74975
74975
|
// src/config.ts
|
|
74976
|
-
import { RetryPolicySchema } from "@deepseek-ai/dsh-llm";
|
|
74976
|
+
import { LlmError as LlmError5, RetryPolicySchema } from "@deepseek-ai/dsh-llm";
|
|
74977
74977
|
import { MAX_TIMER_DELAY_MS } from "@deepseek-ai/dsh-timeout";
|
|
74978
74978
|
|
|
74979
74979
|
// node_modules/@deepseek-ai/cosmokit/lib/index.js
|
|
@@ -75890,6 +75890,14 @@ var PlainConfig = Schema.object(fields);
|
|
|
75890
75890
|
var Config = Schema.object(Object.fromEntries(
|
|
75891
75891
|
Object.entries(fields).map(([key, schema]) => [key, schema.volatile()])
|
|
75892
75892
|
));
|
|
75893
|
+
function assertStreamIdleTimeoutMs(value) {
|
|
75894
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0 || value > MAX_TIMER_DELAY_MS) {
|
|
75895
|
+
throw new LlmError5(
|
|
75896
|
+
`dshopencodego: streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`,
|
|
75897
|
+
"INVALID_CONFIG"
|
|
75898
|
+
);
|
|
75899
|
+
}
|
|
75900
|
+
}
|
|
75893
75901
|
function readConfig(config) {
|
|
75894
75902
|
return Object.fromEntries(Object.keys(fields).flatMap((key) => {
|
|
75895
75903
|
const field = config[key];
|
|
@@ -75921,11 +75929,11 @@ function assertBaseURL(raw) {
|
|
|
75921
75929
|
// src/conversion/context.ts
|
|
75922
75930
|
import { brandString } from "@deepseek-ai/dsh-brand";
|
|
75923
75931
|
import * as llm from "@deepseek-ai/dsh-llm";
|
|
75924
|
-
import { contentHasImage, LlmError as
|
|
75932
|
+
import { contentHasImage, LlmError as LlmError7, requestImageHandleText } from "@deepseek-ai/dsh-llm";
|
|
75925
75933
|
import { requestImageDimensions } from "@deepseek-ai/dsh-attachment";
|
|
75926
75934
|
|
|
75927
75935
|
// src/conversion/replay.ts
|
|
75928
|
-
import { LlmError as
|
|
75936
|
+
import { LlmError as LlmError6 } from "@deepseek-ai/dsh-llm";
|
|
75929
75937
|
var REPLAYABLE_STOP_REASONS = ["stop", "length", "toolUse", "error", "aborted"];
|
|
75930
75938
|
function replayableStopReason(stopReason) {
|
|
75931
75939
|
return REPLAYABLE_STOP_REASONS.includes(stopReason) ? stopReason : "error";
|
|
@@ -75988,7 +75996,7 @@ function toPiReplayState(message, requestedModel = message.model) {
|
|
|
75988
75996
|
};
|
|
75989
75997
|
}
|
|
75990
75998
|
function invalidReplay(message) {
|
|
75991
|
-
throw new
|
|
75999
|
+
throw new LlmError6(`invalid pi-ai replay state: ${message}`, "INVALID_REPLAY_STATE");
|
|
75992
76000
|
}
|
|
75993
76001
|
function readReplayState(value) {
|
|
75994
76002
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return invalidReplay("expected a replay envelope");
|
|
@@ -76048,7 +76056,7 @@ function foreignAssistant(message) {
|
|
|
76048
76056
|
});
|
|
76049
76057
|
break;
|
|
76050
76058
|
case "image":
|
|
76051
|
-
throw new
|
|
76059
|
+
throw new LlmError6("pi-ai chat history cannot represent structured assistant image output", "UNSUPPORTED_CONTENT");
|
|
76052
76060
|
default:
|
|
76053
76061
|
break;
|
|
76054
76062
|
}
|
|
@@ -76122,7 +76130,7 @@ function toPiAssistant(message, onDegrade) {
|
|
|
76122
76130
|
try {
|
|
76123
76131
|
return replayedAssistant(message, source, source.replayState);
|
|
76124
76132
|
} catch (error) {
|
|
76125
|
-
if (!(error instanceof
|
|
76133
|
+
if (!(error instanceof LlmError6) || error.code !== "INVALID_REPLAY_STATE") throw error;
|
|
76126
76134
|
onDegrade?.(error.message);
|
|
76127
76135
|
return foreignAssistant(message);
|
|
76128
76136
|
}
|
|
@@ -76138,7 +76146,7 @@ function toolMessage(message) {
|
|
|
76138
76146
|
function assertSupportedImageRoles(messages) {
|
|
76139
76147
|
for (const message of messages) {
|
|
76140
76148
|
if (message.role !== "user" && toolMessage(message) === void 0 && contentHasImage(message.content)) {
|
|
76141
|
-
throw new
|
|
76149
|
+
throw new LlmError7(`pi-ai cannot represent an image in an in-history ${message.role} message`, "UNSUPPORTED_CONTENT");
|
|
76142
76150
|
}
|
|
76143
76151
|
}
|
|
76144
76152
|
}
|
|
@@ -76186,7 +76194,7 @@ async function userContent(blocks, requestImages, resolveImageAccess) {
|
|
|
76186
76194
|
if (block.type === "image") {
|
|
76187
76195
|
const version = requestImages.get(block.attachment.attachmentId);
|
|
76188
76196
|
if (version === void 0) {
|
|
76189
|
-
throw new
|
|
76197
|
+
throw new LlmError7(
|
|
76190
76198
|
"dshopencodego: an image in this request has no prepared bytes; image input requires the attachment service",
|
|
76191
76199
|
"UNSUPPORTED_CONTENT"
|
|
76192
76200
|
);
|
|
@@ -76210,7 +76218,7 @@ function projectImagesForRequest(messages, images, requestImages) {
|
|
|
76210
76218
|
(block) => requestImages.get(block.attachment.attachmentId).bytes
|
|
76211
76219
|
);
|
|
76212
76220
|
if (over > 0) {
|
|
76213
|
-
throw new
|
|
76221
|
+
throw new LlmError7(
|
|
76214
76222
|
`request images exceed the ${images.maxRequestImageBytes}-byte base64 bound; ${over} more oldest occurrence(s) must be offloaded`,
|
|
76215
76223
|
llm.IMAGE_OFFLOAD_REQUIRED_CODE,
|
|
76216
76224
|
{ offloadImages: over }
|
|
@@ -76243,7 +76251,13 @@ async function toPiContext(options, images, onReplayDegrade) {
|
|
|
76243
76251
|
continue;
|
|
76244
76252
|
}
|
|
76245
76253
|
if (message.role === "system") {
|
|
76246
|
-
|
|
76254
|
+
const text2 = flattenText(message);
|
|
76255
|
+
if (text2.length > 0) {
|
|
76256
|
+
const reminder = text2.replaceAll("</system-reminder>", "<\\/system-reminder>");
|
|
76257
|
+
messages.push({ role: "user", content: `<system-reminder>
|
|
76258
|
+
${reminder}
|
|
76259
|
+
</system-reminder>`, timestamp: 0 });
|
|
76260
|
+
}
|
|
76247
76261
|
continue;
|
|
76248
76262
|
}
|
|
76249
76263
|
if (message.role === "assistant") {
|
|
@@ -76272,7 +76286,7 @@ import {
|
|
|
76272
76286
|
EMPTY_RESPONSE_CODE,
|
|
76273
76287
|
isContextWindowExceededError,
|
|
76274
76288
|
isQuotaExceededError,
|
|
76275
|
-
LlmError as
|
|
76289
|
+
LlmError as LlmError8
|
|
76276
76290
|
} from "@deepseek-ai/dsh-llm";
|
|
76277
76291
|
|
|
76278
76292
|
// node_modules/@earendil-works/pi-ai/dist/utils/overflow.js
|
|
@@ -76520,7 +76534,7 @@ async function* toStreamChunks(events, contextWindow, callerSignal, requestedMod
|
|
|
76520
76534
|
return;
|
|
76521
76535
|
}
|
|
76522
76536
|
}
|
|
76523
|
-
throw new
|
|
76537
|
+
throw new LlmError8("pi-ai event stream ended without a terminal event", "STREAM_CLOSED");
|
|
76524
76538
|
}
|
|
76525
76539
|
|
|
76526
76540
|
// src/go-limits.ts
|
|
@@ -76723,7 +76737,7 @@ function withModelLimit(model, limits) {
|
|
|
76723
76737
|
function stopSequencesFor(model, stop) {
|
|
76724
76738
|
if (stop === void 0) return void 0;
|
|
76725
76739
|
if (model.api === "openai-completions") return stop;
|
|
76726
|
-
throw new
|
|
76740
|
+
throw new LlmError9(
|
|
76727
76741
|
`opencode-go model "${model.id}" speaks ${model.api}, which has no stop-sequence parameter this adapter can reach; drop GenerateOptions.stop for this model`,
|
|
76728
76742
|
"UNSUPPORTED_OPTION"
|
|
76729
76743
|
);
|
|
@@ -76778,8 +76792,12 @@ var OpencodeGoAdapter = class extends LlmAdapter {
|
|
|
76778
76792
|
baseURL: assertBaseURL(config.baseURL),
|
|
76779
76793
|
refreshMs: config.refreshMinutes * 6e4,
|
|
76780
76794
|
defaults: {
|
|
76781
|
-
|
|
76782
|
-
|
|
76795
|
+
// A guess for a model no source sizes, kept in step with the
|
|
76796
|
+
// llm-pi-ai route defaults: modern models are roomier than the
|
|
76797
|
+
// 2026-era numbers these replace, and undersizing one fails a
|
|
76798
|
+
// request the gateway would have served.
|
|
76799
|
+
contextWindow: 1e6,
|
|
76800
|
+
maxTokens: 128e3,
|
|
76783
76801
|
input: ["text"]
|
|
76784
76802
|
},
|
|
76785
76803
|
overrides: config.modelProtocols,
|
|
@@ -76836,7 +76854,7 @@ var OpencodeGoAdapter = class extends LlmAdapter {
|
|
|
76836
76854
|
const config = this.options.config();
|
|
76837
76855
|
const snapshot2 = await this.catalogOf(config).forModel(model);
|
|
76838
76856
|
const facts = snapshot2.facts.get(model);
|
|
76839
|
-
if (facts === void 0) throw new
|
|
76857
|
+
if (facts === void 0) throw new LlmError9(`opencode-go has no model "${model}"`, "UNKNOWN_MODEL");
|
|
76840
76858
|
return this.modelInfo(withModelLimit(toPiModel(facts, config.baseURL), config.modelLimits));
|
|
76841
76859
|
}
|
|
76842
76860
|
/** Describe one model: capacities plus the reasoning levels it really offers. */
|
|
@@ -76882,16 +76900,17 @@ var OpencodeGoAdapter = class extends LlmAdapter {
|
|
|
76882
76900
|
if (effort === void 0 || effort === "off") return void 0;
|
|
76883
76901
|
const supported = getSupportedThinkingLevels(model);
|
|
76884
76902
|
if (supported.some((level) => level === effort)) return effort;
|
|
76885
|
-
throw new
|
|
76903
|
+
throw new LlmError9(
|
|
76886
76904
|
`opencode-go model "${model.id}" does not support reasoning effort "${effort}"`,
|
|
76887
76905
|
"UNSUPPORTED_REASONING_EFFORT"
|
|
76888
76906
|
);
|
|
76889
76907
|
}
|
|
76890
76908
|
async prepareCall(_provider, model, _signal) {
|
|
76891
76909
|
const config = this.options.config();
|
|
76910
|
+
assertStreamIdleTimeoutMs(config.streamIdleTimeoutMs);
|
|
76892
76911
|
const snapshot2 = await this.catalogOf(config).forModel(model);
|
|
76893
76912
|
const facts = snapshot2.facts.get(model);
|
|
76894
|
-
if (facts === void 0) throw new
|
|
76913
|
+
if (facts === void 0) throw new LlmError9(`opencode-go has no model "${model}"`, "UNKNOWN_MODEL");
|
|
76895
76914
|
const prepared = this.modelInfo(withModelLimit(toPiModel(facts, config.baseURL), config.modelLimits));
|
|
76896
76915
|
return {
|
|
76897
76916
|
model: prepared,
|
|
@@ -76900,14 +76919,16 @@ var OpencodeGoAdapter = class extends LlmAdapter {
|
|
|
76900
76919
|
}
|
|
76901
76920
|
async *stream(options) {
|
|
76902
76921
|
const config = this.options.config();
|
|
76922
|
+
assertStreamIdleTimeoutMs(config.streamIdleTimeoutMs);
|
|
76903
76923
|
const snapshot2 = await this.catalogOf(config).forModel(options.model);
|
|
76904
76924
|
yield* this.streamWithSnapshot(options, config, snapshot2);
|
|
76905
76925
|
}
|
|
76906
76926
|
async *streamWithSnapshot(options, config, snapshot2) {
|
|
76907
76927
|
var _stack = [];
|
|
76908
76928
|
try {
|
|
76929
|
+
assertStreamIdleTimeoutMs(config.streamIdleTimeoutMs);
|
|
76909
76930
|
const facts = snapshot2.facts.get(options.model);
|
|
76910
|
-
if (facts === void 0) throw new
|
|
76931
|
+
if (facts === void 0) throw new LlmError9(`opencode-go has no model "${options.model}"`, "UNKNOWN_MODEL");
|
|
76911
76932
|
const model = withModelLimit(toPiModel(facts, config.baseURL), config.modelLimits);
|
|
76912
76933
|
const rates2 = usableRates(facts.cost);
|
|
76913
76934
|
const stop = stopSequencesFor(model, options.stop);
|
|
@@ -76915,7 +76936,7 @@ var OpencodeGoAdapter = class extends LlmAdapter {
|
|
|
76915
76936
|
const maxTokens = options.maxTokens === void 0 || ceiling === null || ceiling === void 0 ? options.maxTokens : Math.min(options.maxTokens, ceiling);
|
|
76916
76937
|
const apiKey = await this.options.resolveApiKey();
|
|
76917
76938
|
if (apiKey === void 0 || apiKey.length === 0) {
|
|
76918
|
-
throw new
|
|
76939
|
+
throw new LlmError9("dshopencodego: no credential resolved for the opencode-go route", "MISSING_CREDENTIAL");
|
|
76919
76940
|
}
|
|
76920
76941
|
const reasoning = this.resolveReasoningLevel(model, options.reasoningEffort);
|
|
76921
76942
|
const consumer = new AbortController();
|
|
@@ -76953,14 +76974,14 @@ var OpencodeGoAdapter = class extends LlmAdapter {
|
|
|
76953
76974
|
};
|
|
76954
76975
|
try {
|
|
76955
76976
|
if (containsImage && !model.input.includes("image")) {
|
|
76956
|
-
throw new
|
|
76977
|
+
throw new LlmError9(`opencode-go model "${model.id}" does not support image input`, "UNSUPPORTED_CONTENT");
|
|
76957
76978
|
}
|
|
76958
76979
|
let imageRequest;
|
|
76959
76980
|
if (containsImage) {
|
|
76960
76981
|
const access2 = this.options.imageAccess;
|
|
76961
76982
|
const store = access2?.resolveAttachments();
|
|
76962
76983
|
if (access2 === void 0 || store === void 0) {
|
|
76963
|
-
throw new
|
|
76984
|
+
throw new LlmError9("dshopencodego image input requires the durable attachment service", "UNSUPPORTED_CONTENT");
|
|
76964
76985
|
}
|
|
76965
76986
|
imageRequest = {
|
|
76966
76987
|
attachments: store,
|
|
@@ -77004,7 +77025,7 @@ var OpencodeGoAdapter = class extends LlmAdapter {
|
|
|
77004
77025
|
while (true) {
|
|
77005
77026
|
const result = await watchdog.next(iterator);
|
|
77006
77027
|
if (timeoutOf(watchdog.signal, "LLM_STREAM_IDLE_TIMEOUT") !== void 0) {
|
|
77007
|
-
throw new
|
|
77028
|
+
throw new LlmError9("opencode-go stream idle timeout", "TIMEOUT");
|
|
77008
77029
|
}
|
|
77009
77030
|
if (result.done) {
|
|
77010
77031
|
exhausted = true;
|
|
@@ -77056,13 +77077,13 @@ var OpencodeGoAdapter = class extends LlmAdapter {
|
|
|
77056
77077
|
} catch (error) {
|
|
77057
77078
|
if (timedOut || timeoutOf(watchdog.signal, "LLM_STREAM_IDLE_TIMEOUT") !== void 0) {
|
|
77058
77079
|
span?.finish(false, "TIMEOUT");
|
|
77059
|
-
throw new
|
|
77080
|
+
throw new LlmError9("opencode-go stream idle timeout", "TIMEOUT", { cause: error });
|
|
77060
77081
|
}
|
|
77061
77082
|
if (options.signal?.aborted) {
|
|
77062
77083
|
span?.finish(false, "ABORTED");
|
|
77063
|
-
throw new
|
|
77084
|
+
throw new LlmError9("opencode-go request aborted by caller", "ABORTED", { cause: error });
|
|
77064
77085
|
}
|
|
77065
|
-
span?.finish(false, error instanceof
|
|
77086
|
+
span?.finish(false, error instanceof LlmError9 ? error.code : void 0);
|
|
77066
77087
|
throw error;
|
|
77067
77088
|
} finally {
|
|
77068
77089
|
consumer.abort("opencode-go stream consumer stopped");
|
|
@@ -77531,7 +77552,7 @@ function registerRemotes(ctx) {
|
|
|
77531
77552
|
|
|
77532
77553
|
// src/catalog/service.ts
|
|
77533
77554
|
import { RemoteError, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
|
|
77534
|
-
import { LlmError as
|
|
77555
|
+
import { LlmError as LlmError10 } from "@deepseek-ai/dsh-llm";
|
|
77535
77556
|
|
|
77536
77557
|
// src/catalog/reading.ts
|
|
77537
77558
|
function catalogReading(snapshot2, visibility, listingFailure, now) {
|
|
@@ -77612,7 +77633,7 @@ var OpencodeGoCatalogService = class extends TypertRemoteService {
|
|
|
77612
77633
|
const reading = catalogReading(
|
|
77613
77634
|
snapshot2,
|
|
77614
77635
|
visibility,
|
|
77615
|
-
failure === void 0 ? void 0 : failure instanceof
|
|
77636
|
+
failure === void 0 ? void 0 : failure instanceof LlmError10 || failure instanceof Error ? failure.message : String(failure)
|
|
77616
77637
|
);
|
|
77617
77638
|
this.reportUnadvertised(snapshot2, visibility);
|
|
77618
77639
|
return reading;
|
|
@@ -78074,7 +78095,7 @@ function createUpdateChecker(deps) {
|
|
|
78074
78095
|
}
|
|
78075
78096
|
|
|
78076
78097
|
// src/update/version.ts
|
|
78077
|
-
var PLUGIN_VERSION = true ? "0.1.
|
|
78098
|
+
var PLUGIN_VERSION = true ? "0.1.76" : "0.0.0-dev";
|
|
78078
78099
|
|
|
78079
78100
|
// src/update/service.ts
|
|
78080
78101
|
import { TypertRemoteService as TypertRemoteService4 } from "@deepseek-ai/dsh-typert-protocol";
|
|
@@ -78103,7 +78124,7 @@ var OpencodeGoUpdateService = class extends TypertRemoteService4 {
|
|
|
78103
78124
|
};
|
|
78104
78125
|
|
|
78105
78126
|
// src/usage/windows.ts
|
|
78106
|
-
import { attributionHeaders as attributionHeaders6, LlmError as
|
|
78127
|
+
import { attributionHeaders as attributionHeaders6, LlmError as LlmError11 } from "@deepseek-ai/dsh-llm";
|
|
78107
78128
|
var USAGE_MAX_BYTES = 1024 * 1024;
|
|
78108
78129
|
var USAGE_TIMEOUT_MS = 1e4;
|
|
78109
78130
|
function parseGoUsage(value) {
|
|
@@ -78121,7 +78142,7 @@ function parseGoUsage(value) {
|
|
|
78121
78142
|
}
|
|
78122
78143
|
async function readUsageWindows(options) {
|
|
78123
78144
|
if (options.apiKey === void 0 || options.apiKey.length === 0) {
|
|
78124
|
-
throw new
|
|
78145
|
+
throw new LlmError11("dshopencodego: no credential is configured for the opencode-go route", "USAGE_UNAVAILABLE");
|
|
78125
78146
|
}
|
|
78126
78147
|
const url = `${options.baseURL.replace(/\/+$/, "")}/usage`;
|
|
78127
78148
|
const timeout = AbortSignal.timeout(USAGE_TIMEOUT_MS);
|
|
@@ -78138,12 +78159,12 @@ async function readUsageWindows(options) {
|
|
|
78138
78159
|
signal: options.signal === void 0 ? timeout : AbortSignal.any([options.signal, timeout])
|
|
78139
78160
|
});
|
|
78140
78161
|
} catch (error) {
|
|
78141
|
-
throw new
|
|
78162
|
+
throw new LlmError11(`could not reach ${url}`, "USAGE_UNAVAILABLE", { cause: error });
|
|
78142
78163
|
}
|
|
78143
78164
|
if (!response.ok) {
|
|
78144
78165
|
await response.body?.cancel().catch(() => {
|
|
78145
78166
|
});
|
|
78146
|
-
throw new
|
|
78167
|
+
throw new LlmError11(`${url} answered HTTP ${response.status}`, "USAGE_UNAVAILABLE");
|
|
78147
78168
|
}
|
|
78148
78169
|
const body = await readBoundedJson(response, url, USAGE_MAX_BYTES);
|
|
78149
78170
|
try {
|
|
@@ -78152,16 +78173,16 @@ async function readUsageWindows(options) {
|
|
|
78152
78173
|
...options.source === void 0 ? {} : { source: options.source }
|
|
78153
78174
|
};
|
|
78154
78175
|
} catch (error) {
|
|
78155
|
-
throw new
|
|
78176
|
+
throw new LlmError11(`${url} returned an invalid usage document`, "USAGE_UNAVAILABLE", { cause: error });
|
|
78156
78177
|
}
|
|
78157
78178
|
}
|
|
78158
78179
|
|
|
78159
78180
|
// src/usage/service.ts
|
|
78160
78181
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
78161
78182
|
import { RemoteError as RemoteError2, TypertRemoteService as TypertRemoteService5 } from "@deepseek-ai/dsh-typert-protocol";
|
|
78162
|
-
import { LlmError as
|
|
78183
|
+
import { LlmError as LlmError12 } from "@deepseek-ai/dsh-llm";
|
|
78163
78184
|
function usageFailure(error, source) {
|
|
78164
|
-
const missing = error instanceof
|
|
78185
|
+
const missing = error instanceof LlmError12 && error.code === "MISSING_CREDENTIAL";
|
|
78165
78186
|
return new RemoteError2(
|
|
78166
78187
|
"dshopencodego/usage-unavailable",
|
|
78167
78188
|
error instanceof Error ? error.message : "OpenCode Go usage is unavailable",
|
|
@@ -78188,7 +78209,7 @@ var OpencodeGoUsageService = class extends TypertRemoteService5 {
|
|
|
78188
78209
|
}
|
|
78189
78210
|
if (key === void 0 || key.length === 0) {
|
|
78190
78211
|
this.identity = void 0;
|
|
78191
|
-
throw usageFailure(new
|
|
78212
|
+
throw usageFailure(new LlmError12("No OpenCode Go API key is configured", "MISSING_CREDENTIAL"), void 0);
|
|
78192
78213
|
}
|
|
78193
78214
|
if (this.identity?.baseURL !== baseURL || this.identity.key !== key) {
|
|
78194
78215
|
this.identity = { baseURL, key, source: randomUUID3() };
|
|
@@ -78237,7 +78258,7 @@ function apply(ctx, raw) {
|
|
|
78237
78258
|
const credentials = ctx.get("credentials");
|
|
78238
78259
|
const hit = credentials !== void 0 ? (await credentials.resolve(credentialRef(ref)))?.value : launchEnvironmentOf(ctx).get(ref)?.value;
|
|
78239
78260
|
if (hit !== void 0 && hit.length > 0) return llm2.assertUsableApiKey(hit, name, ref);
|
|
78240
|
-
throw new
|
|
78261
|
+
throw new LlmError13(
|
|
78241
78262
|
`dshopencodego: no credential; the profile resolves ${ref}, which is not set \u2014 store ${ref} through the credentials service (the Web Models page writes it) or export it`,
|
|
78242
78263
|
"MISSING_CREDENTIAL"
|
|
78243
78264
|
);
|
|
@@ -78327,7 +78348,8 @@ function apply(ctx, raw) {
|
|
|
78327
78348
|
};
|
|
78328
78349
|
}, "dshopencodego: catalog warm-up");
|
|
78329
78350
|
let registration;
|
|
78330
|
-
|
|
78351
|
+
const registrationFacts = () => JSON.stringify({ visibility: current2().modelVisibility, retryPolicy: current2().retryPolicy ?? null });
|
|
78352
|
+
let registeredFacts = registrationFacts();
|
|
78331
78353
|
const applyRoute = (credentialConfigured) => {
|
|
78332
78354
|
const enabled = current2().enabled;
|
|
78333
78355
|
if (enabled && credentialConfigured && registration === void 0) {
|
|
@@ -78348,9 +78370,9 @@ function apply(ctx, raw) {
|
|
|
78348
78370
|
};
|
|
78349
78371
|
const syncRoute = () => {
|
|
78350
78372
|
try {
|
|
78351
|
-
const
|
|
78352
|
-
if (
|
|
78353
|
-
|
|
78373
|
+
const facts = registrationFacts();
|
|
78374
|
+
if (facts !== registeredFacts) {
|
|
78375
|
+
registeredFacts = facts;
|
|
78354
78376
|
registration?.replace([PROVIDER_ID]);
|
|
78355
78377
|
}
|
|
78356
78378
|
const credentials = ctx.get("credentials");
|
|
@@ -78375,7 +78397,7 @@ function apply(ctx, raw) {
|
|
|
78375
78397
|
settingsNs,
|
|
78376
78398
|
async (request, signal) => {
|
|
78377
78399
|
if (request.provider !== PROVIDER_ID && !(request.baseURL ?? "").includes("opencode.ai")) {
|
|
78378
|
-
throw new
|
|
78400
|
+
throw new LlmError13(
|
|
78379
78401
|
"dshopencodego discovers only OpenCode Go/Console endpoints; enter this provider's models by hand",
|
|
78380
78402
|
"DISCOVERY_UNSUPPORTED"
|
|
78381
78403
|
);
|
|
@@ -78416,6 +78438,7 @@ export {
|
|
|
78416
78438
|
SESSION_HEADER,
|
|
78417
78439
|
apply,
|
|
78418
78440
|
assertBaseURL,
|
|
78441
|
+
assertStreamIdleTimeoutMs,
|
|
78419
78442
|
discoverCatalogModels,
|
|
78420
78443
|
fetchModelIds,
|
|
78421
78444
|
inject,
|
package/lib/types/config.d.ts
CHANGED
|
@@ -121,6 +121,20 @@ export type LiveConfig = {
|
|
|
121
121
|
};
|
|
122
122
|
/** Runtime schema for {@link OpencodeGoConfig}; every field stays live. */
|
|
123
123
|
export declare const Config: z<Partial<OpencodeGoConfig>, LiveConfig>;
|
|
124
|
+
/**
|
|
125
|
+
* Validate one request-time idle timeout the schema let through.
|
|
126
|
+
*
|
|
127
|
+
* The schema bounds the persisted profile, but a live reference hands back
|
|
128
|
+
* whatever it holds (and a programmatic mount hands back whatever it returns):
|
|
129
|
+
* `NaN` passes `z.number()`, and a non-positive or overflowing value would
|
|
130
|
+
* otherwise reach `idleWatchdog` mid-request — after the credential was read —
|
|
131
|
+
* as a bare `Error` from its own assertion. Failing here fails before any
|
|
132
|
+
* credential read or network wait, with the route's own message instead of
|
|
133
|
+
* the timer's. Mirrors the resolve-time guard `llm-pi-ai` applies to the same
|
|
134
|
+
* field (`llm-pi-ai/src/config.ts`, "must be a positive finite number").
|
|
135
|
+
* @param value - the configured idle timeout in milliseconds.
|
|
136
|
+
*/
|
|
137
|
+
export declare function assertStreamIdleTimeoutMs(value: unknown): asserts value is number;
|
|
124
138
|
/**
|
|
125
139
|
* Keep the Loader's references: reparsing them would detach live updates.
|
|
126
140
|
*
|
package/lib/types/index.d.ts
CHANGED
|
@@ -36,7 +36,7 @@ declare module '@deepseek-ai/cordis' {
|
|
|
36
36
|
export { OpencodeGoAdapter } from './adapter.ts';
|
|
37
37
|
export type { OpencodeGoAdapterOptions, OpencodeGoImageAccess } from './adapter.ts';
|
|
38
38
|
export { DEFAULT_BASE_URL, CONSOLE_BASE_URL, DISPLAY_NAME, PROVIDER_ID, OpencodeGoCatalog, discoverCatalogModels, fetchModelIds } from './catalog/index.ts';
|
|
39
|
-
export { Config, PlainConfig, assertBaseURL, DEFAULT_API_KEY_ENV } from './config.ts';
|
|
39
|
+
export { Config, PlainConfig, assertBaseURL, assertStreamIdleTimeoutMs, DEFAULT_API_KEY_ENV } from './config.ts';
|
|
40
40
|
export type { OpencodeGoConfig } from './config.ts';
|
|
41
41
|
export { SESSION_HEADER, SESSION_AFFINITY_HEADER, opencodeSessionValue, providerHeaders } from './session-header.ts';
|
|
42
42
|
export { isModelEnabled, sortModels } from './models.ts';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dan-ai-studio/dshopencodego",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.76",
|
|
4
4
|
"description": "OpenCode Go provider for DeepSeek Harness: live gateway catalog, per-conversation session header, usage",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -123,30 +123,30 @@
|
|
|
123
123
|
},
|
|
124
124
|
"devDependencies": {
|
|
125
125
|
"@deepseek-ai/cordis": "4.0.5",
|
|
126
|
-
"@deepseek-ai/dsh-api-remotes": "0.2.1-rc.
|
|
127
|
-
"@deepseek-ai/dsh-attachment": "0.2.1-rc.
|
|
128
|
-
"@deepseek-ai/dsh-brand": "0.2.1-rc.
|
|
129
|
-
"@deepseek-ai/dsh-client-locale": "0.2.1-rc.
|
|
130
|
-
"@deepseek-ai/dsh-client-store": "0.2.1-rc.
|
|
131
|
-
"@deepseek-ai/dsh-client-ui-conversation": "0.2.1-rc.
|
|
132
|
-
"@deepseek-ai/dsh-client-ui-layout": "0.2.1-rc.
|
|
133
|
-
"@deepseek-ai/dsh-client-ui-model-selection": "0.2.1-rc.
|
|
134
|
-
"@deepseek-ai/dsh-client-ui-primitives": "0.2.1-rc.
|
|
135
|
-
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-rc.
|
|
136
|
-
"@deepseek-ai/dsh-client-ui-settings": "0.2.1-rc.
|
|
137
|
-
"@deepseek-ai/dsh-client-ui-sidebar": "0.2.1-rc.
|
|
138
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.2.1-rc.
|
|
139
|
-
"@deepseek-ai/dsh-credentials": "0.2.1-rc.
|
|
140
|
-
"@deepseek-ai/dsh-fs": "0.2.1-rc.
|
|
141
|
-
"@deepseek-ai/dsh-launch-environment": "0.2.1-rc.
|
|
142
|
-
"@deepseek-ai/dsh-llm": "0.2.1-rc.
|
|
143
|
-
"@deepseek-ai/dsh-sandbox": "0.2.1-rc.
|
|
144
|
-
"@deepseek-ai/dsh-scope": "0.2.1-rc.
|
|
145
|
-
"@deepseek-ai/dsh-session": "0.2.1-rc.
|
|
146
|
-
"@deepseek-ai/dsh-settings": "0.2.1-rc.
|
|
147
|
-
"@deepseek-ai/dsh-timeout": "0.2.1-rc.
|
|
148
|
-
"@deepseek-ai/dsh-typert-protocol": "0.2.1-rc.
|
|
149
|
-
"@deepseek-ai/dsh-typert-registry": "0.2.1-rc.
|
|
126
|
+
"@deepseek-ai/dsh-api-remotes": "0.2.1-rc.4",
|
|
127
|
+
"@deepseek-ai/dsh-attachment": "0.2.1-rc.4",
|
|
128
|
+
"@deepseek-ai/dsh-brand": "0.2.1-rc.4",
|
|
129
|
+
"@deepseek-ai/dsh-client-locale": "0.2.1-rc.4",
|
|
130
|
+
"@deepseek-ai/dsh-client-store": "0.2.1-rc.4",
|
|
131
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.2.1-rc.4",
|
|
132
|
+
"@deepseek-ai/dsh-client-ui-layout": "0.2.1-rc.4",
|
|
133
|
+
"@deepseek-ai/dsh-client-ui-model-selection": "0.2.1-rc.4",
|
|
134
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.2.1-rc.4",
|
|
135
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-rc.4",
|
|
136
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.2.1-rc.4",
|
|
137
|
+
"@deepseek-ai/dsh-client-ui-sidebar": "0.2.1-rc.4",
|
|
138
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.2.1-rc.4",
|
|
139
|
+
"@deepseek-ai/dsh-credentials": "0.2.1-rc.4",
|
|
140
|
+
"@deepseek-ai/dsh-fs": "0.2.1-rc.4",
|
|
141
|
+
"@deepseek-ai/dsh-launch-environment": "0.2.1-rc.4",
|
|
142
|
+
"@deepseek-ai/dsh-llm": "0.2.1-rc.4",
|
|
143
|
+
"@deepseek-ai/dsh-sandbox": "0.2.1-rc.4",
|
|
144
|
+
"@deepseek-ai/dsh-scope": "0.2.1-rc.4",
|
|
145
|
+
"@deepseek-ai/dsh-session": "0.2.1-rc.4",
|
|
146
|
+
"@deepseek-ai/dsh-settings": "0.2.1-rc.4",
|
|
147
|
+
"@deepseek-ai/dsh-timeout": "0.2.1-rc.4",
|
|
148
|
+
"@deepseek-ai/dsh-typert-protocol": "0.2.1-rc.4",
|
|
149
|
+
"@deepseek-ai/dsh-typert-registry": "0.2.1-rc.4",
|
|
150
150
|
"@deepseek-ai/schemastery": "~3.18.5-alpha.2",
|
|
151
151
|
"@earendil-works/pi-ai": "~1.4.0",
|
|
152
152
|
"@testing-library/dom": "^10.4.1",
|