@sunerpy/opencode-kiro-auth 0.1.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/LICENSE +678 -0
- package/README.md +270 -0
- package/dist/constants.d.ts +28 -0
- package/dist/constants.js +108 -0
- package/dist/core/account/account-selector.d.ts +25 -0
- package/dist/core/account/account-selector.js +80 -0
- package/dist/core/account/usage-tracker.d.ts +20 -0
- package/dist/core/account/usage-tracker.js +56 -0
- package/dist/core/auth/auth-handler.d.ts +18 -0
- package/dist/core/auth/auth-handler.js +236 -0
- package/dist/core/auth/idc-auth-method.d.ts +9 -0
- package/dist/core/auth/idc-auth-method.js +169 -0
- package/dist/core/auth/token-refresher.d.ts +23 -0
- package/dist/core/auth/token-refresher.js +85 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.js +9 -0
- package/dist/core/request/error-handler.d.ts +32 -0
- package/dist/core/request/error-handler.js +159 -0
- package/dist/core/request/request-handler.d.ts +35 -0
- package/dist/core/request/request-handler.js +296 -0
- package/dist/core/request/response-handler.d.ts +8 -0
- package/dist/core/request/response-handler.js +137 -0
- package/dist/core/request/retry-strategy.d.ts +18 -0
- package/dist/core/request/retry-strategy.js +28 -0
- package/dist/index.d.ts +94 -0
- package/dist/index.js +2 -0
- package/dist/infrastructure/database/account-cache.d.ts +14 -0
- package/dist/infrastructure/database/account-cache.js +44 -0
- package/dist/infrastructure/database/account-repository.d.ts +12 -0
- package/dist/infrastructure/database/account-repository.js +66 -0
- package/dist/infrastructure/index.d.ts +7 -0
- package/dist/infrastructure/index.js +7 -0
- package/dist/infrastructure/transformers/event-stream-parser.d.ts +7 -0
- package/dist/infrastructure/transformers/event-stream-parser.js +115 -0
- package/dist/infrastructure/transformers/history-builder.d.ts +16 -0
- package/dist/infrastructure/transformers/history-builder.js +226 -0
- package/dist/infrastructure/transformers/message-transformer.d.ts +5 -0
- package/dist/infrastructure/transformers/message-transformer.js +99 -0
- package/dist/infrastructure/transformers/tool-call-parser.d.ts +4 -0
- package/dist/infrastructure/transformers/tool-call-parser.js +45 -0
- package/dist/infrastructure/transformers/tool-transformer.d.ts +2 -0
- package/dist/infrastructure/transformers/tool-transformer.js +19 -0
- package/dist/kiro/auth.d.ts +4 -0
- package/dist/kiro/auth.js +25 -0
- package/dist/kiro/oauth-idc.d.ts +25 -0
- package/dist/kiro/oauth-idc.js +167 -0
- package/dist/plugin/accounts.d.ts +29 -0
- package/dist/plugin/accounts.js +266 -0
- package/dist/plugin/auth-bootstrap.d.ts +9 -0
- package/dist/plugin/auth-bootstrap.js +69 -0
- package/dist/plugin/auth-page.d.ts +4 -0
- package/dist/plugin/auth-page.js +721 -0
- package/dist/plugin/config/index.d.ts +3 -0
- package/dist/plugin/config/index.js +2 -0
- package/dist/plugin/config/loader.d.ts +6 -0
- package/dist/plugin/config/loader.js +129 -0
- package/dist/plugin/config/schema.d.ts +88 -0
- package/dist/plugin/config/schema.js +94 -0
- package/dist/plugin/effort.d.ts +46 -0
- package/dist/plugin/effort.js +113 -0
- package/dist/plugin/errors.d.ts +17 -0
- package/dist/plugin/errors.js +34 -0
- package/dist/plugin/health.d.ts +1 -0
- package/dist/plugin/health.js +13 -0
- package/dist/plugin/image-handler.d.ts +18 -0
- package/dist/plugin/image-handler.js +82 -0
- package/dist/plugin/logger.d.ts +8 -0
- package/dist/plugin/logger.js +84 -0
- package/dist/plugin/models.d.ts +2 -0
- package/dist/plugin/models.js +11 -0
- package/dist/plugin/request.d.ts +9 -0
- package/dist/plugin/request.js +287 -0
- package/dist/plugin/response.d.ts +3 -0
- package/dist/plugin/response.js +97 -0
- package/dist/plugin/sdk-client.d.ts +4 -0
- package/dist/plugin/sdk-client.js +55 -0
- package/dist/plugin/storage/locked-operations.d.ts +5 -0
- package/dist/plugin/storage/locked-operations.js +103 -0
- package/dist/plugin/storage/migrations.d.ts +4 -0
- package/dist/plugin/storage/migrations.js +155 -0
- package/dist/plugin/storage/sqlite.d.ts +18 -0
- package/dist/plugin/storage/sqlite.js +166 -0
- package/dist/plugin/streaming/index.d.ts +2 -0
- package/dist/plugin/streaming/index.js +2 -0
- package/dist/plugin/streaming/openai-converter.d.ts +2 -0
- package/dist/plugin/streaming/openai-converter.js +81 -0
- package/dist/plugin/streaming/sdk-stream-transformer.d.ts +1 -0
- package/dist/plugin/streaming/sdk-stream-transformer.js +274 -0
- package/dist/plugin/streaming/stream-parser.d.ts +5 -0
- package/dist/plugin/streaming/stream-parser.js +136 -0
- package/dist/plugin/streaming/stream-state.d.ts +5 -0
- package/dist/plugin/streaming/stream-state.js +59 -0
- package/dist/plugin/streaming/stream-transformer.d.ts +1 -0
- package/dist/plugin/streaming/stream-transformer.js +295 -0
- package/dist/plugin/streaming/types.d.ts +25 -0
- package/dist/plugin/streaming/types.js +2 -0
- package/dist/plugin/sync/kiro-cli-parser.d.ts +8 -0
- package/dist/plugin/sync/kiro-cli-parser.js +72 -0
- package/dist/plugin/sync/kiro-cli-profile.d.ts +1 -0
- package/dist/plugin/sync/kiro-cli-profile.js +30 -0
- package/dist/plugin/sync/kiro-cli.d.ts +2 -0
- package/dist/plugin/sync/kiro-cli.js +212 -0
- package/dist/plugin/sync/stale-accounts.d.ts +9 -0
- package/dist/plugin/sync/stale-accounts.js +31 -0
- package/dist/plugin/token.d.ts +2 -0
- package/dist/plugin/token.js +78 -0
- package/dist/plugin/types.d.ts +125 -0
- package/dist/plugin/types.js +0 -0
- package/dist/plugin/usage.d.ts +3 -0
- package/dist/plugin/usage.js +79 -0
- package/dist/plugin.d.ts +174 -0
- package/dist/plugin.js +170 -0
- package/package.json +74 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type KiroConfig } from './schema.js';
|
|
2
|
+
export declare function getUserConfigPath(): string;
|
|
3
|
+
export declare function getProjectConfigPath(directory: string): string;
|
|
4
|
+
export declare function loadConfig(directory: string): KiroConfig;
|
|
5
|
+
export declare function configExists(path: string): boolean;
|
|
6
|
+
export declare function getDefaultLogsDir(): string;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import * as logger from '../logger.js';
|
|
5
|
+
import { AccountSelectionStrategySchema, DEFAULT_CONFIG, KiroConfigSchema, RegionSchema } from './schema.js';
|
|
6
|
+
function getConfigDir() {
|
|
7
|
+
const platform = process.platform;
|
|
8
|
+
if (platform === 'win32') {
|
|
9
|
+
return join(process.env.APPDATA || join(homedir(), 'AppData', 'Roaming'), 'opencode');
|
|
10
|
+
}
|
|
11
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || join(homedir(), '.config');
|
|
12
|
+
return join(xdgConfig, 'opencode');
|
|
13
|
+
}
|
|
14
|
+
export function getUserConfigPath() {
|
|
15
|
+
return join(getConfigDir(), 'kiro.json');
|
|
16
|
+
}
|
|
17
|
+
function ensureUserConfigTemplate() {
|
|
18
|
+
const path = getUserConfigPath();
|
|
19
|
+
if (!existsSync(path)) {
|
|
20
|
+
try {
|
|
21
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
22
|
+
writeFileSync(path, JSON.stringify(DEFAULT_CONFIG, null, 2), 'utf-8');
|
|
23
|
+
logger.log(`Created default config template at ${path}`);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
logger.warn(`Failed to create config template at ${path}: ${String(error)}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export function getProjectConfigPath(directory) {
|
|
31
|
+
return join(directory, '.opencode', 'kiro.json');
|
|
32
|
+
}
|
|
33
|
+
function loadConfigFile(path) {
|
|
34
|
+
try {
|
|
35
|
+
if (!existsSync(path)) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const content = readFileSync(path, 'utf-8');
|
|
39
|
+
const rawConfig = JSON.parse(content);
|
|
40
|
+
const result = KiroConfigSchema.partial().safeParse(rawConfig);
|
|
41
|
+
if (!result.success) {
|
|
42
|
+
const issues = result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join(', ');
|
|
43
|
+
logger.warn(`Config validation error at ${path}: ${issues}`);
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
return result.data;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (error instanceof SyntaxError) {
|
|
50
|
+
logger.warn(`Invalid JSON in config file ${path}: ${error.message}`);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
logger.warn(`Failed to load config file ${path}: ${String(error)}`);
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function mergeConfigs(base, override) {
|
|
59
|
+
return {
|
|
60
|
+
...base,
|
|
61
|
+
...override
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function parseBooleanEnv(value, fallback) {
|
|
65
|
+
if (value === undefined) {
|
|
66
|
+
return fallback;
|
|
67
|
+
}
|
|
68
|
+
if (value === '1' || value === 'true') {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
if (value === '0' || value === 'false') {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
return fallback;
|
|
75
|
+
}
|
|
76
|
+
function parseNumberEnv(value, fallback) {
|
|
77
|
+
if (value === undefined) {
|
|
78
|
+
return fallback;
|
|
79
|
+
}
|
|
80
|
+
const parsed = Number(value);
|
|
81
|
+
if (isNaN(parsed)) {
|
|
82
|
+
return fallback;
|
|
83
|
+
}
|
|
84
|
+
return parsed;
|
|
85
|
+
}
|
|
86
|
+
function applyEnvOverrides(config) {
|
|
87
|
+
const env = process.env;
|
|
88
|
+
return {
|
|
89
|
+
...config,
|
|
90
|
+
account_selection_strategy: env.KIRO_ACCOUNT_SELECTION_STRATEGY
|
|
91
|
+
? AccountSelectionStrategySchema.catch('lowest-usage').parse(env.KIRO_ACCOUNT_SELECTION_STRATEGY)
|
|
92
|
+
: config.account_selection_strategy,
|
|
93
|
+
default_region: env.KIRO_DEFAULT_REGION
|
|
94
|
+
? RegionSchema.catch('us-east-1').parse(env.KIRO_DEFAULT_REGION)
|
|
95
|
+
: config.default_region,
|
|
96
|
+
rate_limit_retry_delay_ms: parseNumberEnv(env.KIRO_RATE_LIMIT_RETRY_DELAY_MS, config.rate_limit_retry_delay_ms),
|
|
97
|
+
rate_limit_max_retries: parseNumberEnv(env.KIRO_RATE_LIMIT_MAX_RETRIES, config.rate_limit_max_retries),
|
|
98
|
+
max_request_iterations: parseNumberEnv(env.KIRO_MAX_REQUEST_ITERATIONS, config.max_request_iterations),
|
|
99
|
+
request_timeout_ms: parseNumberEnv(env.KIRO_REQUEST_TIMEOUT_MS, config.request_timeout_ms),
|
|
100
|
+
token_expiry_buffer_ms: parseNumberEnv(env.KIRO_TOKEN_EXPIRY_BUFFER_MS, config.token_expiry_buffer_ms),
|
|
101
|
+
usage_sync_max_retries: parseNumberEnv(env.KIRO_USAGE_SYNC_MAX_RETRIES, config.usage_sync_max_retries),
|
|
102
|
+
auth_server_port_start: parseNumberEnv(env.KIRO_AUTH_SERVER_PORT_START, config.auth_server_port_start),
|
|
103
|
+
auth_server_port_range: parseNumberEnv(env.KIRO_AUTH_SERVER_PORT_RANGE, config.auth_server_port_range),
|
|
104
|
+
usage_tracking_enabled: parseBooleanEnv(env.KIRO_USAGE_TRACKING_ENABLED, config.usage_tracking_enabled),
|
|
105
|
+
enable_log_api_request: parseBooleanEnv(env.KIRO_ENABLE_LOG_API_REQUEST, config.enable_log_api_request)
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
export function loadConfig(directory) {
|
|
109
|
+
ensureUserConfigTemplate();
|
|
110
|
+
let config = { ...DEFAULT_CONFIG };
|
|
111
|
+
const userConfigPath = getUserConfigPath();
|
|
112
|
+
const userConfig = loadConfigFile(userConfigPath);
|
|
113
|
+
if (userConfig) {
|
|
114
|
+
config = mergeConfigs(config, userConfig);
|
|
115
|
+
}
|
|
116
|
+
const projectConfigPath = getProjectConfigPath(directory);
|
|
117
|
+
const projectConfig = loadConfigFile(projectConfigPath);
|
|
118
|
+
if (projectConfig) {
|
|
119
|
+
config = mergeConfigs(config, projectConfig);
|
|
120
|
+
}
|
|
121
|
+
config = applyEnvOverrides(config);
|
|
122
|
+
return config;
|
|
123
|
+
}
|
|
124
|
+
export function configExists(path) {
|
|
125
|
+
return existsSync(path);
|
|
126
|
+
}
|
|
127
|
+
export function getDefaultLogsDir() {
|
|
128
|
+
return join(getConfigDir(), 'kiro-logs');
|
|
129
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const AccountSelectionStrategySchema: z.ZodEnum<["sticky", "round-robin", "lowest-usage"]>;
|
|
3
|
+
export type AccountSelectionStrategy = z.infer<typeof AccountSelectionStrategySchema>;
|
|
4
|
+
/**
|
|
5
|
+
* Kiro effort levels control thinking/reasoning depth.
|
|
6
|
+
* - low: minimal reasoning
|
|
7
|
+
* - medium: balanced (default when thinking enabled)
|
|
8
|
+
* - high: deeper reasoning
|
|
9
|
+
* - xhigh: extended reasoning (opus-4.7, opus-4.8 only)
|
|
10
|
+
* - max: maximum reasoning depth (128k thinking tokens on opus-4.7/4.8)
|
|
11
|
+
*/
|
|
12
|
+
export declare const EffortSchema: z.ZodEnum<["low", "medium", "high", "xhigh", "max"]>;
|
|
13
|
+
export type Effort = z.infer<typeof EffortSchema>;
|
|
14
|
+
export declare const RegionSchema: z.ZodEnum<["us-east-1", "us-east-2", "us-west-1", "us-west-2", "af-south-1", "ap-east-1", "ap-south-2", "ap-southeast-3", "ap-southeast-5", "ap-southeast-4", "ap-south-1", "ap-southeast-6", "ap-northeast-3", "ap-northeast-2", "ap-southeast-1", "ap-southeast-2", "ap-east-2", "ap-southeast-7", "ap-northeast-1", "ca-central-1", "ca-west-1", "eu-central-1", "eu-west-1", "eu-west-2", "eu-south-1", "eu-west-3", "eu-south-2", "eu-north-1", "eu-central-2", "il-central-1", "mx-central-1", "me-south-1", "me-central-1", "sa-east-1"]>;
|
|
15
|
+
export type Region = z.infer<typeof RegionSchema>;
|
|
16
|
+
export declare const KiroConfigSchema: z.ZodObject<{
|
|
17
|
+
$schema: z.ZodOptional<z.ZodString>;
|
|
18
|
+
idc_start_url: z.ZodOptional<z.ZodString>;
|
|
19
|
+
idc_region: z.ZodOptional<z.ZodEnum<["us-east-1", "us-east-2", "us-west-1", "us-west-2", "af-south-1", "ap-east-1", "ap-south-2", "ap-southeast-3", "ap-southeast-5", "ap-southeast-4", "ap-south-1", "ap-southeast-6", "ap-northeast-3", "ap-northeast-2", "ap-southeast-1", "ap-southeast-2", "ap-east-2", "ap-southeast-7", "ap-northeast-1", "ca-central-1", "ca-west-1", "eu-central-1", "eu-west-1", "eu-west-2", "eu-south-1", "eu-west-3", "eu-south-2", "eu-north-1", "eu-central-2", "il-central-1", "mx-central-1", "me-south-1", "me-central-1", "sa-east-1"]>>;
|
|
20
|
+
idc_profile_arn: z.ZodOptional<z.ZodString>;
|
|
21
|
+
account_selection_strategy: z.ZodDefault<z.ZodEnum<["sticky", "round-robin", "lowest-usage"]>>;
|
|
22
|
+
default_region: z.ZodDefault<z.ZodEnum<["us-east-1", "us-east-2", "us-west-1", "us-west-2", "af-south-1", "ap-east-1", "ap-south-2", "ap-southeast-3", "ap-southeast-5", "ap-southeast-4", "ap-south-1", "ap-southeast-6", "ap-northeast-3", "ap-northeast-2", "ap-southeast-1", "ap-southeast-2", "ap-east-2", "ap-southeast-7", "ap-northeast-1", "ca-central-1", "ca-west-1", "eu-central-1", "eu-west-1", "eu-west-2", "eu-south-1", "eu-west-3", "eu-south-2", "eu-north-1", "eu-central-2", "il-central-1", "mx-central-1", "me-south-1", "me-central-1", "sa-east-1"]>>;
|
|
23
|
+
rate_limit_retry_delay_ms: z.ZodDefault<z.ZodNumber>;
|
|
24
|
+
rate_limit_max_retries: z.ZodDefault<z.ZodNumber>;
|
|
25
|
+
max_request_iterations: z.ZodDefault<z.ZodNumber>;
|
|
26
|
+
request_timeout_ms: z.ZodDefault<z.ZodNumber>;
|
|
27
|
+
token_expiry_buffer_ms: z.ZodDefault<z.ZodNumber>;
|
|
28
|
+
usage_sync_max_retries: z.ZodDefault<z.ZodNumber>;
|
|
29
|
+
auth_server_port_start: z.ZodDefault<z.ZodNumber>;
|
|
30
|
+
auth_server_port_range: z.ZodDefault<z.ZodNumber>;
|
|
31
|
+
usage_tracking_enabled: z.ZodDefault<z.ZodBoolean>;
|
|
32
|
+
auto_sync_kiro_cli: z.ZodDefault<z.ZodBoolean>;
|
|
33
|
+
enable_log_api_request: z.ZodDefault<z.ZodBoolean>;
|
|
34
|
+
/**
|
|
35
|
+
* Default effort level for thinking models. Controls reasoning depth.
|
|
36
|
+
* When set, this overrides the automatic budget-based mapping.
|
|
37
|
+
* Values: 'low', 'medium', 'high', 'xhigh' (opus-4.7/4.8 only), 'max'
|
|
38
|
+
*/
|
|
39
|
+
effort: z.ZodOptional<z.ZodEnum<["low", "medium", "high", "xhigh", "max"]>>;
|
|
40
|
+
/**
|
|
41
|
+
* Enable automatic effort mapping from OpenCode's thinking budget.
|
|
42
|
+
* When true (default), maps budget ranges to effort levels.
|
|
43
|
+
* When false, only uses explicit effort config or falls back to 'medium'.
|
|
44
|
+
*/
|
|
45
|
+
auto_effort_mapping: z.ZodDefault<z.ZodBoolean>;
|
|
46
|
+
}, "strip", z.ZodTypeAny, {
|
|
47
|
+
account_selection_strategy: "sticky" | "round-robin" | "lowest-usage";
|
|
48
|
+
default_region: "us-east-1" | "us-east-2" | "us-west-1" | "us-west-2" | "af-south-1" | "ap-east-1" | "ap-south-2" | "ap-southeast-3" | "ap-southeast-5" | "ap-southeast-4" | "ap-south-1" | "ap-southeast-6" | "ap-northeast-3" | "ap-northeast-2" | "ap-southeast-1" | "ap-southeast-2" | "ap-east-2" | "ap-southeast-7" | "ap-northeast-1" | "ca-central-1" | "ca-west-1" | "eu-central-1" | "eu-west-1" | "eu-west-2" | "eu-south-1" | "eu-west-3" | "eu-south-2" | "eu-north-1" | "eu-central-2" | "il-central-1" | "mx-central-1" | "me-south-1" | "me-central-1" | "sa-east-1";
|
|
49
|
+
rate_limit_retry_delay_ms: number;
|
|
50
|
+
rate_limit_max_retries: number;
|
|
51
|
+
max_request_iterations: number;
|
|
52
|
+
request_timeout_ms: number;
|
|
53
|
+
token_expiry_buffer_ms: number;
|
|
54
|
+
usage_sync_max_retries: number;
|
|
55
|
+
auth_server_port_start: number;
|
|
56
|
+
auth_server_port_range: number;
|
|
57
|
+
usage_tracking_enabled: boolean;
|
|
58
|
+
auto_sync_kiro_cli: boolean;
|
|
59
|
+
enable_log_api_request: boolean;
|
|
60
|
+
auto_effort_mapping: boolean;
|
|
61
|
+
$schema?: string | undefined;
|
|
62
|
+
idc_start_url?: string | undefined;
|
|
63
|
+
idc_region?: "us-east-1" | "us-east-2" | "us-west-1" | "us-west-2" | "af-south-1" | "ap-east-1" | "ap-south-2" | "ap-southeast-3" | "ap-southeast-5" | "ap-southeast-4" | "ap-south-1" | "ap-southeast-6" | "ap-northeast-3" | "ap-northeast-2" | "ap-southeast-1" | "ap-southeast-2" | "ap-east-2" | "ap-southeast-7" | "ap-northeast-1" | "ca-central-1" | "ca-west-1" | "eu-central-1" | "eu-west-1" | "eu-west-2" | "eu-south-1" | "eu-west-3" | "eu-south-2" | "eu-north-1" | "eu-central-2" | "il-central-1" | "mx-central-1" | "me-south-1" | "me-central-1" | "sa-east-1" | undefined;
|
|
64
|
+
idc_profile_arn?: string | undefined;
|
|
65
|
+
effort?: "low" | "medium" | "high" | "xhigh" | "max" | undefined;
|
|
66
|
+
}, {
|
|
67
|
+
$schema?: string | undefined;
|
|
68
|
+
idc_start_url?: string | undefined;
|
|
69
|
+
idc_region?: "us-east-1" | "us-east-2" | "us-west-1" | "us-west-2" | "af-south-1" | "ap-east-1" | "ap-south-2" | "ap-southeast-3" | "ap-southeast-5" | "ap-southeast-4" | "ap-south-1" | "ap-southeast-6" | "ap-northeast-3" | "ap-northeast-2" | "ap-southeast-1" | "ap-southeast-2" | "ap-east-2" | "ap-southeast-7" | "ap-northeast-1" | "ca-central-1" | "ca-west-1" | "eu-central-1" | "eu-west-1" | "eu-west-2" | "eu-south-1" | "eu-west-3" | "eu-south-2" | "eu-north-1" | "eu-central-2" | "il-central-1" | "mx-central-1" | "me-south-1" | "me-central-1" | "sa-east-1" | undefined;
|
|
70
|
+
idc_profile_arn?: string | undefined;
|
|
71
|
+
account_selection_strategy?: "sticky" | "round-robin" | "lowest-usage" | undefined;
|
|
72
|
+
default_region?: "us-east-1" | "us-east-2" | "us-west-1" | "us-west-2" | "af-south-1" | "ap-east-1" | "ap-south-2" | "ap-southeast-3" | "ap-southeast-5" | "ap-southeast-4" | "ap-south-1" | "ap-southeast-6" | "ap-northeast-3" | "ap-northeast-2" | "ap-southeast-1" | "ap-southeast-2" | "ap-east-2" | "ap-southeast-7" | "ap-northeast-1" | "ca-central-1" | "ca-west-1" | "eu-central-1" | "eu-west-1" | "eu-west-2" | "eu-south-1" | "eu-west-3" | "eu-south-2" | "eu-north-1" | "eu-central-2" | "il-central-1" | "mx-central-1" | "me-south-1" | "me-central-1" | "sa-east-1" | undefined;
|
|
73
|
+
rate_limit_retry_delay_ms?: number | undefined;
|
|
74
|
+
rate_limit_max_retries?: number | undefined;
|
|
75
|
+
max_request_iterations?: number | undefined;
|
|
76
|
+
request_timeout_ms?: number | undefined;
|
|
77
|
+
token_expiry_buffer_ms?: number | undefined;
|
|
78
|
+
usage_sync_max_retries?: number | undefined;
|
|
79
|
+
auth_server_port_start?: number | undefined;
|
|
80
|
+
auth_server_port_range?: number | undefined;
|
|
81
|
+
usage_tracking_enabled?: boolean | undefined;
|
|
82
|
+
auto_sync_kiro_cli?: boolean | undefined;
|
|
83
|
+
enable_log_api_request?: boolean | undefined;
|
|
84
|
+
effort?: "low" | "medium" | "high" | "xhigh" | "max" | undefined;
|
|
85
|
+
auto_effort_mapping?: boolean | undefined;
|
|
86
|
+
}>;
|
|
87
|
+
export type KiroConfig = z.infer<typeof KiroConfigSchema>;
|
|
88
|
+
export declare const DEFAULT_CONFIG: KiroConfig;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const AccountSelectionStrategySchema = z.enum(['sticky', 'round-robin', 'lowest-usage']);
|
|
3
|
+
/**
|
|
4
|
+
* Kiro effort levels control thinking/reasoning depth.
|
|
5
|
+
* - low: minimal reasoning
|
|
6
|
+
* - medium: balanced (default when thinking enabled)
|
|
7
|
+
* - high: deeper reasoning
|
|
8
|
+
* - xhigh: extended reasoning (opus-4.7, opus-4.8 only)
|
|
9
|
+
* - max: maximum reasoning depth (128k thinking tokens on opus-4.7/4.8)
|
|
10
|
+
*/
|
|
11
|
+
export const EffortSchema = z.enum(['low', 'medium', 'high', 'xhigh', 'max']);
|
|
12
|
+
export const RegionSchema = z.enum([
|
|
13
|
+
'us-east-1',
|
|
14
|
+
'us-east-2',
|
|
15
|
+
'us-west-1',
|
|
16
|
+
'us-west-2',
|
|
17
|
+
'af-south-1',
|
|
18
|
+
'ap-east-1',
|
|
19
|
+
'ap-south-2',
|
|
20
|
+
'ap-southeast-3',
|
|
21
|
+
'ap-southeast-5',
|
|
22
|
+
'ap-southeast-4',
|
|
23
|
+
'ap-south-1',
|
|
24
|
+
'ap-southeast-6',
|
|
25
|
+
'ap-northeast-3',
|
|
26
|
+
'ap-northeast-2',
|
|
27
|
+
'ap-southeast-1',
|
|
28
|
+
'ap-southeast-2',
|
|
29
|
+
'ap-east-2',
|
|
30
|
+
'ap-southeast-7',
|
|
31
|
+
'ap-northeast-1',
|
|
32
|
+
'ca-central-1',
|
|
33
|
+
'ca-west-1',
|
|
34
|
+
'eu-central-1',
|
|
35
|
+
'eu-west-1',
|
|
36
|
+
'eu-west-2',
|
|
37
|
+
'eu-south-1',
|
|
38
|
+
'eu-west-3',
|
|
39
|
+
'eu-south-2',
|
|
40
|
+
'eu-north-1',
|
|
41
|
+
'eu-central-2',
|
|
42
|
+
'il-central-1',
|
|
43
|
+
'mx-central-1',
|
|
44
|
+
'me-south-1',
|
|
45
|
+
'me-central-1',
|
|
46
|
+
'sa-east-1'
|
|
47
|
+
]);
|
|
48
|
+
export const KiroConfigSchema = z.object({
|
|
49
|
+
$schema: z.string().optional(),
|
|
50
|
+
idc_start_url: z.string().url().optional(),
|
|
51
|
+
idc_region: RegionSchema.optional(),
|
|
52
|
+
idc_profile_arn: z.string().optional(),
|
|
53
|
+
account_selection_strategy: AccountSelectionStrategySchema.default('lowest-usage'),
|
|
54
|
+
default_region: RegionSchema.default('us-east-1'),
|
|
55
|
+
rate_limit_retry_delay_ms: z.number().min(1000).max(60000).default(5000),
|
|
56
|
+
rate_limit_max_retries: z.number().min(0).max(10).default(3),
|
|
57
|
+
max_request_iterations: z.number().min(5).max(1000).default(20),
|
|
58
|
+
request_timeout_ms: z.number().min(30000).max(600000).default(120000),
|
|
59
|
+
token_expiry_buffer_ms: z.number().min(30000).max(300000).default(300000),
|
|
60
|
+
usage_sync_max_retries: z.number().min(0).max(5).default(3),
|
|
61
|
+
auth_server_port_start: z.number().min(1024).max(65535).default(19847),
|
|
62
|
+
auth_server_port_range: z.number().min(1).max(100).default(10),
|
|
63
|
+
usage_tracking_enabled: z.boolean().default(true),
|
|
64
|
+
auto_sync_kiro_cli: z.boolean().default(true),
|
|
65
|
+
enable_log_api_request: z.boolean().default(false),
|
|
66
|
+
/**
|
|
67
|
+
* Default effort level for thinking models. Controls reasoning depth.
|
|
68
|
+
* When set, this overrides the automatic budget-based mapping.
|
|
69
|
+
* Values: 'low', 'medium', 'high', 'xhigh' (opus-4.7/4.8 only), 'max'
|
|
70
|
+
*/
|
|
71
|
+
effort: EffortSchema.optional(),
|
|
72
|
+
/**
|
|
73
|
+
* Enable automatic effort mapping from OpenCode's thinking budget.
|
|
74
|
+
* When true (default), maps budget ranges to effort levels.
|
|
75
|
+
* When false, only uses explicit effort config or falls back to 'medium'.
|
|
76
|
+
*/
|
|
77
|
+
auto_effort_mapping: z.boolean().default(true)
|
|
78
|
+
});
|
|
79
|
+
export const DEFAULT_CONFIG = {
|
|
80
|
+
account_selection_strategy: 'lowest-usage',
|
|
81
|
+
default_region: 'us-east-1',
|
|
82
|
+
rate_limit_retry_delay_ms: 5000,
|
|
83
|
+
rate_limit_max_retries: 3,
|
|
84
|
+
max_request_iterations: 20,
|
|
85
|
+
request_timeout_ms: 120000,
|
|
86
|
+
token_expiry_buffer_ms: 300000,
|
|
87
|
+
usage_sync_max_retries: 3,
|
|
88
|
+
auth_server_port_start: 19847,
|
|
89
|
+
auth_server_port_range: 10,
|
|
90
|
+
usage_tracking_enabled: true,
|
|
91
|
+
auto_sync_kiro_cli: true,
|
|
92
|
+
enable_log_api_request: false,
|
|
93
|
+
auto_effort_mapping: true
|
|
94
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Effort } from './config/schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* Effort levels ordered from lowest to highest reasoning depth.
|
|
4
|
+
*/
|
|
5
|
+
export declare const EFFORT_LEVELS: readonly Effort[];
|
|
6
|
+
/**
|
|
7
|
+
* Check if a model supports the effort parameter.
|
|
8
|
+
*/
|
|
9
|
+
export declare function supportsEffort(kiroModel: string): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Check if a model supports xhigh effort level.
|
|
12
|
+
*/
|
|
13
|
+
export declare function supportsXHighEffort(kiroModel: string): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Resolve effort level for a given model.
|
|
16
|
+
* - Returns undefined if model doesn't support effort
|
|
17
|
+
* - Clamps xhigh to max for models that don't support it
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveEffort(kiroModel: string, requested: Effort): Effort | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Map OpenCode thinking budget to Kiro effort level.
|
|
22
|
+
*
|
|
23
|
+
* OpenCode sends thinkingBudget from its variant config. Standard values:
|
|
24
|
+
* - low: 8192
|
|
25
|
+
* - medium: 16384
|
|
26
|
+
* - high: 24576
|
|
27
|
+
* - max: 32768
|
|
28
|
+
*
|
|
29
|
+
* We map these ranges to Kiro effort levels:
|
|
30
|
+
* - ≤10000 → low
|
|
31
|
+
* - ≤20000 → medium
|
|
32
|
+
* - ≤28000 → high
|
|
33
|
+
* - ≤32768 → max (or xhigh on opus-4.7/4.8, max otherwise)
|
|
34
|
+
* - >32768 → max
|
|
35
|
+
*/
|
|
36
|
+
export declare function budgetToEffort(budget: number, kiroModel: string): Effort | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Get the effective effort level based on config, budget, and model.
|
|
39
|
+
*
|
|
40
|
+
* Priority:
|
|
41
|
+
* 1. Explicit effort config (if set) - always applied regardless of thinking state
|
|
42
|
+
* 2. Budget-to-effort mapping (if auto_effort_mapping enabled and thinking)
|
|
43
|
+
* 3. 'medium' default (if thinking enabled)
|
|
44
|
+
* 4. undefined (if not thinking)
|
|
45
|
+
*/
|
|
46
|
+
export declare function getEffectiveEffort(kiroModel: string, thinking: boolean, budget: number, configEffort?: Effort, autoEffortMapping?: boolean): Effort | undefined;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Effort levels ordered from lowest to highest reasoning depth.
|
|
3
|
+
*/
|
|
4
|
+
export const EFFORT_LEVELS = ['low', 'medium', 'high', 'xhigh', 'max'];
|
|
5
|
+
/**
|
|
6
|
+
* Models that support the 5-value effort enum (including xhigh).
|
|
7
|
+
* These models support up to 128k thinking tokens with max effort.
|
|
8
|
+
*/
|
|
9
|
+
const XHIGH_CAPABLE_MODELS = new Set(['claude-opus-4.7', 'claude-opus-4.8']);
|
|
10
|
+
/**
|
|
11
|
+
* Models that support the 4-value effort enum (no xhigh).
|
|
12
|
+
* xhigh requests on these models are clamped to max.
|
|
13
|
+
*/
|
|
14
|
+
const EFFORT_CAPABLE_MODELS = new Set([
|
|
15
|
+
'claude-opus-4.5',
|
|
16
|
+
'claude-opus-4.6',
|
|
17
|
+
'claude-opus-4.6-1m',
|
|
18
|
+
'claude-sonnet-4.5',
|
|
19
|
+
'claude-sonnet-4.5-1m',
|
|
20
|
+
'claude-sonnet-4.6',
|
|
21
|
+
'claude-sonnet-4.6-1m',
|
|
22
|
+
...XHIGH_CAPABLE_MODELS
|
|
23
|
+
]);
|
|
24
|
+
/**
|
|
25
|
+
* Check if a model supports the effort parameter.
|
|
26
|
+
*/
|
|
27
|
+
export function supportsEffort(kiroModel) {
|
|
28
|
+
return EFFORT_CAPABLE_MODELS.has(kiroModel);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Check if a model supports xhigh effort level.
|
|
32
|
+
*/
|
|
33
|
+
export function supportsXHighEffort(kiroModel) {
|
|
34
|
+
return XHIGH_CAPABLE_MODELS.has(kiroModel);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Resolve effort level for a given model.
|
|
38
|
+
* - Returns undefined if model doesn't support effort
|
|
39
|
+
* - Clamps xhigh to max for models that don't support it
|
|
40
|
+
*/
|
|
41
|
+
export function resolveEffort(kiroModel, requested) {
|
|
42
|
+
if (!supportsEffort(kiroModel)) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
// xhigh is only supported on opus-4.7 and opus-4.8
|
|
46
|
+
if (requested === 'xhigh' && !supportsXHighEffort(kiroModel)) {
|
|
47
|
+
return 'max';
|
|
48
|
+
}
|
|
49
|
+
return requested;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Map OpenCode thinking budget to Kiro effort level.
|
|
53
|
+
*
|
|
54
|
+
* OpenCode sends thinkingBudget from its variant config. Standard values:
|
|
55
|
+
* - low: 8192
|
|
56
|
+
* - medium: 16384
|
|
57
|
+
* - high: 24576
|
|
58
|
+
* - max: 32768
|
|
59
|
+
*
|
|
60
|
+
* We map these ranges to Kiro effort levels:
|
|
61
|
+
* - ≤10000 → low
|
|
62
|
+
* - ≤20000 → medium
|
|
63
|
+
* - ≤28000 → high
|
|
64
|
+
* - ≤32768 → max (or xhigh on opus-4.7/4.8, max otherwise)
|
|
65
|
+
* - >32768 → max
|
|
66
|
+
*/
|
|
67
|
+
export function budgetToEffort(budget, kiroModel) {
|
|
68
|
+
if (!supportsEffort(kiroModel)) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
let effort;
|
|
72
|
+
if (budget <= 10000) {
|
|
73
|
+
effort = 'low';
|
|
74
|
+
}
|
|
75
|
+
else if (budget <= 20000) {
|
|
76
|
+
effort = 'medium';
|
|
77
|
+
}
|
|
78
|
+
else if (budget <= 28000) {
|
|
79
|
+
effort = 'high';
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
effort = 'max';
|
|
83
|
+
}
|
|
84
|
+
return effort;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get the effective effort level based on config, budget, and model.
|
|
88
|
+
*
|
|
89
|
+
* Priority:
|
|
90
|
+
* 1. Explicit effort config (if set) - always applied regardless of thinking state
|
|
91
|
+
* 2. Budget-to-effort mapping (if auto_effort_mapping enabled and thinking)
|
|
92
|
+
* 3. 'medium' default (if thinking enabled)
|
|
93
|
+
* 4. undefined (if not thinking)
|
|
94
|
+
*/
|
|
95
|
+
export function getEffectiveEffort(kiroModel, thinking, budget, configEffort, autoEffortMapping = true) {
|
|
96
|
+
if (!supportsEffort(kiroModel)) {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
// Explicit config takes precedence - always applied even without thinking
|
|
100
|
+
if (configEffort) {
|
|
101
|
+
return resolveEffort(kiroModel, configEffort);
|
|
102
|
+
}
|
|
103
|
+
// If not thinking, no effort needed
|
|
104
|
+
if (!thinking) {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
// Auto-map budget to effort
|
|
108
|
+
if (autoEffortMapping) {
|
|
109
|
+
return budgetToEffort(budget, kiroModel);
|
|
110
|
+
}
|
|
111
|
+
// Default to medium when thinking without auto-mapping
|
|
112
|
+
return 'medium';
|
|
113
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare class KiroTokenRefreshError extends Error {
|
|
2
|
+
code?: string;
|
|
3
|
+
originalError?: Error;
|
|
4
|
+
constructor(message: string, code?: string, originalError?: Error);
|
|
5
|
+
}
|
|
6
|
+
export declare class KiroQuotaExhaustedError extends Error {
|
|
7
|
+
recoveryTime?: number;
|
|
8
|
+
constructor(message: string, recoveryTime?: number);
|
|
9
|
+
}
|
|
10
|
+
export declare class KiroRateLimitError extends Error {
|
|
11
|
+
retryAfter?: number;
|
|
12
|
+
constructor(message: string, retryAfter?: number);
|
|
13
|
+
}
|
|
14
|
+
export declare class KiroAuthError extends Error {
|
|
15
|
+
statusCode?: number;
|
|
16
|
+
constructor(message: string, statusCode?: number);
|
|
17
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export class KiroTokenRefreshError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
originalError;
|
|
4
|
+
constructor(message, code, originalError) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = 'KiroTokenRefreshError';
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.originalError = originalError;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export class KiroQuotaExhaustedError extends Error {
|
|
12
|
+
recoveryTime;
|
|
13
|
+
constructor(message, recoveryTime) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = 'KiroQuotaExhaustedError';
|
|
16
|
+
this.recoveryTime = recoveryTime;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class KiroRateLimitError extends Error {
|
|
20
|
+
retryAfter;
|
|
21
|
+
constructor(message, retryAfter) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = 'KiroRateLimitError';
|
|
24
|
+
this.retryAfter = retryAfter;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export class KiroAuthError extends Error {
|
|
28
|
+
statusCode;
|
|
29
|
+
constructor(message, statusCode) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.name = 'KiroAuthError';
|
|
32
|
+
this.statusCode = statusCode;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isPermanentError(reason?: string): boolean;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function isPermanentError(reason) {
|
|
2
|
+
if (!reason)
|
|
3
|
+
return false;
|
|
4
|
+
return (reason.includes('Invalid refresh token') ||
|
|
5
|
+
reason.includes('Invalid grant provided') ||
|
|
6
|
+
reason.includes('invalid_grant') ||
|
|
7
|
+
reason.includes('ExpiredTokenException') ||
|
|
8
|
+
reason.includes('InvalidTokenException') ||
|
|
9
|
+
reason.includes('ExpiredClientException') ||
|
|
10
|
+
reason.includes('Client is expired') ||
|
|
11
|
+
reason.includes('HTTP_401') ||
|
|
12
|
+
reason.includes('HTTP_403'));
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface UnifiedImage {
|
|
2
|
+
mediaType: string;
|
|
3
|
+
data: string;
|
|
4
|
+
}
|
|
5
|
+
interface KiroImage {
|
|
6
|
+
format: string;
|
|
7
|
+
source: {
|
|
8
|
+
bytes: Uint8Array;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
interface ImageConversionResult {
|
|
12
|
+
images: KiroImage[];
|
|
13
|
+
omitted: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function extractAllImages(content: any): UnifiedImage[];
|
|
16
|
+
export declare function convertImagesToKiroFormat(images: UnifiedImage[]): ImageConversionResult;
|
|
17
|
+
export declare function extractTextFromParts(parts: any[]): string;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const MAX_KIRO_IMAGES = 4;
|
|
2
|
+
const MAX_KIRO_IMAGE_BYTES = 3_750_000;
|
|
3
|
+
/** Decode base64 to a plain Uint8Array (NOT Buffer) to avoid Buffer.toJSON() trap. */
|
|
4
|
+
function base64ToUint8Array(b64) {
|
|
5
|
+
const bin = atob(b64);
|
|
6
|
+
const arr = new Uint8Array(bin.length);
|
|
7
|
+
for (let i = 0; i < bin.length; i++)
|
|
8
|
+
arr[i] = bin.charCodeAt(i);
|
|
9
|
+
return arr;
|
|
10
|
+
}
|
|
11
|
+
function extractImagesFromAnthropicFormat(content) {
|
|
12
|
+
const images = [];
|
|
13
|
+
for (const item of content) {
|
|
14
|
+
if (item.type === 'image' && item.source?.type === 'base64') {
|
|
15
|
+
images.push({
|
|
16
|
+
mediaType: item.source.media_type || 'image/jpeg',
|
|
17
|
+
data: item.source.data
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return images;
|
|
22
|
+
}
|
|
23
|
+
function extractImagesFromOpenAI(content) {
|
|
24
|
+
const images = [];
|
|
25
|
+
for (const item of content) {
|
|
26
|
+
if (item.type === 'image_url' && item.image_url?.url) {
|
|
27
|
+
const url = item.image_url.url;
|
|
28
|
+
if (url.startsWith('data:')) {
|
|
29
|
+
try {
|
|
30
|
+
const [header, data] = url.split(',', 2);
|
|
31
|
+
if (!data)
|
|
32
|
+
continue;
|
|
33
|
+
const mediaType = header.split(';')[0].replace('data:', '');
|
|
34
|
+
images.push({
|
|
35
|
+
mediaType: mediaType || 'image/jpeg',
|
|
36
|
+
data: data
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return images;
|
|
46
|
+
}
|
|
47
|
+
export function extractAllImages(content) {
|
|
48
|
+
if (!Array.isArray(content))
|
|
49
|
+
return [];
|
|
50
|
+
return [...extractImagesFromAnthropicFormat(content), ...extractImagesFromOpenAI(content)];
|
|
51
|
+
}
|
|
52
|
+
export function convertImagesToKiroFormat(images) {
|
|
53
|
+
const selected = [];
|
|
54
|
+
let totalBase64Chars = 0;
|
|
55
|
+
for (const img of images) {
|
|
56
|
+
if (selected.length >= MAX_KIRO_IMAGES)
|
|
57
|
+
break;
|
|
58
|
+
if (totalBase64Chars + img.data.length > MAX_KIRO_IMAGE_BYTES)
|
|
59
|
+
break;
|
|
60
|
+
selected.push(img);
|
|
61
|
+
totalBase64Chars += img.data.length;
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
images: selected.map((img) => {
|
|
65
|
+
const format = img.mediaType.split('/')[1] || 'png';
|
|
66
|
+
return { format, source: { bytes: base64ToUint8Array(img.data) } };
|
|
67
|
+
}),
|
|
68
|
+
omitted: images.length - selected.length
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export function extractTextFromParts(parts) {
|
|
72
|
+
const textParts = [];
|
|
73
|
+
for (const part of parts) {
|
|
74
|
+
if (part.text && typeof part.text === 'string') {
|
|
75
|
+
textParts.push(part.text);
|
|
76
|
+
}
|
|
77
|
+
else if (part.type === 'text' && part.text) {
|
|
78
|
+
textParts.push(part.text);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return textParts.join('');
|
|
82
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function log(message: string, ...args: unknown[]): void;
|
|
2
|
+
export declare function error(message: string, ...args: unknown[]): void;
|
|
3
|
+
export declare function warn(message: string, ...args: unknown[]): void;
|
|
4
|
+
export declare function debug(message: string, ...args: unknown[]): void;
|
|
5
|
+
export declare function logApiRequest(data: any, timestamp: string): void;
|
|
6
|
+
export declare function logApiResponse(data: any, timestamp: string): void;
|
|
7
|
+
export declare function logApiError(requestData: any, responseData: any, timestamp: string): void;
|
|
8
|
+
export declare function getTimestamp(): string;
|