@toddzheng024/dscode-bundle 0.7.6 → 0.7.7
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/THIRD_PARTY_NOTICES.md +3 -3
- package/cordis.patch.yml +26 -5
- package/package.json +4 -4
- package/plugins/auto-review/index.mjs +6 -1
- package/plugins/compaction/tetris.mjs +65 -0
- package/plugins/compaction/threshold.mjs +46 -0
- package/plugins/credentials/index.mjs +2 -2
- package/plugins/i18n/messages.mjs +18 -0
- package/plugins/openrouter/adapter.mjs +157 -0
- package/plugins/openrouter/index.mjs +112 -0
- package/plugins/openrouter/models.mjs +151 -0
- package/plugins/openrouter/search.mjs +109 -0
- package/plugins/openrouter/wire.mjs +413 -0
- package/plugins/providers/catalog.mjs +18 -68
- package/plugins/providers/openrouter-account.mjs +171 -0
- package/plugins/session-metrics/balance.mjs +29 -19
- package/plugins/session-metrics/index.mjs +19 -9
- package/plugins/session-metrics/pricing.mjs +26 -6
- package/plugins/session-metrics/view.mjs +1 -1
- package/plugins/ultra/policy.mjs +0 -16
- package/presets/dscode/agent.cordis.yml +1 -1
- package/vendor/compaction-basic/index.js +983 -0
- package/vendor/compaction-basic/types/config.d.ts +37 -0
- package/vendor/compaction-basic/types/index.d.ts +84 -0
- package/vendor/compaction-basic/types/region.d.ts +65 -0
- package/vendor/compaction-basic/types/summarizer.d.ts +64 -0
- package/vendor/compaction-basic/types/types.d.ts +73 -0
- package/vendor/tui/dscode-providers/catalog.mjs +18 -68
- package/vendor/tui/dscode-providers/openrouter-account.mjs +171 -0
- package/vendor/tui/index.mjs +390 -165
- package/plugins/session-metrics/openrouter-prices.mjs +0 -96
- package/vendor/pi-ai/index.js +0 -2701
- package/vendor/pi-ai/types/adapter.d.ts +0 -105
- package/vendor/pi-ai/types/auth.d.ts +0 -60
- package/vendor/pi-ai/types/catalog.d.ts +0 -355
- package/vendor/pi-ai/types/config.d.ts +0 -208
- package/vendor/pi-ai/types/context.d.ts +0 -42
- package/vendor/pi-ai/types/discovery.d.ts +0 -43
- package/vendor/pi-ai/types/index.d.ts +0 -69
- package/vendor/pi-ai/types/login.d.ts +0 -21
- package/vendor/pi-ai/types/provider.d.ts +0 -59
- package/vendor/pi-ai/types/replay.d.ts +0 -63
- package/vendor/pi-ai/types/stream.d.ts +0 -43
- /package/vendor/{pi-ai → compaction-basic}/LICENSE +0 -0
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
|
|
4
|
-
// OpenRouter list prices for every model it serves, read from its public model
|
|
5
|
-
// listing (no key needed) and kept for a day in DSH_HOME, so any OpenRouter model
|
|
6
|
-
// can be priced. The listing quotes USD per token; the table keeps USD per million.
|
|
7
|
-
export const OPENROUTER_MODELS_URL = 'https://openrouter.ai/api/v1/models';
|
|
8
|
-
const MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
|
9
|
-
const RETRY_MS = 10 * 60 * 1000;
|
|
10
|
-
const FILE = 'openrouter-prices.json';
|
|
11
|
-
let table = { fetchedAt: 0, models: {} };
|
|
12
|
-
let attemptedAt = 0, pending;
|
|
13
|
-
|
|
14
|
-
const perMillion = value => {
|
|
15
|
-
const number = Number(value);
|
|
16
|
-
return value != null && value !== '' && Number.isFinite(number) && number >= 0 ? number * 1e6 : undefined;
|
|
17
|
-
};
|
|
18
|
-
const ratesOf = pricing => {
|
|
19
|
-
const input = perMillion(pricing?.prompt), output = perMillion(pricing?.completion);
|
|
20
|
-
if (input === undefined || output === undefined) return undefined;
|
|
21
|
-
return { input, output, cacheRead: perMillion(pricing.input_cache_read), cacheWrite: perMillion(pricing.input_cache_write) };
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Per-model prices from an OpenRouter `/models` body.
|
|
26
|
-
* @returns `{ [id]: { input, output, cacheRead?, cacheWrite?, tiers? } }` in USD per million tokens;
|
|
27
|
-
* a tier applies once a request's prompt reaches its `minPromptTokens`.
|
|
28
|
-
*/
|
|
29
|
-
export function parseOpenRouterModels(body) {
|
|
30
|
-
const models = {};
|
|
31
|
-
for (const model of Array.isArray(body?.data) ? body.data : []) {
|
|
32
|
-
const base = typeof model?.id === 'string' ? ratesOf(model.pricing) : undefined;
|
|
33
|
-
if (!base) continue;
|
|
34
|
-
const tiers = (Array.isArray(model.pricing.overrides) ? model.pricing.overrides : [])
|
|
35
|
-
.map(tier => ({ minPromptTokens: Number(tier?.min_prompt_tokens), ...ratesOf({ ...model.pricing, ...tier }) }))
|
|
36
|
-
.filter(tier => Number.isFinite(tier.minPromptTokens) && tier.input !== undefined)
|
|
37
|
-
.sort((left, right) => left.minPromptTokens - right.minPromptTokens);
|
|
38
|
-
models[model.id] = { ...base, ...(tiers.length ? { tiers } : {}) };
|
|
39
|
-
}
|
|
40
|
-
return models;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/** Prices for one model at a request's prompt size, or undefined when the table lists none. */
|
|
44
|
-
export function openRouterRates(model, promptTokens = 0) {
|
|
45
|
-
const entry = table.models[model];
|
|
46
|
-
if (!entry) return undefined;
|
|
47
|
-
return entry.tiers?.findLast(tier => promptTokens >= tier.minPromptTokens) ?? entry;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/** Version stamp for rows priced from the live table: the day it was fetched. */
|
|
51
|
-
export function openRouterPriceVersion() {
|
|
52
|
-
return table.fetchedAt > 0 ? `openrouter-models-${new Date(table.fetchedAt).toISOString().slice(0, 10)}` : undefined;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/** Replace the table (and forget the last attempt); for tests and cache loads. */
|
|
56
|
-
export function setOpenRouterPrices(models, fetchedAt = Date.now()) {
|
|
57
|
-
table = { fetchedAt, models };
|
|
58
|
-
attemptedAt = 0;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Load the cached table, then refetch it once it is a day old. A failure keeps the
|
|
63
|
-
* last table and waits ten minutes before trying again; never throws.
|
|
64
|
-
*/
|
|
65
|
-
export async function refreshOpenRouterPrices({ home, fetch: fetchImpl = globalThis.fetch, now = Date.now() } = {}) {
|
|
66
|
-
const path = home ? join(home, FILE) : undefined;
|
|
67
|
-
if (table.fetchedAt === 0 && path) {
|
|
68
|
-
try {
|
|
69
|
-
const cached = JSON.parse(readFileSync(path, 'utf8'));
|
|
70
|
-
if (Number.isFinite(cached?.fetchedAt) && cached.models && typeof cached.models === 'object') table = { fetchedAt: cached.fetchedAt, models: cached.models };
|
|
71
|
-
} catch { /* no usable cache */ }
|
|
72
|
-
}
|
|
73
|
-
if (now - table.fetchedAt < MAX_AGE_MS || now - attemptedAt < RETRY_MS || typeof fetchImpl !== 'function') return table;
|
|
74
|
-
if (pending) return pending;
|
|
75
|
-
attemptedAt = now;
|
|
76
|
-
pending = (async () => {
|
|
77
|
-
try {
|
|
78
|
-
const response = await fetchImpl(OPENROUTER_MODELS_URL, { headers: { Accept: 'application/json' } });
|
|
79
|
-
if (!response.ok) return table;
|
|
80
|
-
const models = parseOpenRouterModels(await response.json());
|
|
81
|
-
if (Object.keys(models).length === 0) return table;
|
|
82
|
-
table = { fetchedAt: now, models };
|
|
83
|
-
if (path) {
|
|
84
|
-
mkdirSync(home, { recursive: true });
|
|
85
|
-
writeFileSync(`${path}.tmp`, JSON.stringify(table));
|
|
86
|
-
renameSync(`${path}.tmp`, path);
|
|
87
|
-
}
|
|
88
|
-
return table;
|
|
89
|
-
} catch {
|
|
90
|
-
return table;
|
|
91
|
-
} finally {
|
|
92
|
-
pending = undefined;
|
|
93
|
-
}
|
|
94
|
-
})();
|
|
95
|
-
return pending;
|
|
96
|
-
}
|