dsh-opencode-go 0.2.0 → 0.2.1
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.en.md +20 -18
- package/README.md +26 -18
- package/THIRD_PARTY_NOTICES.md +5 -1
- package/docs/advanced.en.md +17 -13
- package/docs/advanced.md +18 -13
- package/docs/assets/usage-history-desktop.jpg +0 -0
- package/docs/assets/usage-history-mobile.jpg +0 -0
- package/docs/assets/usage-history-models.jpg +0 -0
- package/docs/development.md +23 -9
- package/docs/usage-analytics.en.md +34 -85
- package/docs/usage-analytics.md +34 -85
- package/docs/verification.md +50 -13
- package/lib/build-info.json +1 -1
- package/lib/client.js +2111 -2257
- package/lib/free-http-worker.js +32 -0
- package/lib/index.js +3078 -1899
- package/lib/types/accounts.d.ts +2 -2
- package/lib/types/adapter.d.ts +24 -9
- package/lib/types/analytics.d.ts +22 -332
- package/lib/types/catalog.d.ts +35 -76
- package/lib/types/client/AnalyticsDialog.d.ts +11 -18
- package/lib/types/client/Section.d.ts +3 -13
- package/lib/types/client/UsagePill.d.ts +10 -3
- package/lib/types/client/controller.d.ts +10 -8
- package/lib/types/client/dashboard-copy.d.ts +58 -0
- package/lib/types/client/index.d.ts +9 -0
- package/lib/types/client/presentation.d.ts +36 -72
- package/lib/types/config.d.ts +5 -1
- package/lib/types/contracts.d.ts +80 -25
- package/lib/types/conversion.d.ts +10 -2
- package/lib/types/free-channel.d.ts +21 -0
- package/lib/types/free-http-worker.d.ts +1 -0
- package/lib/types/free-policy.d.ts +4 -0
- package/lib/types/free-protocol.d.ts +16 -0
- package/lib/types/free-runtime.d.ts +2 -0
- package/lib/types/free-socks-tunnel.d.ts +4 -0
- package/lib/types/free-transport.d.ts +19 -0
- package/lib/types/index.d.ts +1 -1
- package/lib/types/pricing.d.ts +29 -0
- package/lib/types/sdk-types.d.ts +1577 -2890
- package/lib/types/transport.d.ts +13 -5
- package/lib/vendor-licenses.txt +79 -55
- package/package.json +4 -4
- package/docs/assets/usage-panel.png +0 -0
package/lib/types/accounts.d.ts
CHANGED
|
@@ -33,9 +33,9 @@ export interface AttemptOutcome {
|
|
|
33
33
|
aborted: boolean;
|
|
34
34
|
hasNext: boolean;
|
|
35
35
|
}
|
|
36
|
-
/** Switching accounts must never replay output or
|
|
36
|
+
/** Switching accounts must never replay output, charged work or model permission failures. */
|
|
37
37
|
export declare function accountFallback(outcome: AttemptOutcome): GoAccountSwitch['reason'] | undefined;
|
|
38
|
-
/**
|
|
38
|
+
/** Only credential, rate and quota failures cool down a key; PERMISSION_DENIED is model-scoped. */
|
|
39
39
|
export declare function isGatewayKeyRejection(failure: {
|
|
40
40
|
code: string;
|
|
41
41
|
}): boolean;
|
package/lib/types/adapter.d.ts
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
/** Request snapshots, SDK dispatch, deadlines and seamless account fallback. */
|
|
2
|
-
import { type OpencodeGoModelLimits, type GoAccountSwitch } from './contracts.ts';
|
|
2
|
+
import { type OpencodeGoModelLimits, type GoAccountSwitch, type ModelSource } from './contracts.ts';
|
|
3
3
|
import { type GenerateOptions, type ImageAttachmentAccess, type StreamChunk, LlmAdapter, type LlmModelInfo, type LlmResolvedModelInfo } from '@deepseek-ai/dsh-llm';
|
|
4
4
|
import type { AttachmentStore, ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';
|
|
5
5
|
import type { Api, Model, Provider } from './sdk-types.ts';
|
|
6
6
|
import { type OpencodeGoConfig } from './config.ts';
|
|
7
7
|
import { ProxyTransport } from './transport.ts';
|
|
8
8
|
import { OpencodeGoCatalog } from './catalog.ts';
|
|
9
|
+
import { FreeBunTransport } from './free-transport.ts';
|
|
10
|
+
import { FreeChannelState } from './free-channel.ts';
|
|
9
11
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* Per-model settings continue to cap caller values for every model. The model
|
|
13
|
-
* has already had capacity overrides applied.
|
|
12
|
+
* Cap large models at 64k unless the caller or settings specify an allowance.
|
|
13
|
+
* Per-model settings continue to cap explicit caller values.
|
|
14
14
|
*/
|
|
15
15
|
export declare function requestMaxTokens(model: {
|
|
16
16
|
id: string;
|
|
17
17
|
maxTokens: number;
|
|
18
|
+
source?: ModelSource;
|
|
18
19
|
}, limits: OpencodeGoModelLimits, requested?: number): number | undefined;
|
|
19
20
|
/**
|
|
20
21
|
* The attachment-service bridges one image request reads. Construction-time
|
|
@@ -29,6 +30,8 @@ export interface OpencodeGoImageAccess {
|
|
|
29
30
|
}
|
|
30
31
|
/** Host dependencies used by a single attempt, independent of account selection. */
|
|
31
32
|
export interface OpencodeGoRequestExecutorOptions {
|
|
33
|
+
/** Free-only passive backoff; never consulted by the Go executor. */
|
|
34
|
+
freeChannel?: FreeChannelState;
|
|
32
35
|
/** Resolve the credential reference captured with this call's endpoint; missing must fail loud. */
|
|
33
36
|
resolveApiKey: (config: OpencodeGoConfig, signal?: AbortSignal) => Promise<string | undefined>;
|
|
34
37
|
/**
|
|
@@ -45,14 +48,17 @@ export interface OpencodeGoRequestSnapshot {
|
|
|
45
48
|
model: Model<Api>;
|
|
46
49
|
provider: Provider;
|
|
47
50
|
sessionId: string;
|
|
51
|
+
apiKey?: string;
|
|
48
52
|
}
|
|
49
53
|
/** Shares the adapter's transport without owning its lifetime or retrying accounts. */
|
|
50
54
|
export declare class OpencodeGoRequestExecutor {
|
|
51
55
|
private readonly options;
|
|
52
56
|
private readonly transport;
|
|
53
|
-
|
|
57
|
+
private readonly freeTransport;
|
|
58
|
+
constructor(options: OpencodeGoRequestExecutorOptions, transport: ProxyTransport, freeTransport?: FreeBunTransport);
|
|
54
59
|
/** One account, one SDK attempt; host recovery still owns failures after output. */
|
|
55
60
|
stream(options: GenerateOptions, snapshot: OpencodeGoRequestSnapshot): AsyncIterable<StreamChunk>;
|
|
61
|
+
private attempt;
|
|
56
62
|
}
|
|
57
63
|
/** One request's serving account, with the identity captured before discovery. */
|
|
58
64
|
export interface GoAccountSettlement {
|
|
@@ -64,6 +70,7 @@ export interface GoAccountSettlement {
|
|
|
64
70
|
}
|
|
65
71
|
/** Constructor inputs for {@link OpencodeGoAdapter}. */
|
|
66
72
|
export interface OpencodeGoAdapterOptions extends OpencodeGoRequestExecutorOptions {
|
|
73
|
+
source?: ModelSource;
|
|
67
74
|
/** Shared with Host usage reads for this plugin mount. */
|
|
68
75
|
transport?: ProxyTransport;
|
|
69
76
|
/** Mount-owned discovery; direct construction supplies its own manager. */
|
|
@@ -74,40 +81,46 @@ export interface OpencodeGoAdapterOptions extends OpencodeGoRequestExecutorOptio
|
|
|
74
81
|
* two configuration generations.
|
|
75
82
|
*/
|
|
76
83
|
config: () => OpencodeGoConfig;
|
|
77
|
-
/** Observe
|
|
84
|
+
/** Observe discovery retaining its last successful directory. */
|
|
78
85
|
onFallback?: (detail: {
|
|
79
86
|
url: string;
|
|
80
87
|
error: unknown;
|
|
81
88
|
kept: number;
|
|
82
89
|
}) => void;
|
|
83
|
-
/** Observe
|
|
90
|
+
/** Observe chat rows with invalid or unsupported declarations. */
|
|
84
91
|
onOmitted?: (ids: readonly string[]) => void;
|
|
85
92
|
onCatalogWarning?: (warning: string) => void;
|
|
86
93
|
/** Re-read picker models after a background catalog refresh commits. */
|
|
87
94
|
onCatalogRefresh?: () => void;
|
|
88
95
|
/** Host account-state version for actual requests, captured before asynchronous model discovery. */
|
|
89
96
|
accountGeneration?: () => number;
|
|
97
|
+
/** Shared by both adapters so account settlement ordering spans both routes. */
|
|
98
|
+
nextCallSequence?: () => number;
|
|
90
99
|
/** One outcome for both the displayed notice and the persisted selection. */
|
|
91
100
|
onAccountSettled?: (event: GoAccountSettlement) => void;
|
|
92
101
|
/** Legacy notice observer. Hosts that persist selection should use onAccountSettled. */
|
|
93
102
|
onAccountSwitch?: (notice: GoAccountSwitch | undefined, config: OpencodeGoConfig, seq: number) => void;
|
|
94
103
|
}
|
|
95
104
|
/**
|
|
96
|
-
*
|
|
105
|
+
* One source's route adapter. The catalog snapshot freezes at each operation,
|
|
97
106
|
* so a refresh between two requests never mixes model generations inside one
|
|
98
107
|
* call.
|
|
99
108
|
*/
|
|
100
109
|
export declare class OpencodeGoAdapter extends LlmAdapter {
|
|
101
110
|
private readonly options;
|
|
111
|
+
private readonly source;
|
|
102
112
|
private readonly resolveCatalog;
|
|
103
113
|
private readonly transport;
|
|
104
114
|
private readonly requestExecutor;
|
|
115
|
+
private readonly freeTransport;
|
|
116
|
+
private readonly freeChannel;
|
|
105
117
|
/** Per-reference rejection deadlines, isolated by the gateway that rejected it. */
|
|
106
118
|
private readonly rejectedKeys;
|
|
107
119
|
/** Reference updates invalidate rejections from attempts using an older key. */
|
|
108
120
|
private readonly credentialVersions;
|
|
109
121
|
/** Monotonic sequence of the latest request this adapter started. */
|
|
110
122
|
private callSeq;
|
|
123
|
+
private nextCallSequence;
|
|
111
124
|
constructor(options: OpencodeGoAdapterOptions);
|
|
112
125
|
dispose(): Promise<void>;
|
|
113
126
|
/**
|
|
@@ -137,6 +150,8 @@ export declare class OpencodeGoAdapter extends LlmAdapter {
|
|
|
137
150
|
private streamWithSnapshot;
|
|
138
151
|
private dispatch;
|
|
139
152
|
private streamAccounts;
|
|
153
|
+
/** Resolve Free keys only when selecting an account or retrying a failed attempt. */
|
|
154
|
+
private accountCandidates;
|
|
140
155
|
private rememberRejectedKey;
|
|
141
156
|
/** A stored change to a reference outranks the gateway's last rejection of it. */
|
|
142
157
|
forgetRejectedKey(ref: string): void;
|
package/lib/types/analytics.d.ts
CHANGED
|
@@ -1,345 +1,35 @@
|
|
|
1
1
|
import type { Context } from '@deepseek-ai/cordis';
|
|
2
2
|
import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* model.cost); this file only carries what models.dev does not publish.
|
|
7
|
-
*
|
|
8
|
-
* Source: https://opencode.ai/v2/docs/console/go/ (Go and Go Plus tables).
|
|
9
|
-
* The snapshot is reviewed when the model list or the plan changes; the report
|
|
10
|
-
* shows {@link GO_PLAN_AS_OF}, so a stale table is visible rather than silent.
|
|
11
|
-
*
|
|
12
|
-
*/
|
|
13
|
-
/** Date the limits below were read from the official plan page. */
|
|
14
|
-
export declare const GO_PLAN_AS_OF = "2026-10-18";
|
|
15
|
-
/** Human-readable source for the limit snapshot. */
|
|
16
|
-
export declare const GO_PLAN_SOURCE = "https://opencode.ai/v2/docs/console/go/";
|
|
17
|
-
/** Why a row has no numeric limit. */
|
|
18
|
-
export type GoLimitNote = 'unlimited' | 'limited-time';
|
|
19
|
-
/** One model's monthly allowance on each plan (USD), or a note instead. */
|
|
20
|
-
export interface GoMonthlyLimit {
|
|
21
|
-
/** Go plan monthly limit in USD; null when the row is unlimited. */
|
|
22
|
-
readonly go: number | null;
|
|
23
|
-
/** Go Plus plan monthly limit in USD; null when the row is unlimited. */
|
|
24
|
-
readonly goPlus: number | null;
|
|
25
|
-
readonly note?: GoLimitNote;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Monthly limits by model id. Promo rows use the effective (post-strike-through)
|
|
29
|
-
* value and carry {@link GoLimitNote} 'limited-time'; free rows are unlimited.
|
|
30
|
-
*/
|
|
31
|
-
export declare const GO_MONTHLY_LIMITS: Readonly<Record<string, GoMonthlyLimit>>;
|
|
32
|
-
/**
|
|
33
|
-
* Read one model's limit snapshot.
|
|
34
|
-
* @param model - catalog model id.
|
|
35
|
-
* @returns the row, or undefined when the plan page lists no such model.
|
|
36
|
-
*/
|
|
37
|
-
export declare function goMonthlyLimit(model: string): GoMonthlyLimit | undefined;
|
|
38
|
-
/** Models with a documented peak/off-peak tariff (DeepSeek V4.1 Flash and V4 Pro). */
|
|
39
|
-
export declare const PEAK_PRICED_MODELS: ReadonlySet<string>;
|
|
40
|
-
/**
|
|
41
|
-
* Whether a request started inside the documented DeepSeek peak window:
|
|
42
|
-
* 01:00-04:00 and 06:00-10:00 UTC, Monday through Friday. All other hours,
|
|
43
|
-
* including weekends, are off-peak.
|
|
44
|
-
* @param at - request start time in Unix epoch milliseconds.
|
|
45
|
-
* @returns true when the peak multiplier applies.
|
|
46
|
-
*/
|
|
47
|
-
export declare function isPeakPricedAt(at: number): boolean;
|
|
48
|
-
/** The four billable rates, in USD per one million tokens. */
|
|
49
|
-
export interface CostRates {
|
|
50
|
-
readonly input: number;
|
|
51
|
-
readonly output: number;
|
|
52
|
-
readonly cacheRead: number;
|
|
53
|
-
readonly cacheWrite: number;
|
|
54
|
-
}
|
|
55
|
-
/** One context-length tier; the highest matching threshold prices the attempt. */
|
|
56
|
-
export interface CostTier extends CostRates {
|
|
57
|
-
readonly inputTokensAbove: number;
|
|
58
|
-
}
|
|
59
|
-
/** Structural face of the catalog's ModelCost. */
|
|
60
|
-
export interface ModelCostLike extends CostRates {
|
|
61
|
-
readonly tiers?: readonly CostTier[];
|
|
62
|
-
}
|
|
63
|
-
/** The token components one request reported. */
|
|
64
|
-
export interface UsageCounts {
|
|
65
|
-
readonly input: number;
|
|
66
|
-
readonly output: number;
|
|
67
|
-
readonly cacheRead: number;
|
|
68
|
-
readonly cacheWrite: number;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Billed input tokens: reported input plus cache reads and writes.
|
|
72
|
-
* @param usage - one request's token components.
|
|
73
|
-
* @returns the total the tier threshold is compared against.
|
|
74
|
-
*/
|
|
75
|
-
export declare function billedInput(usage: UsageCounts): number;
|
|
76
|
-
/**
|
|
77
|
-
* Whether every rate of a model is zero (a free row).
|
|
78
|
-
* @param cost - the model's catalog cost.
|
|
79
|
-
* @returns true when no component could ever charge.
|
|
80
|
-
*/
|
|
81
|
-
export declare function isFreeCost(cost: ModelCostLike): boolean;
|
|
82
|
-
/**
|
|
83
|
-
* Price one settled request.
|
|
84
|
-
* @param model - the model id that served the request.
|
|
85
|
-
* @param usage - its token components.
|
|
86
|
-
* @param cost - the catalog cost for that model.
|
|
87
|
-
* @param at - request start time, used for the DeepSeek peak window.
|
|
88
|
-
* @returns the estimated cost in integer micro-USD.
|
|
89
|
-
*/
|
|
90
|
-
export declare function priceUsage(model: string, usage: UsageCounts, cost: ModelCostLike, at: number): number;
|
|
91
|
-
/** Route id used by this plugin before 0.1.16. */
|
|
92
|
-
export declare const LEGACY_PROVIDER_ID = "opencode-go";
|
|
93
|
-
/** 0.1.16 isolated the plugin route; later legacy-id records belong to DSH native. */
|
|
94
|
-
export declare const LEGACY_ROUTE_CUTOFF_MS: number;
|
|
95
|
-
/** Minimal structural event face; the Host owns the real session types. */
|
|
96
|
-
export interface AnalyticsEventLike {
|
|
97
|
-
readonly type: string;
|
|
98
|
-
readonly seq: number;
|
|
99
|
-
readonly time: number;
|
|
100
|
-
readonly data?: unknown;
|
|
101
|
-
}
|
|
102
|
-
/** Minimal structural snapshot returned by readSession. */
|
|
103
|
-
export interface AnalyticsSnapshotLike {
|
|
104
|
-
readonly inheritedEventCount: number;
|
|
105
|
-
readonly events: readonly AnalyticsEventLike[];
|
|
106
|
-
}
|
|
107
|
-
/** One model request that the dashboard can price. */
|
|
108
|
-
export interface RequestFact {
|
|
109
|
-
/** Request start, Unix epoch milliseconds. */
|
|
110
|
-
readonly at: number;
|
|
111
|
-
readonly model: string;
|
|
112
|
-
readonly input: number;
|
|
113
|
-
readonly output: number;
|
|
114
|
-
readonly cacheRead: number;
|
|
115
|
-
readonly cacheWrite: number;
|
|
116
|
-
/** The request was recorded under the pre-0.1.16 route id. */
|
|
117
|
-
readonly legacy: boolean;
|
|
118
|
-
readonly kind: 'message' | 'summary';
|
|
119
|
-
/** The request settled without a usable usage report. */
|
|
120
|
-
readonly missingUsage: boolean;
|
|
121
|
-
}
|
|
122
|
-
/** Everything one session contributes, before date filtering. */
|
|
123
|
-
export interface FoldedSession {
|
|
124
|
-
readonly facts: RequestFact[];
|
|
125
|
-
/** Start times of attempts that committed no surface message. */
|
|
126
|
-
readonly attempts: number[];
|
|
127
|
-
/** Model calls with no usable routing header or model id. */
|
|
128
|
-
readonly unattributed: number[];
|
|
129
|
-
/** Events that passed the fork-prefix filter — never the inherited prefix (review P11). */
|
|
130
|
-
readonly events: number;
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Whether a recorded provider id belongs to this plugin.
|
|
134
|
-
* @param provider - the provider id in a request header or summary event.
|
|
135
|
-
* @param at - the request start time.
|
|
136
|
-
* @param cutoff - legacy route cutoff, overridable in tests.
|
|
137
|
-
* @returns true when the request is this plugin's.
|
|
138
|
-
*/
|
|
139
|
-
export declare function isPluginRoute(provider: unknown, at: number, cutoff?: number): boolean;
|
|
140
|
-
/**
|
|
141
|
-
* Fold one session snapshot.
|
|
142
|
-
* @param snapshot - complete raw event log plus its fork-inherited prefix length.
|
|
143
|
-
* @param options - test seams; the cutoff defaults to the 0.1.16 release.
|
|
144
|
-
* @returns the session's priceable facts and counters.
|
|
145
|
-
*/
|
|
146
|
-
export declare function foldSession(snapshot: AnalyticsSnapshotLike, options?: {
|
|
147
|
-
cutoff?: number;
|
|
148
|
-
}): FoldedSession;
|
|
149
|
-
/** Why an analytics read failed. */
|
|
150
|
-
export type AnalyticsFailureReason = 'no-session-query' | 'invalid-range' | 'scan-failed';
|
|
151
|
-
/** One dashboard read. Dates are Unix epoch milliseconds. */
|
|
152
|
-
export interface AnalyticsQuery {
|
|
153
|
-
/** Inclusive start. */
|
|
154
|
-
from: number;
|
|
155
|
-
/** Exclusive end. */
|
|
156
|
-
to: number;
|
|
157
|
-
/** IANA timezone used to bucket days. */
|
|
158
|
-
timeZone: string;
|
|
159
|
-
/** Session scan cap, 1..2000; the Host default applies when absent. */
|
|
160
|
-
maxSessions?: number;
|
|
161
|
-
}
|
|
162
|
-
/** Totals over the requested range. */
|
|
163
|
-
export interface AnalyticsTotals {
|
|
164
|
-
requests: number;
|
|
165
|
-
unsettledAttempts: number;
|
|
166
|
-
summaries: number;
|
|
167
|
-
inputTokens: number;
|
|
168
|
-
outputTokens: number;
|
|
169
|
-
cacheReadTokens: number;
|
|
170
|
-
cacheWriteTokens: number;
|
|
171
|
-
estimatedMicroUsd: number;
|
|
172
|
-
pricedRequests: number;
|
|
173
|
-
unpricedRequests: number;
|
|
174
|
-
missingUsage: number;
|
|
175
|
-
}
|
|
176
|
-
/** One model's share of the range. */
|
|
177
|
-
export interface AnalyticsModelRow {
|
|
178
|
-
model: string;
|
|
179
|
-
name?: string;
|
|
180
|
-
requests: number;
|
|
181
|
-
missingUsage: number;
|
|
182
|
-
inputTokens: number;
|
|
183
|
-
outputTokens: number;
|
|
184
|
-
cacheReadTokens: number;
|
|
185
|
-
cacheWriteTokens: number;
|
|
186
|
-
estimatedMicroUsd: number;
|
|
187
|
-
pricedRequests: number;
|
|
188
|
-
unpricedRequests: number;
|
|
189
|
-
/** Go monthly limit in USD; null when unlimited or unknown. */
|
|
190
|
-
limitGoUsd: number | null;
|
|
191
|
-
/** Go Plus monthly limit in USD; null when unlimited or unknown. */
|
|
192
|
-
limitGoPlusUsd: number | null;
|
|
193
|
-
limitNote?: 'unlimited' | 'limited-time' | 'unknown';
|
|
194
|
-
}
|
|
195
|
-
/** One local calendar day. */
|
|
196
|
-
export interface AnalyticsDayRow {
|
|
197
|
-
/** YYYY-MM-DD in the query timezone. */
|
|
198
|
-
day: string;
|
|
199
|
-
requests: number;
|
|
200
|
-
tokens: number;
|
|
201
|
-
estimatedMicroUsd: number;
|
|
202
|
-
}
|
|
203
|
-
/** Coverage and budget limits for this report. */
|
|
204
|
-
export interface AnalyticsCoverage {
|
|
205
|
-
listedSessions: number;
|
|
206
|
-
scannedSessions: number;
|
|
207
|
-
matchedSessions: number;
|
|
208
|
-
failedSessions: number;
|
|
209
|
-
eventsScanned: number;
|
|
210
|
-
summaries: number;
|
|
211
|
-
legacyRequests: number;
|
|
212
|
-
missingUsage: number;
|
|
213
|
-
truncated: boolean;
|
|
214
|
-
truncation?: 'sessions' | 'events' | 'time';
|
|
215
|
-
scanMs: number;
|
|
216
|
-
timeZoneFallback?: true;
|
|
217
|
-
/**
|
|
218
|
-
* Sessions listed but never scanned because the slice cap or a budget
|
|
219
|
-
* stopped first (review P16/P18/M1). Observability only — this never
|
|
220
|
-
* implies the requested range was fully covered.
|
|
221
|
-
*/
|
|
222
|
-
unreadSessions?: number;
|
|
223
|
-
/**
|
|
224
|
-
* Cache entries the end-of-run trim dropped after this report was computed
|
|
225
|
-
* from run-local results; the next run re-reads them (review P3/S1).
|
|
226
|
-
*/
|
|
227
|
-
evictedSessions?: number;
|
|
228
|
-
/**
|
|
229
|
-
* Model calls in range with no usable routing header or model id, counted
|
|
230
|
-
* for visibility only — never in tokens or cost (review P12).
|
|
231
|
-
*/
|
|
232
|
-
unattributedRequests?: number;
|
|
233
|
-
/** Session listing wall time; scanMs excludes it (review S6). */
|
|
234
|
-
listMs?: number;
|
|
235
|
-
/** Pricing harvest wall time; scanMs excludes it (review S6/P4). */
|
|
236
|
-
pricingMs?: number;
|
|
237
|
-
}
|
|
238
|
-
/** Where the prices came from. */
|
|
239
|
-
export interface AnalyticsPricing {
|
|
240
|
-
source: 'models.dev';
|
|
241
|
-
updatedAt?: number;
|
|
242
|
-
/**
|
|
243
|
-
* True only when the whole price table was unavailable; unpricedModels then
|
|
244
|
-
* lists every model that actually appeared in the range (review P15). A
|
|
245
|
-
* table that loaded but lacks a model leaves this unset and lists the model.
|
|
246
|
-
*/
|
|
247
|
-
unavailable?: true;
|
|
248
|
-
unpricedModels: string[];
|
|
249
|
-
}
|
|
250
|
-
/** One complete dashboard response. */
|
|
251
|
-
export interface AnalyticsReport {
|
|
252
|
-
generatedAt: number;
|
|
253
|
-
range: {
|
|
254
|
-
from: number;
|
|
255
|
-
to: number;
|
|
256
|
-
};
|
|
257
|
-
timeZone: string;
|
|
258
|
-
totals: AnalyticsTotals;
|
|
259
|
-
byModel: AnalyticsModelRow[];
|
|
260
|
-
byDay: AnalyticsDayRow[];
|
|
261
|
-
coverage: AnalyticsCoverage;
|
|
262
|
-
pricing: AnalyticsPricing;
|
|
263
|
-
}
|
|
264
|
-
/** Structural face of one sessionQuery record. */
|
|
265
|
-
export interface AnalyticsSessionRecord {
|
|
266
|
-
readonly header?: {
|
|
267
|
-
readonly id?: string;
|
|
268
|
-
readonly createdAt?: number;
|
|
269
|
-
};
|
|
270
|
-
readonly live?: boolean;
|
|
271
|
-
readonly persisted?: boolean;
|
|
272
|
-
}
|
|
273
|
-
/** The subset of ctx.sessionQuery this service needs. */
|
|
274
|
-
export interface AnalyticsSessionQuery {
|
|
275
|
-
listSessions(signal?: AbortSignal): Promise<readonly AnalyticsSessionRecord[]>;
|
|
276
|
-
readSession(id: string): Promise<AnalyticsSnapshotLike>;
|
|
277
|
-
}
|
|
278
|
-
/** Structural face of one catalog model. */
|
|
279
|
-
export interface AnalyticsPricingModel {
|
|
280
|
-
readonly id?: string;
|
|
281
|
-
readonly name?: string;
|
|
282
|
-
readonly cost?: ModelCostLike;
|
|
283
|
-
}
|
|
284
|
-
/** Pricing data and its last update, when known. */
|
|
285
|
-
export interface AnalyticsPriceBook {
|
|
286
|
-
readonly models: ReadonlyMap<string, AnalyticsPricingModel>;
|
|
287
|
-
readonly updatedAt?: number;
|
|
288
|
-
}
|
|
289
|
-
/** Structural face of the catalog data the price book builder consumes. */
|
|
290
|
-
export interface AnalyticsCatalogSnapshotLike {
|
|
291
|
-
readonly models: ReadonlyMap<string, AnalyticsPricingModel>;
|
|
292
|
-
readonly details?: ReadonlyMap<string, {
|
|
293
|
-
readonly costKnown?: false;
|
|
294
|
-
}>;
|
|
295
|
-
readonly metadataUpdatedAtMs?: number;
|
|
296
|
-
}
|
|
297
|
-
/** Construction options; tests inject fakes for every seam. */
|
|
3
|
+
import { type AnalyticsQuery, type AnalyticsReport, type AnalyticsExport } from './contracts.ts';
|
|
4
|
+
import { ProxyTransport } from './transport.ts';
|
|
5
|
+
export declare const ANALYTICS_MAX_BYTES: number;
|
|
298
6
|
export interface AnalyticsOptions {
|
|
299
|
-
|
|
300
|
-
|
|
7
|
+
baseURL: () => string;
|
|
8
|
+
proxyURL?: () => string;
|
|
9
|
+
transport?: ProxyTransport;
|
|
10
|
+
resolveApiKey: (ref: string) => Promise<string | undefined>;
|
|
11
|
+
accountRefs: () => readonly string[];
|
|
301
12
|
now?: () => number;
|
|
302
|
-
|
|
303
|
-
maxSessions?: number;
|
|
304
|
-
maxEvents?: number;
|
|
305
|
-
maxFacts?: number;
|
|
306
|
-
/**
|
|
307
|
-
* Maximum concurrent session reads (review P1/S3). One or less scans
|
|
308
|
-
* serially — the rollback path for a Host whose readSession cannot run
|
|
309
|
-
* concurrently.
|
|
310
|
-
*/
|
|
311
|
-
maxConcurrency?: number;
|
|
13
|
+
fetch?: typeof globalThis.fetch;
|
|
312
14
|
}
|
|
313
|
-
/**
|
|
314
|
-
* Build the analytics price book from one catalog snapshot (review P14 core
|
|
315
|
-
* half). A model the metadata marked `costKnown: false` — upstream published
|
|
316
|
-
* no cost block, or a malformed one whose fabricated zeros are
|
|
317
|
-
* indistinguishable from a genuinely free model — is entered without a cost,
|
|
318
|
-
* so its requests land in the unpriced bucket instead of being priced at 0.
|
|
319
|
-
* A published block with legal components stays priced even when all zero.
|
|
320
|
-
*/
|
|
321
|
-
export declare function analyticsPriceBook(snapshot: AnalyticsCatalogSnapshotLike): AnalyticsPriceBook;
|
|
322
|
-
/** One mount owns the scan cache; multiple dashboard opens share it. */
|
|
15
|
+
/** The Host retains the official CSV; ordinary reads expose only aggregate numbers. */
|
|
323
16
|
export declare class GoAnalyticsService extends TypertRemoteService {
|
|
324
17
|
private readonly options;
|
|
18
|
+
private readonly identities;
|
|
325
19
|
private readonly cache;
|
|
326
20
|
private readonly pending;
|
|
327
|
-
|
|
328
|
-
private
|
|
329
|
-
private factTotal;
|
|
21
|
+
private readonly active;
|
|
22
|
+
private readonly transport;
|
|
330
23
|
constructor(ctx: Context, options: AnalyticsOptions);
|
|
331
|
-
/**
|
|
332
|
-
* Read one aggregate report.
|
|
333
|
-
* @param raw - the validated query from the RPC codec.
|
|
334
|
-
* @param signal - caller cancellation, injected by the gateway after the
|
|
335
|
-
* business parameters and never carried on the wire.
|
|
336
|
-
* @returns the report; failures carry a reason in the domain error details.
|
|
337
|
-
*/
|
|
338
24
|
read(raw: AnalyticsQuery, signal?: AbortSignal): Promise<AnalyticsReport>;
|
|
25
|
+
exportCsv(raw: AnalyticsQuery, signal?: AbortSignal): Promise<AnalyticsExport>;
|
|
339
26
|
private now;
|
|
340
|
-
private
|
|
341
|
-
private
|
|
342
|
-
private
|
|
343
|
-
|
|
344
|
-
private
|
|
27
|
+
private query;
|
|
28
|
+
private failure;
|
|
29
|
+
private forget;
|
|
30
|
+
private network;
|
|
31
|
+
private assertCurrentNetwork;
|
|
32
|
+
private identity;
|
|
33
|
+
private dataset;
|
|
34
|
+
private fetchDataset;
|
|
345
35
|
}
|