@serkanalgur/opencode-nexus 1.2.7 → 1.3.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/dist/index.js +93 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9740,6 +9740,7 @@ class NexusOrchestrator {
|
|
|
9740
9740
|
return this._healthMonitor;
|
|
9741
9741
|
}
|
|
9742
9742
|
notifications = null;
|
|
9743
|
+
modelCosts = new Map;
|
|
9743
9744
|
constructor(config, messageStoreConfig, memoryStoreConfig) {
|
|
9744
9745
|
this.config = this.mergeConfig(config);
|
|
9745
9746
|
this.budget = this.config.budget;
|
|
@@ -9761,6 +9762,7 @@ class NexusOrchestrator {
|
|
|
9761
9762
|
this.ctx = ctx;
|
|
9762
9763
|
this.onStateChange = onStateChange ?? null;
|
|
9763
9764
|
this.configManager.loadFromPath(process.cwd());
|
|
9765
|
+
await this.loadModelCosts();
|
|
9764
9766
|
this.cleanupInterval = setInterval(() => this.cleanupStaleData(), 300000);
|
|
9765
9767
|
this._healthMonitor = new HealthMonitor({
|
|
9766
9768
|
checkInterval: this.config.agents.healthCheckInterval
|
|
@@ -9776,6 +9778,56 @@ class NexusOrchestrator {
|
|
|
9776
9778
|
};
|
|
9777
9779
|
await this.moduleRegistry.setupAll(moduleCtx);
|
|
9778
9780
|
}
|
|
9781
|
+
async loadModelCosts() {
|
|
9782
|
+
try {
|
|
9783
|
+
if (!this.ctx)
|
|
9784
|
+
return;
|
|
9785
|
+
if (this.ctx.client?.model?.list) {
|
|
9786
|
+
const result = await this.ctx.client.model.list();
|
|
9787
|
+
const models = result?.data?.data ?? result?.data ?? [];
|
|
9788
|
+
if (Array.isArray(models)) {
|
|
9789
|
+
for (const model of models) {
|
|
9790
|
+
if (model.cost && Array.isArray(model.cost) && model.cost.length > 0) {
|
|
9791
|
+
const baseCost = model.cost[0];
|
|
9792
|
+
this.modelCosts.set(model.id, {
|
|
9793
|
+
input: baseCost.input || 0,
|
|
9794
|
+
output: baseCost.output || 0,
|
|
9795
|
+
cacheRead: baseCost.cache?.read || 0,
|
|
9796
|
+
cacheWrite: baseCost.cache?.write || 0
|
|
9797
|
+
});
|
|
9798
|
+
}
|
|
9799
|
+
}
|
|
9800
|
+
}
|
|
9801
|
+
return;
|
|
9802
|
+
}
|
|
9803
|
+
const location = this.ctx.location ?? this.ctx.data?.location?.default();
|
|
9804
|
+
if (location && this.ctx.data?.location?.model) {
|
|
9805
|
+
await this.ctx.data.location.model.sync(location);
|
|
9806
|
+
const models = this.ctx.data.location.model.list(location) ?? [];
|
|
9807
|
+
for (const model of models) {
|
|
9808
|
+
if (model.cost && Array.isArray(model.cost) && model.cost.length > 0) {
|
|
9809
|
+
const baseCost = model.cost[0];
|
|
9810
|
+
this.modelCosts.set(model.id, {
|
|
9811
|
+
input: baseCost.input || 0,
|
|
9812
|
+
output: baseCost.output || 0,
|
|
9813
|
+
cacheRead: baseCost.cache?.read || 0,
|
|
9814
|
+
cacheWrite: baseCost.cache?.write || 0
|
|
9815
|
+
});
|
|
9816
|
+
}
|
|
9817
|
+
}
|
|
9818
|
+
}
|
|
9819
|
+
} catch {}
|
|
9820
|
+
}
|
|
9821
|
+
setModelCosts(costs) {
|
|
9822
|
+
for (const [model, cost] of Object.entries(costs)) {
|
|
9823
|
+
this.modelCosts.set(model, {
|
|
9824
|
+
input: cost.input,
|
|
9825
|
+
output: cost.output,
|
|
9826
|
+
cacheRead: cost.cacheRead || 0,
|
|
9827
|
+
cacheWrite: cost.cacheWrite || 0
|
|
9828
|
+
});
|
|
9829
|
+
}
|
|
9830
|
+
}
|
|
9779
9831
|
initBroadcaster(opts) {
|
|
9780
9832
|
this.broadcaster = new StateBroadcaster(this, opts);
|
|
9781
9833
|
const previousOnStateChange = this.onStateChange;
|
|
@@ -10354,6 +10406,10 @@ Please continue from where the previous agent left off.`;
|
|
|
10354
10406
|
return this.selectBestModel(role, complexity);
|
|
10355
10407
|
}
|
|
10356
10408
|
estimateModelCost(model) {
|
|
10409
|
+
const realCost = this.modelCosts.get(model);
|
|
10410
|
+
if (realCost) {
|
|
10411
|
+
return (realCost.input * 1000 + realCost.output * 1000) / 2;
|
|
10412
|
+
}
|
|
10357
10413
|
const costs = {
|
|
10358
10414
|
"claude-sonnet-4-6": 0.15,
|
|
10359
10415
|
"claude-opus-4-7": 15,
|
|
@@ -10905,6 +10961,43 @@ var src_default = define({
|
|
|
10905
10961
|
return { content: "Dashboard stopped" };
|
|
10906
10962
|
}
|
|
10907
10963
|
});
|
|
10964
|
+
editor.add({
|
|
10965
|
+
name: "model.costs",
|
|
10966
|
+
description: "Show real model pricing from OpenCode or set custom costs",
|
|
10967
|
+
input: {
|
|
10968
|
+
type: "object",
|
|
10969
|
+
properties: {
|
|
10970
|
+
model: { type: "string", description: "Model ID to show cost for (optional, shows all if omitted)" },
|
|
10971
|
+
setInput: { type: "number", description: "Set input cost per token for a model" },
|
|
10972
|
+
setOutput: { type: "number", description: "Set output cost per token for a model" }
|
|
10973
|
+
},
|
|
10974
|
+
additionalProperties: false
|
|
10975
|
+
},
|
|
10976
|
+
execute: async (input) => {
|
|
10977
|
+
const { model, setInput, setOutput } = input;
|
|
10978
|
+
if (model && setInput !== undefined && setOutput !== undefined) {
|
|
10979
|
+
orchestrator.setModelCosts({ [model]: { input: setInput, output: setOutput } });
|
|
10980
|
+
return { content: `Set ${model}: input=$${setInput}/token, output=$${setOutput}/token` };
|
|
10981
|
+
}
|
|
10982
|
+
if (model) {
|
|
10983
|
+
const cost = orchestrator.modelCosts.get(model);
|
|
10984
|
+
if (cost) {
|
|
10985
|
+
return { content: `${model}: input=$${cost.input}/token, output=$${cost.output}/token, cache_read=$${cost.cacheRead}/token, cache_write=$${cost.cacheWrite}/token` };
|
|
10986
|
+
}
|
|
10987
|
+
const estimate = orchestrator["estimateModelCost"](model);
|
|
10988
|
+
return { content: `${model}: no real pricing data (estimated $${estimate}/1K tokens)` };
|
|
10989
|
+
}
|
|
10990
|
+
if (orchestrator.modelCosts.size > 0) {
|
|
10991
|
+
const lines = ["\uD83D\uDCCA Model Pricing (from OpenCode):"];
|
|
10992
|
+
for (const [id, cost] of orchestrator.modelCosts) {
|
|
10993
|
+
lines.push(` ${id}: $${cost.input}/token in, $${cost.output}/token out`);
|
|
10994
|
+
}
|
|
10995
|
+
return { content: lines.join(`
|
|
10996
|
+
`) };
|
|
10997
|
+
}
|
|
10998
|
+
return { content: "No real pricing data loaded. Using hardcoded estimates." };
|
|
10999
|
+
}
|
|
11000
|
+
});
|
|
10908
11001
|
editor.add({
|
|
10909
11002
|
name: "spawn",
|
|
10910
11003
|
description: "Spawn a sub-agent for a task",
|