@sunerpy/opencode-kiro-auth 0.13.0 → 0.13.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/dist/constants.d.ts +3 -0
- package/dist/constants.js +31 -0
- package/dist/core/request/error-handler.d.ts +1 -0
- package/dist/core/request/error-handler.js +7 -0
- package/dist/core/request/request-handler.js +19 -7
- package/dist/plugin/models.d.ts +1 -0
- package/dist/plugin/models.js +20 -2
- package/package.json +1 -1
package/dist/constants.d.ts
CHANGED
|
@@ -19,6 +19,9 @@ export declare const KIRO_CONSTANTS: {
|
|
|
19
19
|
export declare const MODEL_MAPPING: Record<string, string>;
|
|
20
20
|
export declare const SUPPORTED_MODELS: string[];
|
|
21
21
|
export declare function isLongContextModel(model: string): boolean;
|
|
22
|
+
export declare const DEFAULT_MODEL_CONTEXT_LIMIT = 200000;
|
|
23
|
+
export declare const MODEL_CONTEXT_LIMITS: Record<string, number>;
|
|
24
|
+
export declare function getModelContextLimit(baseModel: string): number;
|
|
22
25
|
export declare const KIRO_AUTH_SERVICE: {
|
|
23
26
|
ENDPOINT: string;
|
|
24
27
|
SSO_OIDC_ENDPOINT: string;
|
package/dist/constants.js
CHANGED
|
@@ -98,6 +98,37 @@ const LONG_CONTEXT_MODELS = new Set(Object.keys(MODEL_MAPPING).filter((k) => k.i
|
|
|
98
98
|
export function isLongContextModel(model) {
|
|
99
99
|
return LONG_CONTEXT_MODELS.has(model);
|
|
100
100
|
}
|
|
101
|
+
// SSOT for token accounting, keyed by BASE model id (effort/thinking suffix
|
|
102
|
+
// stripped). Values MUST equal the limit.context advertised in src/plugin.ts —
|
|
103
|
+
// enforced by context-window.test.ts. Drift makes OpenCode under-count usage and
|
|
104
|
+
// skip auto-compaction until Kiro hard-rejects with 400 "Input is too long."
|
|
105
|
+
export const DEFAULT_MODEL_CONTEXT_LIMIT = 200000;
|
|
106
|
+
export const MODEL_CONTEXT_LIMITS = {
|
|
107
|
+
auto: 200000,
|
|
108
|
+
'claude-haiku-4-5': 200000,
|
|
109
|
+
'claude-sonnet-4': 200000,
|
|
110
|
+
'claude-sonnet-4-5': 200000,
|
|
111
|
+
'claude-sonnet-4-5-1m': 1000000,
|
|
112
|
+
'claude-sonnet-4-6': 1000000,
|
|
113
|
+
'claude-sonnet-4-6-1m': 1000000,
|
|
114
|
+
'claude-sonnet-5': 1000000,
|
|
115
|
+
'claude-opus-4-5': 200000,
|
|
116
|
+
'claude-opus-4-6': 1000000,
|
|
117
|
+
'claude-opus-4-6-1m': 1000000,
|
|
118
|
+
'claude-opus-4-7': 1000000,
|
|
119
|
+
'claude-opus-4-8': 1000000,
|
|
120
|
+
'deepseek-3.2': 128000,
|
|
121
|
+
'glm-5': 200000,
|
|
122
|
+
'minimax-m2.5': 200000,
|
|
123
|
+
'minimax-m2.1': 200000,
|
|
124
|
+
'qwen3-coder-next': 256000,
|
|
125
|
+
'gpt-5.6-sol': 272000,
|
|
126
|
+
'gpt-5.6-terra': 272000,
|
|
127
|
+
'gpt-5.6-luna': 272000
|
|
128
|
+
};
|
|
129
|
+
export function getModelContextLimit(baseModel) {
|
|
130
|
+
return MODEL_CONTEXT_LIMITS[baseModel] ?? DEFAULT_MODEL_CONTEXT_LIMIT;
|
|
131
|
+
}
|
|
101
132
|
export const KIRO_AUTH_SERVICE = {
|
|
102
133
|
ENDPOINT: 'https://prod.{{region}}.auth.desktop.kiro.dev',
|
|
103
134
|
SSO_OIDC_ENDPOINT: 'https://oidc.{{region}}.amazonaws.com',
|
|
@@ -3,6 +3,7 @@ import type { AccountManager } from '../../plugin/accounts.js';
|
|
|
3
3
|
import type { ManagedAccount } from '../../plugin/types.js';
|
|
4
4
|
import type { ForceRefreshResult } from '../auth/token-refresher.js';
|
|
5
5
|
type ToastFunction = (message: string, variant: 'info' | 'warning' | 'success' | 'error') => void;
|
|
6
|
+
export declare function isKiroContextOverflowBody(text: string): boolean;
|
|
6
7
|
export interface RequestContext {
|
|
7
8
|
retry: number;
|
|
8
9
|
forcedRefreshAccountIds?: Set<string>;
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { isAccessTokenError, toDeadReason } from '../../plugin/health.js';
|
|
2
|
+
// Unambiguous Kiro size-overflow 400 signals only. The generic "Improperly
|
|
3
|
+
// formed request." is deliberately excluded: it has no size discriminator in
|
|
4
|
+
// the body, so matching it would wrongly reclassify unrelated 400s as overflow.
|
|
5
|
+
const KIRO_CONTEXT_OVERFLOW_PATTERNS = [/input is too long/i, /CONTENT_LENGTH_EXCEEDS_THRESHOLD/i];
|
|
6
|
+
export function isKiroContextOverflowBody(text) {
|
|
7
|
+
return KIRO_CONTEXT_OVERFLOW_PATTERNS.some((p) => p.test(text));
|
|
8
|
+
}
|
|
2
9
|
export class ErrorHandler {
|
|
3
10
|
config;
|
|
4
11
|
accountManager;
|
|
@@ -7,7 +7,7 @@ import { syncFromKiroCli } from '../../plugin/sync/kiro-cli.js';
|
|
|
7
7
|
import { AccountSelector } from '../account/account-selector.js';
|
|
8
8
|
import { UsageTracker } from '../account/usage-tracker.js';
|
|
9
9
|
import { TokenRefresher } from '../auth/token-refresher.js';
|
|
10
|
-
import { ErrorHandler } from './error-handler.js';
|
|
10
|
+
import { ErrorHandler, isKiroContextOverflowBody } from './error-handler.js';
|
|
11
11
|
import { ResponseHandler } from './response-handler.js';
|
|
12
12
|
import { RetryStrategy } from './retry-strategy.js';
|
|
13
13
|
const KIRO_API_PATTERN = /^(https?:\/\/)?q\.[a-z0-9-]+\.amazonaws\.com/;
|
|
@@ -155,12 +155,14 @@ export class RequestHandler {
|
|
|
155
155
|
if (apiTimestamp) {
|
|
156
156
|
this.logSdkError(sdkPrep, e, acc, apiTimestamp);
|
|
157
157
|
}
|
|
158
|
-
const
|
|
158
|
+
const errorBody = JSON.stringify({ message: e.message, __type: e.name });
|
|
159
|
+
const errorStatusText = e.name || 'Error';
|
|
160
|
+
const jsonHeaders = { 'Content-Type': 'application/json' };
|
|
161
|
+
const errorResult = await this.errorHandler.handle(e, new Response(errorBody, {
|
|
159
162
|
status: httpStatus,
|
|
160
|
-
statusText:
|
|
161
|
-
headers:
|
|
162
|
-
});
|
|
163
|
-
const errorResult = await this.errorHandler.handle(e, mockResponse, acc, handlerContext, showToast);
|
|
163
|
+
statusText: errorStatusText,
|
|
164
|
+
headers: jsonHeaders
|
|
165
|
+
}), acc, handlerContext, showToast);
|
|
164
166
|
if (errorResult.shouldRetry) {
|
|
165
167
|
if (errorResult.newContext) {
|
|
166
168
|
handlerContext = errorResult.newContext;
|
|
@@ -170,7 +172,17 @@ export class RequestHandler {
|
|
|
170
172
|
}
|
|
171
173
|
continue;
|
|
172
174
|
}
|
|
173
|
-
|
|
175
|
+
// Terminal, non-retryable HTTP error. Return a fresh Response carrying
|
|
176
|
+
// the real Kiro body so @ai-sdk/openai-compatible produces an
|
|
177
|
+
// APICallError with status+body (not a bare Error that OpenCode
|
|
178
|
+
// degrades to UnknownError). Remap size-overflow 400s to 413 so
|
|
179
|
+
// OpenCode classifies context_overflow and auto-compacts.
|
|
180
|
+
const terminalStatus = httpStatus === 400 && isKiroContextOverflowBody(e.message ?? '') ? 413 : httpStatus;
|
|
181
|
+
return new Response(errorBody, {
|
|
182
|
+
status: terminalStatus,
|
|
183
|
+
statusText: errorStatusText,
|
|
184
|
+
headers: jsonHeaders
|
|
185
|
+
});
|
|
174
186
|
}
|
|
175
187
|
const networkResult = await this.errorHandler.handleNetworkError(e, handlerContext, showToast);
|
|
176
188
|
if (networkResult.shouldRetry) {
|
package/dist/plugin/models.d.ts
CHANGED
|
@@ -20,4 +20,5 @@ export interface ResolvedModelVariant {
|
|
|
20
20
|
* with `effort` left undefined.
|
|
21
21
|
*/
|
|
22
22
|
export declare function resolveModelVariant(model: string): ResolvedModelVariant;
|
|
23
|
+
export declare function stripModelSuffix(model: string): string;
|
|
23
24
|
export declare function getContextWindowSize(model: string): number;
|
package/dist/plugin/models.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MODEL_MAPPING, SUPPORTED_MODELS,
|
|
1
|
+
import { MODEL_MAPPING, SUPPORTED_MODELS, getModelContextLimit } from '../constants.js';
|
|
2
2
|
export function resolveKiroModel(model) {
|
|
3
3
|
const resolved = MODEL_MAPPING[model];
|
|
4
4
|
if (!resolved) {
|
|
@@ -43,6 +43,24 @@ export function resolveModelVariant(model) {
|
|
|
43
43
|
}
|
|
44
44
|
return { wireId: resolveKiroModel(model), effort: undefined };
|
|
45
45
|
}
|
|
46
|
+
export function stripModelSuffix(model) {
|
|
47
|
+
for (const suffix of EFFORT_SUFFIXES) {
|
|
48
|
+
const marker = `-${suffix}`;
|
|
49
|
+
if (model.endsWith(marker)) {
|
|
50
|
+
const base = model.slice(0, -marker.length);
|
|
51
|
+
if (VARIANT_BASE_ALLOWLIST.has(base)) {
|
|
52
|
+
return base;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (model.endsWith('-thinking')) {
|
|
57
|
+
const base = model.slice(0, -'-thinking'.length);
|
|
58
|
+
if (MODEL_MAPPING[base]) {
|
|
59
|
+
return base;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return model;
|
|
63
|
+
}
|
|
46
64
|
export function getContextWindowSize(model) {
|
|
47
|
-
return
|
|
65
|
+
return getModelContextLimit(stripModelSuffix(model));
|
|
48
66
|
}
|