@sriinnu/kosha-discovery 1.2.0 → 1.5.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/README.md +65 -26
- package/dist/aliases.d.ts +6 -1
- package/dist/aliases.d.ts.map +1 -1
- package/dist/aliases.js +38 -12
- package/dist/aliases.js.map +1 -1
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +25 -2
- package/dist/cache.js.map +1 -1
- package/dist/claude-generation.d.ts +59 -0
- package/dist/claude-generation.d.ts.map +1 -0
- package/dist/claude-generation.js +117 -0
- package/dist/claude-generation.js.map +1 -0
- package/dist/cli-cmd-doctor.d.ts +17 -0
- package/dist/cli-cmd-doctor.d.ts.map +1 -0
- package/dist/cli-cmd-doctor.js +199 -0
- package/dist/cli-cmd-doctor.js.map +1 -0
- package/dist/cli-cmd-model.js +2 -2
- package/dist/cli-cmd-model.js.map +1 -1
- package/dist/cli-cmd-spend.d.ts +10 -0
- package/dist/cli-cmd-spend.d.ts.map +1 -0
- package/dist/cli-cmd-spend.js +130 -0
- package/dist/cli-cmd-spend.js.map +1 -0
- package/dist/cli-commands.d.ts +4 -1
- package/dist/cli-commands.d.ts.map +1 -1
- package/dist/cli-commands.js +10 -2
- package/dist/cli-commands.js.map +1 -1
- package/dist/cli-format.js.map +1 -1
- package/dist/cli-help.d.ts.map +1 -1
- package/dist/cli-help.js +4 -2
- package/dist/cli-help.js.map +1 -1
- package/dist/cli.js +10 -0
- package/dist/cli.js.map +1 -1
- package/dist/cost.d.ts +152 -0
- package/dist/cost.d.ts.map +1 -0
- package/dist/cost.js +377 -0
- package/dist/cost.js.map +1 -0
- package/dist/credentials/resolver.d.ts +10 -0
- package/dist/credentials/resolver.d.ts.map +1 -1
- package/dist/credentials/resolver.js +64 -31
- package/dist/credentials/resolver.js.map +1 -1
- package/dist/discovery/anthropic.d.ts +19 -1
- package/dist/discovery/anthropic.d.ts.map +1 -1
- package/dist/discovery/anthropic.js +112 -8
- package/dist/discovery/anthropic.js.map +1 -1
- package/dist/discovery/base.d.ts +7 -0
- package/dist/discovery/base.d.ts.map +1 -1
- package/dist/discovery/base.js +32 -4
- package/dist/discovery/base.js.map +1 -1
- package/dist/discovery/bedrock.d.ts.map +1 -1
- package/dist/discovery/cerebras.d.ts.map +1 -1
- package/dist/discovery/cohere.d.ts.map +1 -1
- package/dist/discovery/deepinfra.d.ts.map +1 -1
- package/dist/discovery/deepseek.d.ts.map +1 -1
- package/dist/discovery/fireworks.d.ts.map +1 -1
- package/dist/discovery/glm.d.ts.map +1 -1
- package/dist/discovery/google.d.ts +3 -1
- package/dist/discovery/google.d.ts.map +1 -1
- package/dist/discovery/google.js +13 -6
- package/dist/discovery/google.js.map +1 -1
- package/dist/discovery/groq.d.ts.map +1 -1
- package/dist/discovery/index.d.ts +2 -0
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/index.js +6 -0
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/llama-cpp.d.ts.map +1 -1
- package/dist/discovery/lmstudio.d.ts +26 -0
- package/dist/discovery/lmstudio.d.ts.map +1 -0
- package/dist/discovery/lmstudio.js +93 -0
- package/dist/discovery/lmstudio.js.map +1 -0
- package/dist/discovery/minimax.d.ts.map +1 -1
- package/dist/discovery/mistral.d.ts.map +1 -1
- package/dist/discovery/moonshot.d.ts.map +1 -1
- package/dist/discovery/nvidia.d.ts.map +1 -1
- package/dist/discovery/ollama.d.ts.map +1 -1
- package/dist/discovery/openai-compatible.d.ts.map +1 -1
- package/dist/discovery/openai.d.ts.map +1 -1
- package/dist/discovery/openrouter.d.ts +29 -5
- package/dist/discovery/openrouter.d.ts.map +1 -1
- package/dist/discovery/openrouter.js +56 -18
- package/dist/discovery/openrouter.js.map +1 -1
- package/dist/discovery/perplexity.d.ts.map +1 -1
- package/dist/discovery/promo-overrides.js.map +1 -1
- package/dist/discovery/static-direct.d.ts +9 -1
- package/dist/discovery/static-direct.d.ts.map +1 -1
- package/dist/discovery/static-direct.js +68 -7
- package/dist/discovery/static-direct.js.map +1 -1
- package/dist/discovery/together.d.ts.map +1 -1
- package/dist/discovery/vercel.d.ts.map +1 -1
- package/dist/discovery/vertex.d.ts.map +1 -1
- package/dist/discovery/vllm.d.ts +26 -0
- package/dist/discovery/vllm.d.ts.map +1 -0
- package/dist/discovery/vllm.js +93 -0
- package/dist/discovery/vllm.js.map +1 -0
- package/dist/discovery/zai.d.ts.map +1 -1
- package/dist/discovery-contract.d.ts +7 -0
- package/dist/discovery-contract.d.ts.map +1 -1
- package/dist/discovery-contract.js.map +1 -1
- package/dist/discovery-routes.d.ts +9 -0
- package/dist/discovery-routes.d.ts.map +1 -1
- package/dist/discovery-routes.js +106 -18
- package/dist/discovery-routes.js.map +1 -1
- package/dist/enrichment/litellm.d.ts +1 -1
- package/dist/enrichment/litellm.d.ts.map +1 -1
- package/dist/enrichment/litellm.js +3 -3
- package/dist/entry.d.ts +14 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +26 -0
- package/dist/entry.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.d.ts +207 -2
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +203 -51
- package/dist/mcp-server.js.map +1 -1
- package/dist/model-features.d.ts.map +1 -1
- package/dist/model-features.js +11 -2
- package/dist/model-features.js.map +1 -1
- package/dist/normalize.d.ts +7 -7
- package/dist/normalize.js +8 -8
- package/dist/provider-catalog.d.ts.map +1 -1
- package/dist/provider-catalog.js +26 -0
- package/dist/provider-catalog.js.map +1 -1
- package/dist/proxy.d.ts +49 -7
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +754 -89
- package/dist/proxy.js.map +1 -1
- package/dist/registry-query.js +2 -2
- package/dist/registry-query.js.map +1 -1
- package/dist/registry-routing.d.ts +65 -0
- package/dist/registry-routing.d.ts.map +1 -0
- package/dist/registry-routing.js +165 -0
- package/dist/registry-routing.js.map +1 -0
- package/dist/registry-runtime.d.ts +2 -0
- package/dist/registry-runtime.d.ts.map +1 -1
- package/dist/registry-runtime.js +159 -15
- package/dist/registry-runtime.js.map +1 -1
- package/dist/registry-selection.js +6 -0
- package/dist/registry-selection.js.map +1 -1
- package/dist/registry.d.ts +69 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +133 -1
- package/dist/registry.js.map +1 -1
- package/dist/resilience.d.ts +15 -0
- package/dist/resilience.d.ts.map +1 -1
- package/dist/resilience.js +23 -1
- package/dist/resilience.js.map +1 -1
- package/dist/server.d.ts +44 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +328 -33
- package/dist/server.js.map +1 -1
- package/dist/tally.d.ts +80 -0
- package/dist/tally.d.ts.map +1 -0
- package/dist/tally.js +176 -0
- package/dist/tally.js.map +1 -0
- package/dist/types.d.ts +22 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/wire-anthropic.d.ts +264 -0
- package/dist/wire-anthropic.d.ts.map +1 -0
- package/dist/wire-anthropic.js +960 -0
- package/dist/wire-anthropic.js.map +1 -0
- package/package.json +14 -10
- package/logo.png +0 -0
package/dist/cli-help.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-help.js","sourceRoot":"","sources":["../src/cli-help.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACN,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAC5C,CAAC,GACD,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,QAAQ,GAAG,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"cli-help.js","sourceRoot":"","sources":["../src/cli-help.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { ModelRegistry } from "./registry.js";
|
|
15
15
|
import { DIM, RED, c } from "./cli-format.js";
|
|
16
|
+
import { cmdDoctor } from "./cli-cmd-doctor.js";
|
|
17
|
+
import { cmdSpend } from "./cli-cmd-spend.js";
|
|
16
18
|
import { cmdCapabilities, cmdCapable, cmdCheapest, cmdDiscover, cmdEnrich, cmdLatest, cmdList, cmdModel, cmdProviders, cmdRefresh, cmdResolve, cmdRoles, cmdRoutes, cmdSearch, cmdServe, showHelp, showSplash, showVersion, } from "./cli-commands.js";
|
|
17
19
|
/**
|
|
18
20
|
* Parse a raw argv slice into positional tokens and named flags.
|
|
@@ -133,6 +135,14 @@ async function main() {
|
|
|
133
135
|
case "update":
|
|
134
136
|
await cmdRefresh(registry, flags);
|
|
135
137
|
break;
|
|
138
|
+
case "doctor":
|
|
139
|
+
case "health":
|
|
140
|
+
await cmdDoctor(registry, flags);
|
|
141
|
+
break;
|
|
142
|
+
case "spend":
|
|
143
|
+
case "usage":
|
|
144
|
+
await cmdSpend(registry, flags);
|
|
145
|
+
break;
|
|
136
146
|
default:
|
|
137
147
|
console.error(c(RED, `Unknown command: "${command}"`));
|
|
138
148
|
console.error(c(DIM, 'Run "kosha --help" for usage information.'));
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/cost.d.ts
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kosha-discovery — Cost primitives shared by the proxy and the CLI.
|
|
3
|
+
*
|
|
4
|
+
* Three pieces, all pure synthesis over the model + provider catalog:
|
|
5
|
+
* - Pre-flight cost estimation (input + expected-output tokens × rates).
|
|
6
|
+
* - JSONL spend ledger persisted under `~/.kosha/`, partitioned one file
|
|
7
|
+
* per calendar month (`ledger-YYYY-MM.jsonl`) so the budget gate only
|
|
8
|
+
* ever scans the month it cares about — not the full history. The legacy
|
|
9
|
+
* append-only `ledger.jsonl` is still read for backward compat so
|
|
10
|
+
* existing installs keep working until it stops growing.
|
|
11
|
+
* - Monthly budget gate driven by `KOSHA_MONTHLY_BUDGET_USD`.
|
|
12
|
+
*
|
|
13
|
+
* No tokenizer dependency — request bodies travel through the proxy
|
|
14
|
+
* untouched, so we approximate input tokens with a coarse char→token ratio.
|
|
15
|
+
* @module
|
|
16
|
+
*/
|
|
17
|
+
import type { ModelCard } from "./types.js";
|
|
18
|
+
/** A single completion record written to the ledger. */
|
|
19
|
+
export interface LedgerEntry {
|
|
20
|
+
ts: number;
|
|
21
|
+
provider: string;
|
|
22
|
+
modelId: string;
|
|
23
|
+
requested: string;
|
|
24
|
+
tenant: string | null;
|
|
25
|
+
/** Estimated total cost in USD. */
|
|
26
|
+
estimatedUsd: number;
|
|
27
|
+
/** Input tokens estimated from the forwarded request body. */
|
|
28
|
+
estimatedInputTokens: number;
|
|
29
|
+
/** Output tokens the caller asked for (or our fallback). */
|
|
30
|
+
estimatedOutputTokens: number;
|
|
31
|
+
upstreamStatus: number;
|
|
32
|
+
/** Reconciled cost from the provider's `usage` block, when it returned one. */
|
|
33
|
+
actualUsd?: number;
|
|
34
|
+
/** Uncached input tokens the provider billed. */
|
|
35
|
+
actualInputTokens?: number;
|
|
36
|
+
/** Output tokens the provider billed. */
|
|
37
|
+
actualOutputTokens?: number;
|
|
38
|
+
/** Cache-read (hit) input tokens the provider reported. */
|
|
39
|
+
cacheReadTokens?: number;
|
|
40
|
+
/** Cache-write (creation) input tokens the provider reported. */
|
|
41
|
+
cacheWriteTokens?: number;
|
|
42
|
+
/** `upstream` when the actual* fields came from the provider; `estimate` when only the pre-flight numbers exist. */
|
|
43
|
+
usageSource?: "upstream" | "estimate";
|
|
44
|
+
/**
|
|
45
|
+
* `request` (default) for the row written when a request completes;
|
|
46
|
+
* `adjustment` for a follow-up row that corrects an earlier estimate once
|
|
47
|
+
* the upstream usage arrived (streaming responses). Adjustment rows carry
|
|
48
|
+
* deltas, so summing every row's {@link ledgerRowUsd} yields actual spend.
|
|
49
|
+
*/
|
|
50
|
+
kind?: "request" | "adjustment";
|
|
51
|
+
/** Correlates an adjustment with the request row it amends. */
|
|
52
|
+
requestId?: string;
|
|
53
|
+
/** Adjustment rows only: actual − estimated, in USD (may be negative). */
|
|
54
|
+
adjustmentUsd?: number;
|
|
55
|
+
/** Adjustment rows only: actual − estimated input tokens. */
|
|
56
|
+
adjustmentInputTokens?: number;
|
|
57
|
+
/** Adjustment rows only: actual − estimated output tokens. */
|
|
58
|
+
adjustmentOutputTokens?: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The USD figure a ledger row contributes to spend: an adjustment row's
|
|
62
|
+
* delta; otherwise the reconciled upstream cost when the row has one, the
|
|
63
|
+
* pre-flight estimate if not. Every reader (budget gate, `kosha spend`,
|
|
64
|
+
* /metrics) goes through this so they agree.
|
|
65
|
+
*/
|
|
66
|
+
export declare function ledgerRowUsd(row: Pick<LedgerEntry, "estimatedUsd" | "actualUsd" | "kind" | "adjustmentUsd">): number;
|
|
67
|
+
/** True for rows that represent a completed request (not a later correction). */
|
|
68
|
+
export declare function isRequestRow(row: Pick<LedgerEntry, "kind">): boolean;
|
|
69
|
+
/** Reconciled cost derived from a provider's `usage` block. */
|
|
70
|
+
export interface ActualUsageCost {
|
|
71
|
+
usd: number;
|
|
72
|
+
inputTokens: number;
|
|
73
|
+
outputTokens: number;
|
|
74
|
+
cacheReadTokens: number;
|
|
75
|
+
cacheWriteTokens: number;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Which accounting convention the usage block follows:
|
|
79
|
+
* - `openai` — `prompt_tokens` already includes cached tokens
|
|
80
|
+
* (`prompt_tokens_details.cached_tokens` is a subset).
|
|
81
|
+
* - `anthropic` — `input_tokens` excludes cache reads / writes, which are
|
|
82
|
+
* reported separately and billed at their own rates.
|
|
83
|
+
*/
|
|
84
|
+
export type UsageShape = "openai" | "anthropic";
|
|
85
|
+
/**
|
|
86
|
+
* Turn a provider `usage` block into a reconciled USD cost against the
|
|
87
|
+
* model's pricing. Returns null when the model has no usable pricing or the
|
|
88
|
+
* block carries no token counts. Cache rates fall back to the provider's
|
|
89
|
+
* published ratios (Anthropic: reads 0.1×, writes 1.25× input; OpenAI: reads
|
|
90
|
+
* 0.5× input) when the catalog entry lacks explicit cache pricing, so a
|
|
91
|
+
* cached request is never priced as if it were fully uncached.
|
|
92
|
+
*/
|
|
93
|
+
export declare function actualCostFromUsage(model: ModelCard, rawUsage: unknown, shape: UsageShape): ActualUsageCost | null;
|
|
94
|
+
export declare const DEFAULT_LEDGER_PATH: string;
|
|
95
|
+
export interface CostEstimate {
|
|
96
|
+
estimatedUsd: number;
|
|
97
|
+
inputTokens: number;
|
|
98
|
+
expectedOutputTokens: number;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Estimate the USD cost of forwarding `requestBody` to `model`. Returns null
|
|
102
|
+
* when the model has no usable pricing — the caller should treat that as
|
|
103
|
+
* "cost unknown" rather than free.
|
|
104
|
+
*/
|
|
105
|
+
export declare function estimateRequestCost(model: ModelCard, requestBody: Record<string, unknown>): CostEstimate | null;
|
|
106
|
+
/**
|
|
107
|
+
* Read `KOSHA_MONTHLY_BUDGET_USD` (if any). Returns null when no budget is
|
|
108
|
+
* configured — the proxy's budget gate then becomes a no-op. This cap is
|
|
109
|
+
* global: it is always compared against total spend, never a tenant's slice,
|
|
110
|
+
* so a caller cannot escape it by inventing a fresh tenant tag.
|
|
111
|
+
*/
|
|
112
|
+
export declare function readMonthlyBudgetUsd(): number | null;
|
|
113
|
+
/**
|
|
114
|
+
* Read `KOSHA_TENANT_BUDGET_USD` (if any): an additional per-tenant monthly
|
|
115
|
+
* cap applied on top of the global one to requests that carry a tenant tag.
|
|
116
|
+
*/
|
|
117
|
+
export declare function readTenantBudgetUsd(): number | null;
|
|
118
|
+
/**
|
|
119
|
+
* Sum estimated USD spend for entries falling in the calendar month that
|
|
120
|
+
* contains `nowMs`. Tenant scopes the sum when given.
|
|
121
|
+
*
|
|
122
|
+
* Reads only the month's partition (`ledger-YYYY-MM.jsonl` next to
|
|
123
|
+
* `ledgerPath`) plus, for backward compat, the legacy append-only
|
|
124
|
+
* `ledgerPath` itself — so existing installs whose history still lives in
|
|
125
|
+
* the un-partitioned file keep counting until that file stops growing. At
|
|
126
|
+
* most two files are read, never the full history.
|
|
127
|
+
*/
|
|
128
|
+
export declare function readSpendForMonth(nowMs: number, tenant?: string | null, ledgerPath?: string): Promise<number>;
|
|
129
|
+
/**
|
|
130
|
+
* Drop monthly partition files older than the retention window. Best-effort:
|
|
131
|
+
* errors are swallowed because retention is housekeeping, not correctness.
|
|
132
|
+
* The legacy `ledgerPath` file itself is never touched — only
|
|
133
|
+
* `ledger-YYYY-MM.jsonl` siblings are eligible. Returns the count of
|
|
134
|
+
* partitions removed (handy for tests / a future `kosha ledger trim`).
|
|
135
|
+
*
|
|
136
|
+
* The window is "current month plus `retentionMonths - 1` prior months", so
|
|
137
|
+
* the default of 12 keeps a rolling year. Exported so the CLI can run an
|
|
138
|
+
* explicit sweep without waiting for an append.
|
|
139
|
+
*/
|
|
140
|
+
export declare function trimLedgerPartitions(ledgerPath: string, nowMs: number, retentionMonths?: number): Promise<number>;
|
|
141
|
+
/**
|
|
142
|
+
* Append one ledger entry atomically. The entry is written to the monthly
|
|
143
|
+
* partition for its own `ts` (`ledger-YYYY-MM.jsonl`), keeping each file
|
|
144
|
+
* bounded to a single month so budget reads don't scan the full history.
|
|
145
|
+
*
|
|
146
|
+
* Writes are append-only so concurrent processes don't clobber each other.
|
|
147
|
+
* A best-effort atomic create-and-rename is used if the first append hits
|
|
148
|
+
* ENOENT, so a fresh install comes up cleanly. After the write we run a
|
|
149
|
+
* best-effort retention trim so old partitions age out without a cron job.
|
|
150
|
+
*/
|
|
151
|
+
export declare function appendLedgerEntry(entry: LedgerEntry, ledgerPath?: string): Promise<void>;
|
|
152
|
+
//# sourceMappingURL=cost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"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"}
|
package/dist/cost.js
ADDED
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kosha-discovery — Cost primitives shared by the proxy and the CLI.
|
|
3
|
+
*
|
|
4
|
+
* Three pieces, all pure synthesis over the model + provider catalog:
|
|
5
|
+
* - Pre-flight cost estimation (input + expected-output tokens × rates).
|
|
6
|
+
* - JSONL spend ledger persisted under `~/.kosha/`, partitioned one file
|
|
7
|
+
* per calendar month (`ledger-YYYY-MM.jsonl`) so the budget gate only
|
|
8
|
+
* ever scans the month it cares about — not the full history. The legacy
|
|
9
|
+
* append-only `ledger.jsonl` is still read for backward compat so
|
|
10
|
+
* existing installs keep working until it stops growing.
|
|
11
|
+
* - Monthly budget gate driven by `KOSHA_MONTHLY_BUDGET_USD`.
|
|
12
|
+
*
|
|
13
|
+
* No tokenizer dependency — request bodies travel through the proxy
|
|
14
|
+
* untouched, so we approximate input tokens with a coarse char→token ratio.
|
|
15
|
+
* @module
|
|
16
|
+
*/
|
|
17
|
+
import { appendFile, mkdir, readFile, readdir, rename, unlink, writeFile } from "fs/promises";
|
|
18
|
+
import { randomBytes } from "crypto";
|
|
19
|
+
import { homedir } from "os";
|
|
20
|
+
import { dirname, join } from "path";
|
|
21
|
+
import { normalizeTokenUsage } from "./tally.js";
|
|
22
|
+
/**
|
|
23
|
+
* The USD figure a ledger row contributes to spend: an adjustment row's
|
|
24
|
+
* delta; otherwise the reconciled upstream cost when the row has one, the
|
|
25
|
+
* pre-flight estimate if not. Every reader (budget gate, `kosha spend`,
|
|
26
|
+
* /metrics) goes through this so they agree.
|
|
27
|
+
*/
|
|
28
|
+
export function ledgerRowUsd(row) {
|
|
29
|
+
if (row.kind === "adjustment") {
|
|
30
|
+
return typeof row.adjustmentUsd === "number" && Number.isFinite(row.adjustmentUsd) ? row.adjustmentUsd : 0;
|
|
31
|
+
}
|
|
32
|
+
if (typeof row.actualUsd === "number" && Number.isFinite(row.actualUsd))
|
|
33
|
+
return row.actualUsd;
|
|
34
|
+
return typeof row.estimatedUsd === "number" && Number.isFinite(row.estimatedUsd) ? row.estimatedUsd : 0;
|
|
35
|
+
}
|
|
36
|
+
/** True for rows that represent a completed request (not a later correction). */
|
|
37
|
+
export function isRequestRow(row) {
|
|
38
|
+
return row.kind !== "adjustment";
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Turn a provider `usage` block into a reconciled USD cost against the
|
|
42
|
+
* model's pricing. Returns null when the model has no usable pricing or the
|
|
43
|
+
* block carries no token counts. Cache rates fall back to the provider's
|
|
44
|
+
* published ratios (Anthropic: reads 0.1×, writes 1.25× input; OpenAI: reads
|
|
45
|
+
* 0.5× input) when the catalog entry lacks explicit cache pricing, so a
|
|
46
|
+
* cached request is never priced as if it were fully uncached.
|
|
47
|
+
*/
|
|
48
|
+
export function actualCostFromUsage(model, rawUsage, shape) {
|
|
49
|
+
const pricing = model.pricing;
|
|
50
|
+
if (!pricing || typeof pricing.inputPerMillion !== "number" || typeof pricing.outputPerMillion !== "number")
|
|
51
|
+
return null;
|
|
52
|
+
if (!rawUsage || typeof rawUsage !== "object")
|
|
53
|
+
return null;
|
|
54
|
+
const usage = normalizeTokenUsage(rawUsage);
|
|
55
|
+
if (!usage)
|
|
56
|
+
return null;
|
|
57
|
+
const cacheRead = usage.cachedInputTokens ?? 0;
|
|
58
|
+
const cacheWrite = usage.cacheWriteTokens ?? 0;
|
|
59
|
+
const uncachedInput = shape === "openai" ? Math.max(0, usage.inputTokens - cacheRead) : usage.inputTokens;
|
|
60
|
+
const readRate = pricing.cacheReadPerMillion ?? pricing.inputPerMillion * (shape === "anthropic" ? 0.1 : 0.5);
|
|
61
|
+
const writeRate = pricing.cacheWritePerMillion ?? (shape === "anthropic" ? pricing.inputPerMillion * 1.25 : 0);
|
|
62
|
+
const usd = tokensTimesRate(uncachedInput, pricing.inputPerMillion) +
|
|
63
|
+
tokensTimesRate(usage.outputTokens, pricing.outputPerMillion) +
|
|
64
|
+
tokensTimesRate(cacheRead, readRate) +
|
|
65
|
+
tokensTimesRate(cacheWrite, writeRate);
|
|
66
|
+
if (!Number.isFinite(usd) || usd < 0)
|
|
67
|
+
return null;
|
|
68
|
+
return { usd, inputTokens: uncachedInput, outputTokens: usage.outputTokens, cacheReadTokens: cacheRead, cacheWriteTokens: cacheWrite };
|
|
69
|
+
}
|
|
70
|
+
export const DEFAULT_LEDGER_PATH = join(homedir(), ".kosha", "ledger.jsonl");
|
|
71
|
+
/**
|
|
72
|
+
* How many monthly partitions to retain on disk. Older partitions are
|
|
73
|
+
* trimmed opportunistically on append. Tunable via
|
|
74
|
+
* `KOSHA_LEDGER_RETENTION_MONTHS`; non-positive / unparseable values fall
|
|
75
|
+
* back to the default. The legacy `ledger.jsonl` is never trimmed by the
|
|
76
|
+
* partition sweeper — only `ledger-YYYY-MM.jsonl` siblings are.
|
|
77
|
+
*/
|
|
78
|
+
const DEFAULT_RETENTION_MONTHS = 12;
|
|
79
|
+
/**
|
|
80
|
+
* Conservative chars-per-token used when we don't have a tokenizer wired up.
|
|
81
|
+
* This is intentionally lower than the OpenAI rule of thumb (~4) so the
|
|
82
|
+
* estimate skews high; underestimating spend is the dangerous direction.
|
|
83
|
+
*/
|
|
84
|
+
const CHARS_PER_TOKEN = 3.5;
|
|
85
|
+
/** Output tokens to assume when the caller doesn't request `max_tokens`. */
|
|
86
|
+
const DEFAULT_EXPECTED_OUTPUT_TOKENS = 512;
|
|
87
|
+
/** Per-MTok rates are stored in USD; price = (tokens/1_000_000) * rate. */
|
|
88
|
+
function tokensTimesRate(tokens, perMillion) {
|
|
89
|
+
return (tokens / 1_000_000) * perMillion;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Estimate the USD cost of forwarding `requestBody` to `model`. Returns null
|
|
93
|
+
* when the model has no usable pricing — the caller should treat that as
|
|
94
|
+
* "cost unknown" rather than free.
|
|
95
|
+
*/
|
|
96
|
+
export function estimateRequestCost(model, requestBody) {
|
|
97
|
+
const pricing = model.pricing;
|
|
98
|
+
if (!pricing)
|
|
99
|
+
return null;
|
|
100
|
+
if (typeof pricing.inputPerMillion !== "number" || typeof pricing.outputPerMillion !== "number")
|
|
101
|
+
return null;
|
|
102
|
+
const inputTokens = approximateInputTokens(requestBody);
|
|
103
|
+
// `max_completion_tokens` is OpenAI's current spelling; `max_tokens` the legacy one.
|
|
104
|
+
const requestedOutput = typeof requestBody.max_completion_tokens === "number" && requestBody.max_completion_tokens > 0
|
|
105
|
+
? requestBody.max_completion_tokens
|
|
106
|
+
: typeof requestBody.max_tokens === "number" && requestBody.max_tokens > 0
|
|
107
|
+
? requestBody.max_tokens
|
|
108
|
+
: undefined;
|
|
109
|
+
const expectedOutputTokens = requestedOutput !== undefined ? Math.floor(requestedOutput) : DEFAULT_EXPECTED_OUTPUT_TOKENS;
|
|
110
|
+
const estimatedUsd = tokensTimesRate(inputTokens, pricing.inputPerMillion) +
|
|
111
|
+
tokensTimesRate(expectedOutputTokens, pricing.outputPerMillion);
|
|
112
|
+
return { estimatedUsd, inputTokens, expectedOutputTokens };
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Approximate input token count by walking the OpenAI-style `messages`
|
|
116
|
+
* array, falling back to total stringified body length. Intentionally
|
|
117
|
+
* conservative (small CHARS_PER_TOKEN) so the estimate doesn't undershoot.
|
|
118
|
+
*/
|
|
119
|
+
function approximateInputTokens(body) {
|
|
120
|
+
const messages = body.messages;
|
|
121
|
+
if (Array.isArray(messages)) {
|
|
122
|
+
let chars = 0;
|
|
123
|
+
for (const msg of messages) {
|
|
124
|
+
if (!msg || typeof msg !== "object")
|
|
125
|
+
continue;
|
|
126
|
+
const content = msg.content;
|
|
127
|
+
if (typeof content === "string") {
|
|
128
|
+
chars += content.length;
|
|
129
|
+
}
|
|
130
|
+
else if (Array.isArray(content)) {
|
|
131
|
+
for (const part of content) {
|
|
132
|
+
if (typeof part === "string")
|
|
133
|
+
chars += part.length;
|
|
134
|
+
else if (part && typeof part === "object" && typeof part.text === "string") {
|
|
135
|
+
chars += part.text.length;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (chars > 0)
|
|
141
|
+
return Math.ceil(chars / CHARS_PER_TOKEN);
|
|
142
|
+
}
|
|
143
|
+
const fallback = JSON.stringify(body).length;
|
|
144
|
+
return Math.ceil(fallback / CHARS_PER_TOKEN);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Read `KOSHA_MONTHLY_BUDGET_USD` (if any). Returns null when no budget is
|
|
148
|
+
* configured — the proxy's budget gate then becomes a no-op. This cap is
|
|
149
|
+
* global: it is always compared against total spend, never a tenant's slice,
|
|
150
|
+
* so a caller cannot escape it by inventing a fresh tenant tag.
|
|
151
|
+
*/
|
|
152
|
+
export function readMonthlyBudgetUsd() {
|
|
153
|
+
return readPositiveUsd(process.env.KOSHA_MONTHLY_BUDGET_USD);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Read `KOSHA_TENANT_BUDGET_USD` (if any): an additional per-tenant monthly
|
|
157
|
+
* cap applied on top of the global one to requests that carry a tenant tag.
|
|
158
|
+
*/
|
|
159
|
+
export function readTenantBudgetUsd() {
|
|
160
|
+
return readPositiveUsd(process.env.KOSHA_TENANT_BUDGET_USD);
|
|
161
|
+
}
|
|
162
|
+
function readPositiveUsd(raw) {
|
|
163
|
+
if (!raw)
|
|
164
|
+
return null;
|
|
165
|
+
const parsed = Number.parseFloat(raw);
|
|
166
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Sum estimated USD spend for entries falling in the calendar month that
|
|
170
|
+
* contains `nowMs`. Tenant scopes the sum when given.
|
|
171
|
+
*
|
|
172
|
+
* Reads only the month's partition (`ledger-YYYY-MM.jsonl` next to
|
|
173
|
+
* `ledgerPath`) plus, for backward compat, the legacy append-only
|
|
174
|
+
* `ledgerPath` itself — so existing installs whose history still lives in
|
|
175
|
+
* the un-partitioned file keep counting until that file stops growing. At
|
|
176
|
+
* most two files are read, never the full history.
|
|
177
|
+
*/
|
|
178
|
+
export async function readSpendForMonth(nowMs, tenant, ledgerPath = DEFAULT_LEDGER_PATH) {
|
|
179
|
+
const cutoffStart = startOfMonth(nowMs);
|
|
180
|
+
const cutoffEnd = startOfNextMonth(nowMs);
|
|
181
|
+
// The month partition is the hot path; the legacy file is the fallback
|
|
182
|
+
// for pre-partitioning history. Order matters only for readability —
|
|
183
|
+
// both are filtered by the same ts window below.
|
|
184
|
+
const sources = [partitionPathFor(ledgerPath, nowMs), ledgerPath];
|
|
185
|
+
let total = 0;
|
|
186
|
+
for (const file of sources) {
|
|
187
|
+
let raw;
|
|
188
|
+
try {
|
|
189
|
+
raw = await readFile(file, "utf-8");
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
// Missing file (partition not yet created, or legacy absent) is
|
|
193
|
+
// a clean "nothing here" — try the next source.
|
|
194
|
+
if (err?.code === "ENOENT")
|
|
195
|
+
continue;
|
|
196
|
+
throw err;
|
|
197
|
+
}
|
|
198
|
+
for (const line of raw.split("\n")) {
|
|
199
|
+
if (!line)
|
|
200
|
+
continue;
|
|
201
|
+
let row;
|
|
202
|
+
try {
|
|
203
|
+
row = JSON.parse(line);
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
continue; // skip corrupt lines, don't crash budget enforcement
|
|
207
|
+
}
|
|
208
|
+
if (row.ts < cutoffStart || row.ts >= cutoffEnd)
|
|
209
|
+
continue;
|
|
210
|
+
if (tenant && row.tenant !== tenant)
|
|
211
|
+
continue;
|
|
212
|
+
total += ledgerRowUsd(row);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return total;
|
|
216
|
+
}
|
|
217
|
+
/** Strip control characters and bound length on a ledger string field. The
|
|
218
|
+
* ledger records caller-supplied values (modelId, tenant tag, the original
|
|
219
|
+
* requested model string), so we sanitize them before writing to disk: each
|
|
220
|
+
* line stays a single, well-formed JSON record. Without this, a crafted
|
|
221
|
+
* model id with embedded CR/LF could split one row into two. */
|
|
222
|
+
function sanitizeLedgerString(value) {
|
|
223
|
+
return value.replace(/[\r\n\t]/g, "").slice(0, 256);
|
|
224
|
+
}
|
|
225
|
+
/** Apply sanitizeLedgerString to every string field of the entry. Numeric
|
|
226
|
+
* fields are pass-through. */
|
|
227
|
+
function sanitizeEntry(entry) {
|
|
228
|
+
return {
|
|
229
|
+
ts: entry.ts,
|
|
230
|
+
provider: sanitizeLedgerString(entry.provider),
|
|
231
|
+
modelId: sanitizeLedgerString(entry.modelId),
|
|
232
|
+
requested: sanitizeLedgerString(entry.requested),
|
|
233
|
+
tenant: entry.tenant === null ? null : sanitizeLedgerString(entry.tenant),
|
|
234
|
+
estimatedUsd: entry.estimatedUsd,
|
|
235
|
+
estimatedInputTokens: entry.estimatedInputTokens,
|
|
236
|
+
estimatedOutputTokens: entry.estimatedOutputTokens,
|
|
237
|
+
upstreamStatus: entry.upstreamStatus,
|
|
238
|
+
...(entry.actualUsd !== undefined ? { actualUsd: entry.actualUsd } : {}),
|
|
239
|
+
...(entry.actualInputTokens !== undefined ? { actualInputTokens: entry.actualInputTokens } : {}),
|
|
240
|
+
...(entry.actualOutputTokens !== undefined ? { actualOutputTokens: entry.actualOutputTokens } : {}),
|
|
241
|
+
...(entry.cacheReadTokens !== undefined ? { cacheReadTokens: entry.cacheReadTokens } : {}),
|
|
242
|
+
...(entry.cacheWriteTokens !== undefined ? { cacheWriteTokens: entry.cacheWriteTokens } : {}),
|
|
243
|
+
...(entry.usageSource !== undefined ? { usageSource: entry.usageSource } : {}),
|
|
244
|
+
...(entry.kind !== undefined ? { kind: entry.kind } : {}),
|
|
245
|
+
...(entry.requestId !== undefined ? { requestId: sanitizeLedgerString(entry.requestId) } : {}),
|
|
246
|
+
...(entry.adjustmentUsd !== undefined ? { adjustmentUsd: entry.adjustmentUsd } : {}),
|
|
247
|
+
...(entry.adjustmentInputTokens !== undefined ? { adjustmentInputTokens: entry.adjustmentInputTokens } : {}),
|
|
248
|
+
...(entry.adjustmentOutputTokens !== undefined ? { adjustmentOutputTokens: entry.adjustmentOutputTokens } : {}),
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/** `YYYY-MM` (zero-padded month) for the UTC calendar month containing ts.
|
|
252
|
+
* UTC matches startOfMonth/startOfNextMonth so the partition a row lands in
|
|
253
|
+
* is exactly the month the budget cutoffs bracket. */
|
|
254
|
+
function monthKeyFromTs(ts) {
|
|
255
|
+
const d = new Date(ts);
|
|
256
|
+
return `${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, "0")}`;
|
|
257
|
+
}
|
|
258
|
+
/** Parse a `YYYY-MM` key back to its UTC month-start epoch ms, or null when
|
|
259
|
+
* the shape is wrong. Used by trim to age partitions out deterministically. */
|
|
260
|
+
function monthStartFromKey(key) {
|
|
261
|
+
const m = /^(\d{4})-(\d{2})$/.exec(key);
|
|
262
|
+
if (!m)
|
|
263
|
+
return null;
|
|
264
|
+
const year = Number(m[1]);
|
|
265
|
+
const month = Number(m[2]) - 1; // JS months are 0-indexed
|
|
266
|
+
if (month < 0 || month > 11)
|
|
267
|
+
return null;
|
|
268
|
+
return Date.UTC(year, month, 1);
|
|
269
|
+
}
|
|
270
|
+
/** Path of the monthly partition file a given ts belongs in. Partitions are
|
|
271
|
+
* siblings of the legacy ledger file so they share its directory and perms. */
|
|
272
|
+
function partitionPathFor(ledgerPath, ts) {
|
|
273
|
+
return join(dirname(ledgerPath), `ledger-${monthKeyFromTs(ts)}.jsonl`);
|
|
274
|
+
}
|
|
275
|
+
/** Read the retention window from `KOSHA_LEDGER_RETENTION_MONTHS`, falling
|
|
276
|
+
* back to the default for missing/non-positive/unparseable values. */
|
|
277
|
+
function readRetentionMonths() {
|
|
278
|
+
const raw = process.env.KOSHA_LEDGER_RETENTION_MONTHS;
|
|
279
|
+
if (!raw)
|
|
280
|
+
return DEFAULT_RETENTION_MONTHS;
|
|
281
|
+
const parsed = Number.parseInt(raw, 10);
|
|
282
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_RETENTION_MONTHS;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Drop monthly partition files older than the retention window. Best-effort:
|
|
286
|
+
* errors are swallowed because retention is housekeeping, not correctness.
|
|
287
|
+
* The legacy `ledgerPath` file itself is never touched — only
|
|
288
|
+
* `ledger-YYYY-MM.jsonl` siblings are eligible. Returns the count of
|
|
289
|
+
* partitions removed (handy for tests / a future `kosha ledger trim`).
|
|
290
|
+
*
|
|
291
|
+
* The window is "current month plus `retentionMonths - 1` prior months", so
|
|
292
|
+
* the default of 12 keeps a rolling year. Exported so the CLI can run an
|
|
293
|
+
* explicit sweep without waiting for an append.
|
|
294
|
+
*/
|
|
295
|
+
export async function trimLedgerPartitions(ledgerPath, nowMs, retentionMonths = readRetentionMonths()) {
|
|
296
|
+
const dir = dirname(ledgerPath);
|
|
297
|
+
const d = new Date(nowMs);
|
|
298
|
+
// First month we keep: current month shifted back (N-1). Date.UTC wraps
|
|
299
|
+
// negative months into prior years correctly (month -5 of 2026 → Aug 2025).
|
|
300
|
+
const cutoffStart = Date.UTC(d.getUTCFullYear(), d.getUTCMonth() - (retentionMonths - 1), 1);
|
|
301
|
+
let entries;
|
|
302
|
+
try {
|
|
303
|
+
entries = await readdir(dir);
|
|
304
|
+
}
|
|
305
|
+
catch {
|
|
306
|
+
// No directory yet (ENOENT) or unreadable — nothing to trim.
|
|
307
|
+
return 0;
|
|
308
|
+
}
|
|
309
|
+
let removed = 0;
|
|
310
|
+
for (const name of entries) {
|
|
311
|
+
const m = /^ledger-(\d{4})-(\d{2})\.jsonl$/.exec(name);
|
|
312
|
+
if (!m)
|
|
313
|
+
continue;
|
|
314
|
+
const start = monthStartFromKey(`${m[1]}-${m[2]}`);
|
|
315
|
+
if (start === null || start >= cutoffStart)
|
|
316
|
+
continue;
|
|
317
|
+
await unlink(join(dir, name)).catch(() => {
|
|
318
|
+
// raced with another sweeper or permission issue — fine, best-effort
|
|
319
|
+
});
|
|
320
|
+
removed += 1;
|
|
321
|
+
}
|
|
322
|
+
return removed;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Append one ledger entry atomically. The entry is written to the monthly
|
|
326
|
+
* partition for its own `ts` (`ledger-YYYY-MM.jsonl`), keeping each file
|
|
327
|
+
* bounded to a single month so budget reads don't scan the full history.
|
|
328
|
+
*
|
|
329
|
+
* Writes are append-only so concurrent processes don't clobber each other.
|
|
330
|
+
* A best-effort atomic create-and-rename is used if the first append hits
|
|
331
|
+
* ENOENT, so a fresh install comes up cleanly. After the write we run a
|
|
332
|
+
* best-effort retention trim so old partitions age out without a cron job.
|
|
333
|
+
*/
|
|
334
|
+
export async function appendLedgerEntry(entry, ledgerPath = DEFAULT_LEDGER_PATH) {
|
|
335
|
+
await mkdir(dirname(ledgerPath), { recursive: true });
|
|
336
|
+
const partPath = partitionPathFor(ledgerPath, entry.ts);
|
|
337
|
+
const line = `${JSON.stringify(sanitizeEntry(entry))}\n`;
|
|
338
|
+
try {
|
|
339
|
+
await appendFile(partPath, line, "utf-8");
|
|
340
|
+
}
|
|
341
|
+
catch (err) {
|
|
342
|
+
// If append fails (e.g. permissions) we just swallow — ledger is
|
|
343
|
+
// observability, not load-bearing routing state. A best-effort
|
|
344
|
+
// create-and-rename gets us going on a fresh install.
|
|
345
|
+
if (err?.code === "ENOENT") {
|
|
346
|
+
const tmp = `${partPath}.${randomBytes(4).toString("hex")}.tmp`;
|
|
347
|
+
try {
|
|
348
|
+
await writeFile(tmp, line, "utf-8");
|
|
349
|
+
await rename(tmp, partPath);
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
// give up silently
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
// Opportunistic, best-effort retention sweep. Housekeeping must never
|
|
357
|
+
// break the append — the ledger is observability.
|
|
358
|
+
try {
|
|
359
|
+
await trimLedgerPartitions(ledgerPath, entry.ts);
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
// swallowed
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
function startOfMonth(nowMs) {
|
|
366
|
+
const d = new Date(nowMs);
|
|
367
|
+
// Important: pair `getUTCMonth()`/`getUTCFullYear()` with `Date.UTC()`.
|
|
368
|
+
// The numeric `new Date(year, month, …)` constructor interprets its args
|
|
369
|
+
// as LOCAL time, so the previous code drifted by up to ~24h around month
|
|
370
|
+
// boundaries in any non-UTC timezone — breaking budget cutoffs.
|
|
371
|
+
return Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), 1);
|
|
372
|
+
}
|
|
373
|
+
function startOfNextMonth(nowMs) {
|
|
374
|
+
const d = new Date(nowMs);
|
|
375
|
+
return Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + 1, 1);
|
|
376
|
+
}
|
|
377
|
+
//# sourceMappingURL=cost.js.map
|
package/dist/cost.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.js","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,6 +29,16 @@ import type { CredentialResult } from "../types.js";
|
|
|
29
29
|
export declare class CredentialResolver {
|
|
30
30
|
private readonly home;
|
|
31
31
|
private readonly isWindows;
|
|
32
|
+
/**
|
|
33
|
+
* Return every plausible config-directory path for a per-tool config file,
|
|
34
|
+
* in resolution order. We honour both common Linux conventions
|
|
35
|
+
* (`$XDG_CONFIG_HOME/<tool>`, `~/.config/<tool>`) and the Windows
|
|
36
|
+
* convention (`%APPDATA%\<tool>`), so a user with credentials in any
|
|
37
|
+
* standard location is found rather than silently skipped.
|
|
38
|
+
*/
|
|
39
|
+
private toolConfigCandidates;
|
|
40
|
+
/** Read the first existing JSON file from a list of candidate paths. */
|
|
41
|
+
private readFirstJson;
|
|
32
42
|
/**
|
|
33
43
|
* Resolve credentials for the given provider.
|
|
34
44
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/credentials/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD;;;;;;;;;;GAUG;AACH,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IAEpD;;;;;;;OAOG;IACG,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/credentials/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD;;;;;;;;;;GAUG;AACH,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IAEpD;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IAU5B,wEAAwE;YAC1D,aAAa;IAQ3B;;;;;;;OAOG;IACG,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAmDjF;IAMD;;;;;;;;OAQG;YACW,gBAAgB;IAuD9B;;;;;;OAMG;YACW,aAAa;IA2C3B;;;;;;OAMG;YACW,aAAa;IA4C3B;;;;;OAKG;YACW,iBAAiB;IAoB/B;;;;;OAKG;YACW,sBAAsB;IAsBpC;;;OAGG;IACH,OAAO,CAAC,aAAa;IAQrB;;;;;;;;;;;;;OAaG;YACW,wBAAwB;IAqDtC;;;;;;;;;OASG;YACW,gBAAgB;IAsB9B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,kBAAkB;IA2C1B;;;;;;;;;;;;;;OAcG;YACW,uBAAuB;IA0CrC;;;;;;;OAOG;YACW,qBAAqB;IAkBnC;;;OAGG;IACH,OAAO,CAAC,eAAe;IAavB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAkBzB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,kBAAkB;IAmB1B,oEAAoE;YACtD,QAAQ;IAStB,sEAAsE;YACxD,YAAY;IAQ1B,8DAA8D;IAC9D,OAAO,CAAC,eAAe;IAiBvB,6CAA6C;IAC7C,OAAO,CAAC,cAAc;IAetB,8EAA8E;IAC9E,OAAO,CAAC,mBAAmB;CAS3B"}
|