dsh-coding-subscription-oauth 0.6.2 → 0.6.3

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.
Files changed (121) hide show
  1. package/CHANGELOG.md +222 -206
  2. package/CONTRIBUTING.md +129 -120
  3. package/INSTALL.md +218 -218
  4. package/LICENSE +19 -19
  5. package/NOTICE +11 -11
  6. package/README.de.md +289 -289
  7. package/README.es.md +290 -290
  8. package/README.fr.md +290 -290
  9. package/README.ja.md +290 -290
  10. package/README.ko.md +290 -290
  11. package/README.md +304 -304
  12. package/README.pt-BR.md +290 -290
  13. package/README.ru.md +290 -290
  14. package/README.zh-CN.md +302 -302
  15. package/compatibility/dsh-bom.json +0 -0
  16. package/cordis.patch.yml +13 -13
  17. package/docs/00-project-rules.md +212 -195
  18. package/docs/02-architecture.md +130 -130
  19. package/docs/02-architecture.zh-CN.md +130 -130
  20. package/lib/bin.js.map +1 -1
  21. package/lib/capability-settings.d.ts +8 -2
  22. package/lib/capability-settings.d.ts.map +1 -1
  23. package/lib/capability-tools.d.ts +7 -2
  24. package/lib/capability-tools.d.ts.map +1 -1
  25. package/lib/client.js +3 -3
  26. package/lib/client.js.map +2 -2
  27. package/lib/codex-images.d.ts +8 -0
  28. package/lib/codex-images.d.ts.map +1 -1
  29. package/lib/index.js +32 -7
  30. package/lib/index.js.map +2 -2
  31. package/lib/invariant.js.map +1 -1
  32. package/media/en/settings_accounts.png +0 -0
  33. package/media/en/settings_capabilities.png +0 -0
  34. package/media/en/settings_gateway.png +0 -0
  35. package/media/settings_accounts.png +0 -0
  36. package/media/settings_capabilities.png +0 -0
  37. package/media/settings_gateway.png +0 -0
  38. package/media/settings_overview.png +0 -0
  39. package/media/zh-CN/settings_accounts.png +0 -0
  40. package/media/zh-CN/settings_capabilities.png +0 -0
  41. package/media/zh-CN/settings_gateway.png +0 -0
  42. package/package.json +148 -148
  43. package/patches/dsh-agy@0.1.2.patch +25 -25
  44. package/scripts/release.mjs +186 -186
  45. package/scripts/smoke-deployed-routes.mjs +146 -146
  46. package/scripts/verify-deployed-catalog.mjs +87 -87
  47. package/src/adapter.ts +273 -273
  48. package/src/alias-adapter.ts +130 -130
  49. package/src/auth-routes.ts +921 -921
  50. package/src/auth.ts +67 -67
  51. package/src/bin.ts +350 -350
  52. package/src/capability-routes.ts +279 -279
  53. package/src/capability-runtime.ts +314 -313
  54. package/src/capability-settings.ts +671 -658
  55. package/src/capability-tools.ts +685 -666
  56. package/src/catalog.ts +271 -271
  57. package/src/client/GrokBuildSettings.tsx +771 -770
  58. package/src/client/api.ts +88 -88
  59. package/src/client/components/AboutTab.tsx +30 -30
  60. package/src/client/components/AccountsTab.tsx +241 -241
  61. package/src/client/components/Badge.tsx +33 -33
  62. package/src/client/components/CapabilitiesTab.tsx +265 -265
  63. package/src/client/components/CliPullPreview.tsx +116 -116
  64. package/src/client/components/CopyButton.tsx +57 -57
  65. package/src/client/components/GatewayTab.tsx +469 -469
  66. package/src/client/components/NoticeBanner.tsx +46 -46
  67. package/src/client/components/ProgressBar.tsx +53 -53
  68. package/src/client/components/ProviderCard.tsx +606 -606
  69. package/src/client/components/SettingsTabs.tsx +75 -75
  70. package/src/client/components/ToggleSwitch.tsx +71 -71
  71. package/src/client/constants.ts +230 -224
  72. package/src/client/display.ts +61 -61
  73. package/src/client/dshClientAdapter.ts +127 -127
  74. package/src/client/gatewaySnippets.ts +37 -37
  75. package/src/client/index.tsx +156 -156
  76. package/src/client/locales.ts +540 -535
  77. package/src/client/microStyles.ts +52 -52
  78. package/src/client/parsers.ts +398 -396
  79. package/src/client/styles.ts +325 -325
  80. package/src/client/types.ts +199 -197
  81. package/src/codex-http.ts +447 -447
  82. package/src/codex-images.ts +503 -485
  83. package/src/codex-model-capabilities.ts +320 -320
  84. package/src/codex-search.ts +245 -245
  85. package/src/codex-usage.ts +263 -263
  86. package/src/compatibility.ts +41 -41
  87. package/src/dsh-host-adapter.ts +173 -173
  88. package/src/gateway-anthropic-messages.ts +84 -84
  89. package/src/gateway-auth.ts +102 -102
  90. package/src/gateway-backend.ts +274 -274
  91. package/src/gateway-body.ts +49 -49
  92. package/src/gateway-config.ts +76 -76
  93. package/src/gateway-http.ts +104 -104
  94. package/src/gateway-openai-chat.ts +124 -124
  95. package/src/gateway-openai-responses.ts +53 -53
  96. package/src/gateway-parse.ts +224 -224
  97. package/src/gateway-protocol.ts +52 -52
  98. package/src/gateway-routes.ts +158 -158
  99. package/src/gateway.ts +258 -258
  100. package/src/grok-errors.ts +24 -24
  101. package/src/grok-imagine.ts +1627 -1627
  102. package/src/grok-import.ts +151 -151
  103. package/src/http-json.ts +82 -82
  104. package/src/ids.ts +59 -59
  105. package/src/imagine-routes.ts +463 -463
  106. package/src/index.ts +709 -709
  107. package/src/invariant.ts +17 -17
  108. package/src/kimi-errors.ts +26 -26
  109. package/src/media-store.ts +927 -927
  110. package/src/oauth-import-routes.ts +324 -324
  111. package/src/oauth-providers.ts +152 -152
  112. package/src/oauth-session.ts +183 -183
  113. package/src/oauth-sources.ts +1104 -1104
  114. package/src/oauth.ts +620 -620
  115. package/src/provider.ts +128 -128
  116. package/src/proxy.ts +11 -11
  117. package/src/redact.ts +72 -72
  118. package/src/session.ts +218 -218
  119. package/src/store.ts +217 -217
  120. package/src/web-origin.ts +296 -296
  121. package/src/web-routes.ts +38 -38
@@ -1,147 +1,147 @@
1
- /**
2
- * Harness route aliases over a native-id PiAiAdapter.
3
- * @module dsh-coding-subscription-oauth/alias-adapter
4
- */
5
-
6
- import type {
7
- GenerateOptions,
8
- LlmModelInfo,
9
- LlmProviderInfo,
10
- LlmResolvedModelInfo,
11
- ResolvedRetryPolicy,
12
- StreamChunk,
13
- } from "@deepseek-ai/dsh-llm";
14
- import { LlmAdapter, LlmError } from "@deepseek-ai/dsh-llm";
15
- import { remapXaiCapacityFailure } from "./grok-errors.ts";
16
- import { remapAuthFailureIfContextOverflow } from "./kimi-errors.ts";
17
-
18
- export interface AliasLlmRoutePolicy {
19
- /** User-facing provider name shown above models in the model selector. */
20
- displayName?: string;
21
- /** Return false to hide every model for this route from discovery. */
22
- isAuthenticated?: () => Promise<boolean>;
23
- /**
24
- * After authentication, keep only models this predicate accepts.
25
- * Used by opt-in routes (e.g. Codex Fast) so ineligible ids stay hidden
26
- * without hiding the whole authenticated catalog.
27
- */
28
- includeModel?: (modelId: string) => boolean;
29
- /**
30
- * Called once when a stream for this route finishes with an AUTH failure
31
- * (upstream rejected a locally-valid token). Implementations backdate the
32
- * stored credential's expiry so the retried step refreshes before reuse.
33
- * Awaiting it here keeps invalidation ordered before the retry executor
34
- * reruns the step; failures are swallowed so the original AUTH surfaces.
35
- */
36
- onAuthFailure?: () => Promise<void>;
37
- }
38
-
1
+ /**
2
+ * Harness route aliases over a native-id PiAiAdapter.
3
+ * @module dsh-coding-subscription-oauth/alias-adapter
4
+ */
5
+
6
+ import type {
7
+ GenerateOptions,
8
+ LlmModelInfo,
9
+ LlmProviderInfo,
10
+ LlmResolvedModelInfo,
11
+ ResolvedRetryPolicy,
12
+ StreamChunk,
13
+ } from "@deepseek-ai/dsh-llm";
14
+ import { LlmAdapter, LlmError } from "@deepseek-ai/dsh-llm";
15
+ import { remapXaiCapacityFailure } from "./grok-errors.ts";
16
+ import { remapAuthFailureIfContextOverflow } from "./kimi-errors.ts";
17
+
18
+ export interface AliasLlmRoutePolicy {
19
+ /** User-facing provider name shown above models in the model selector. */
20
+ displayName?: string;
21
+ /** Return false to hide every model for this route from discovery. */
22
+ isAuthenticated?: () => Promise<boolean>;
23
+ /**
24
+ * After authentication, keep only models this predicate accepts.
25
+ * Used by opt-in routes (e.g. Codex Fast) so ineligible ids stay hidden
26
+ * without hiding the whole authenticated catalog.
27
+ */
28
+ includeModel?: (modelId: string) => boolean;
29
+ /**
30
+ * Called once when a stream for this route finishes with an AUTH failure
31
+ * (upstream rejected a locally-valid token). Implementations backdate the
32
+ * stored credential's expiry so the retried step refreshes before reuse.
33
+ * Awaiting it here keeps invalidation ordered before the retry executor
34
+ * reruns the step; failures are swallowed so the original AUTH surfaces.
35
+ */
36
+ onAuthFailure?: () => Promise<void>;
37
+ }
38
+
39
39
  export function normalizeReplayForRoute(
40
40
  message: GenerateOptions["messages"][number],
41
41
  route: string,
42
42
  nativeReplayProvider: string,
43
- ): GenerateOptions["messages"][number] {
44
- if (message.role !== "assistant" || message.source.kind !== "model") return message;
45
- if (message.source.provider !== route) {
46
- if (message.source.replayState === undefined) return message;
47
- const { replayState: _foreignReplay, ...source } = message.source;
48
- return { ...message, source };
49
- }
43
+ ): GenerateOptions["messages"][number] {
44
+ if (message.role !== "assistant" || message.source.kind !== "model") return message;
45
+ if (message.source.provider !== route) {
46
+ if (message.source.replayState === undefined) return message;
47
+ const { replayState: _foreignReplay, ...source } = message.source;
48
+ return { ...message, source };
49
+ }
50
50
  // The rc.2 envelope stays entirely opaque. PiAiAdapter only keys replay
51
51
  // validation from source.provider, so restore the native provider identity
52
52
  // without inspecting or changing replayState.
53
53
  return { ...message, source: { ...message.source, provider: nativeReplayProvider } };
54
- }
55
-
56
- /**
57
- * Keeps pi-ai model.provider identities native while exposing collision-free
58
- * Harness route names. Every public operation translates exactly once.
59
- */
60
- export class AliasLlmAdapter extends LlmAdapter {
54
+ }
55
+
56
+ /**
57
+ * Keeps pi-ai model.provider identities native while exposing collision-free
58
+ * Harness route names. Every public operation translates exactly once.
59
+ */
60
+ export class AliasLlmAdapter extends LlmAdapter {
61
61
  constructor(
62
62
  private readonly inner: LlmAdapter,
63
63
  private readonly aliases: ReadonlyMap<string, string>,
64
64
  private readonly policies: ReadonlyMap<string, AliasLlmRoutePolicy> = new Map(),
65
65
  private readonly replayProviders: ReadonlyMap<string, string> = aliases,
66
- ) {
67
- super();
68
- }
69
-
70
- private nativeProvider(route: string): string {
71
- const provider = this.aliases.get(route);
72
- if (provider === undefined) throw new LlmError(`OAuth adapter does not own provider "${route}"`, "NO_ADAPTER");
73
- return provider;
74
- }
75
-
76
- providerInfo(provider: string): LlmProviderInfo {
77
- const native = this.nativeProvider(provider);
78
- const info = this.inner.providerInfo(native);
79
- const displayName = this.policies.get(provider)?.displayName;
80
- return { ...info, id: provider, ...(displayName === undefined ? {} : { name: displayName }) };
81
- }
82
-
83
- providerRetryPolicy(provider: string): ResolvedRetryPolicy | undefined {
84
- return this.inner.providerRetryPolicy(this.nativeProvider(provider));
85
- }
86
-
87
- async listModels(provider: string): Promise<readonly LlmModelInfo[]> {
88
- const native = this.nativeProvider(provider);
89
- const isAuthenticated = this.policies.get(provider)?.isAuthenticated;
90
- if (isAuthenticated !== undefined) {
91
- try {
92
- if (!(await isAuthenticated())) return [];
93
- } catch {
94
- // A corrupt/unreadable credential must hide models instead of breaking
95
- // the entire model picker or presenting a route that cannot be used.
96
- return [];
97
- }
98
- }
99
- const listed = (await this.inner.listModels(native)).map((model) => ({ ...model, provider }));
100
- const includeModel = this.policies.get(provider)?.includeModel;
101
- return includeModel === undefined ? listed : listed.filter((model) => includeModel(model.id));
102
- }
103
-
104
- async resolveModel(provider: string, model: string, signal?: AbortSignal): Promise<LlmResolvedModelInfo> {
105
- const native = this.nativeProvider(provider);
106
- return { ...(await this.inner.resolveModel(native, model, signal)), provider };
107
- }
108
-
109
- async *stream(options: GenerateOptions): AsyncIterable<StreamChunk> {
110
- const route = options.provider;
111
- const native = this.nativeProvider(route);
66
+ ) {
67
+ super();
68
+ }
69
+
70
+ private nativeProvider(route: string): string {
71
+ const provider = this.aliases.get(route);
72
+ if (provider === undefined) throw new LlmError(`OAuth adapter does not own provider "${route}"`, "NO_ADAPTER");
73
+ return provider;
74
+ }
75
+
76
+ providerInfo(provider: string): LlmProviderInfo {
77
+ const native = this.nativeProvider(provider);
78
+ const info = this.inner.providerInfo(native);
79
+ const displayName = this.policies.get(provider)?.displayName;
80
+ return { ...info, id: provider, ...(displayName === undefined ? {} : { name: displayName }) };
81
+ }
82
+
83
+ providerRetryPolicy(provider: string): ResolvedRetryPolicy | undefined {
84
+ return this.inner.providerRetryPolicy(this.nativeProvider(provider));
85
+ }
86
+
87
+ async listModels(provider: string): Promise<readonly LlmModelInfo[]> {
88
+ const native = this.nativeProvider(provider);
89
+ const isAuthenticated = this.policies.get(provider)?.isAuthenticated;
90
+ if (isAuthenticated !== undefined) {
91
+ try {
92
+ if (!(await isAuthenticated())) return [];
93
+ } catch {
94
+ // A corrupt/unreadable credential must hide models instead of breaking
95
+ // the entire model picker or presenting a route that cannot be used.
96
+ return [];
97
+ }
98
+ }
99
+ const listed = (await this.inner.listModels(native)).map((model) => ({ ...model, provider }));
100
+ const includeModel = this.policies.get(provider)?.includeModel;
101
+ return includeModel === undefined ? listed : listed.filter((model) => includeModel(model.id));
102
+ }
103
+
104
+ async resolveModel(provider: string, model: string, signal?: AbortSignal): Promise<LlmResolvedModelInfo> {
105
+ const native = this.nativeProvider(provider);
106
+ return { ...(await this.inner.resolveModel(native, model, signal)), provider };
107
+ }
108
+
109
+ async *stream(options: GenerateOptions): AsyncIterable<StreamChunk> {
110
+ const route = options.provider;
111
+ const native = this.nativeProvider(route);
112
112
  const messages = options.messages.map((message) =>
113
113
  normalizeReplayForRoute(message, route, this.replayProviders.get(route) ?? native),
114
114
  );
115
- let authFailureNotified = false;
116
- for await (const raw of this.inner.stream({ ...options, provider: native, messages })) {
117
- const chunk =
118
- raw.type === "finish" && raw.reason.kind === "error"
119
- ? {
120
- ...raw,
121
- reason: {
122
- ...raw.reason,
123
- failure: remapXaiCapacityFailure(remapAuthFailureIfContextOverflow(raw.reason.failure)),
124
- },
125
- }
126
- : raw;
127
- if (
128
- !authFailureNotified &&
129
- chunk.type === "finish" &&
130
- chunk.reason.kind === "error" &&
131
- chunk.reason.failure.code === "AUTH"
132
- ) {
133
- authFailureNotified = true;
134
- const onAuthFailure = this.policies.get(route)?.onAuthFailure;
135
- if (onAuthFailure !== undefined) {
136
- try {
137
- await onAuthFailure();
138
- } catch {
139
- // Invalidation is best-effort: the original AUTH failure must
140
- // surface unchanged even when the credential store is unreadable.
141
- }
142
- }
143
- }
115
+ let authFailureNotified = false;
116
+ for await (const raw of this.inner.stream({ ...options, provider: native, messages })) {
117
+ const chunk =
118
+ raw.type === "finish" && raw.reason.kind === "error"
119
+ ? {
120
+ ...raw,
121
+ reason: {
122
+ ...raw.reason,
123
+ failure: remapXaiCapacityFailure(remapAuthFailureIfContextOverflow(raw.reason.failure)),
124
+ },
125
+ }
126
+ : raw;
127
+ if (
128
+ !authFailureNotified &&
129
+ chunk.type === "finish" &&
130
+ chunk.reason.kind === "error" &&
131
+ chunk.reason.failure.code === "AUTH"
132
+ ) {
133
+ authFailureNotified = true;
134
+ const onAuthFailure = this.policies.get(route)?.onAuthFailure;
135
+ if (onAuthFailure !== undefined) {
136
+ try {
137
+ await onAuthFailure();
138
+ } catch {
139
+ // Invalidation is best-effort: the original AUTH failure must
140
+ // surface unchanged even when the credential store is unreadable.
141
+ }
142
+ }
143
+ }
144
144
  yield chunk;
145
- }
146
- }
147
- }
145
+ }
146
+ }
147
+ }