@zhafron/opencode-kiro-auth 1.1.0 → 1.1.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.
@@ -15,6 +15,7 @@ export declare const KiroConfigSchema: z.ZodObject<{
15
15
  rate_limit_retry_delay_ms: z.ZodDefault<z.ZodNumber>;
16
16
  rate_limit_max_retries: z.ZodDefault<z.ZodNumber>;
17
17
  usage_tracking_enabled: z.ZodDefault<z.ZodBoolean>;
18
+ enable_log_api_request: z.ZodDefault<z.ZodBoolean>;
18
19
  }, "strip", z.ZodTypeAny, {
19
20
  session_recovery: boolean;
20
21
  auto_resume: boolean;
@@ -26,6 +27,7 @@ export declare const KiroConfigSchema: z.ZodObject<{
26
27
  rate_limit_retry_delay_ms: number;
27
28
  rate_limit_max_retries: number;
28
29
  usage_tracking_enabled: boolean;
30
+ enable_log_api_request: boolean;
29
31
  $schema?: string | undefined;
30
32
  }, {
31
33
  $schema?: string | undefined;
@@ -39,6 +41,7 @@ export declare const KiroConfigSchema: z.ZodObject<{
39
41
  rate_limit_retry_delay_ms?: number | undefined;
40
42
  rate_limit_max_retries?: number | undefined;
41
43
  usage_tracking_enabled?: boolean | undefined;
44
+ enable_log_api_request?: boolean | undefined;
42
45
  }>;
43
46
  export type KiroConfig = z.infer<typeof KiroConfigSchema>;
44
47
  export declare const DEFAULT_CONFIG: KiroConfig;
@@ -12,7 +12,8 @@ export const KiroConfigSchema = z.object({
12
12
  default_region: RegionSchema.default('us-east-1'),
13
13
  rate_limit_retry_delay_ms: z.number().min(1000).max(60000).default(5000),
14
14
  rate_limit_max_retries: z.number().min(0).max(10).default(3),
15
- usage_tracking_enabled: z.boolean().default(true)
15
+ usage_tracking_enabled: z.boolean().default(true),
16
+ enable_log_api_request: z.boolean().default(false)
16
17
  });
17
18
  export const DEFAULT_CONFIG = {
18
19
  session_recovery: true,
@@ -24,5 +25,6 @@ export const DEFAULT_CONFIG = {
24
25
  default_region: 'us-east-1',
25
26
  rate_limit_retry_delay_ms: 5000,
26
27
  rate_limit_max_retries: 3,
27
- usage_tracking_enabled: true
28
+ usage_tracking_enabled: true,
29
+ enable_log_api_request: false
28
30
  };
@@ -2,3 +2,6 @@ export declare function log(message: string, ...args: unknown[]): void;
2
2
  export declare function error(message: string, ...args: unknown[]): void;
3
3
  export declare function warn(message: string, ...args: unknown[]): void;
4
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 getTimestamp(): string;
@@ -1,4 +1,4 @@
1
- import { appendFileSync, mkdirSync } from 'node:fs';
1
+ import { appendFileSync, mkdirSync, writeFileSync } from 'node:fs';
2
2
  import { homedir } from 'node:os';
3
3
  import { join } from 'node:path';
4
4
  const getLogDir = () => {
@@ -19,6 +19,17 @@ const writeToFile = (level, message, ...args) => {
19
19
  }
20
20
  catch (e) { }
21
21
  };
22
+ const writeApiLog = (type, data, timestamp) => {
23
+ try {
24
+ const dir = getLogDir();
25
+ mkdirSync(dir, { recursive: true });
26
+ const filename = `${timestamp}_${type}.json`;
27
+ const path = join(dir, filename);
28
+ const content = JSON.stringify(data, null, 2);
29
+ writeFileSync(path, content);
30
+ }
31
+ catch (e) { }
32
+ };
22
33
  export function log(message, ...args) {
23
34
  writeToFile('INFO', message, ...args);
24
35
  }
@@ -33,3 +44,12 @@ export function debug(message, ...args) {
33
44
  writeToFile('DEBUG', message, ...args);
34
45
  }
35
46
  }
47
+ export function logApiRequest(data, timestamp) {
48
+ writeApiLog('request', data, timestamp);
49
+ }
50
+ export function logApiResponse(data, timestamp) {
51
+ writeApiLog('response', data, timestamp);
52
+ }
53
+ export function getTimestamp() {
54
+ return new Date().toISOString().replace(/[:.]/g, '-');
55
+ }
@@ -81,6 +81,10 @@ export function transformToCodeWhisperer(url, body, model, auth, think = false,
81
81
  uim.images = imgs;
82
82
  if (trs.length)
83
83
  uim.userInputMessageContext = { toolResults: deduplicateToolResults(trs) };
84
+ const prev = history[history.length - 1];
85
+ if (prev && prev.userInputMessage) {
86
+ history.push({ assistantResponseMessage: { content: 'Continue' } });
87
+ }
84
88
  history.push({ userInputMessage: uim });
85
89
  }
86
90
  else if (m.role === 'tool') {
@@ -100,6 +104,10 @@ export function transformToCodeWhisperer(url, body, model, auth, think = false,
100
104
  toolUseId: m.tool_call_id
101
105
  });
102
106
  }
107
+ const prev = history[history.length - 1];
108
+ if (prev && prev.userInputMessage) {
109
+ history.push({ assistantResponseMessage: { content: 'Continue' } });
110
+ }
103
111
  history.push({
104
112
  userInputMessage: {
105
113
  content: 'Tool results provided.',
package/dist/plugin.js CHANGED
@@ -72,8 +72,41 @@ export const createKiroPlugin = (id) => async ({ client, directory }) => {
72
72
  }
73
73
  }
74
74
  const prep = transformToCodeWhisperer(url, init?.body, model, auth, think, budget);
75
+ const apiTimestamp = config.enable_log_api_request ? logger.getTimestamp() : null;
76
+ if (config.enable_log_api_request && apiTimestamp) {
77
+ let parsedBody = null;
78
+ if (prep.init.body && typeof prep.init.body === 'string') {
79
+ try {
80
+ parsedBody = JSON.parse(prep.init.body);
81
+ }
82
+ catch (e) {
83
+ parsedBody = prep.init.body;
84
+ }
85
+ }
86
+ logger.logApiRequest({
87
+ url: prep.url,
88
+ method: prep.init.method,
89
+ headers: prep.init.headers,
90
+ body: parsedBody,
91
+ conversationId: prep.conversationId,
92
+ model: prep.effectiveModel
93
+ }, apiTimestamp);
94
+ }
75
95
  try {
76
96
  const res = await fetch(prep.url, prep.init);
97
+ if (config.enable_log_api_request && apiTimestamp) {
98
+ const responseHeaders = {};
99
+ res.headers.forEach((value, key) => {
100
+ responseHeaders[key] = value;
101
+ });
102
+ logger.logApiResponse({
103
+ status: res.status,
104
+ statusText: res.statusText,
105
+ headers: responseHeaders,
106
+ conversationId: prep.conversationId,
107
+ model: prep.effectiveModel
108
+ }, apiTimestamp);
109
+ }
77
110
  if (res.ok) {
78
111
  if (config.usage_tracking_enabled)
79
112
  fetchUsageLimits(auth)
@@ -155,9 +188,30 @@ export const createKiroPlugin = (id) => async ({ client, directory }) => {
155
188
  await am.saveToDisk();
156
189
  continue;
157
190
  }
191
+ if (config.enable_log_api_request && apiTimestamp) {
192
+ const responseHeaders = {};
193
+ res.headers.forEach((value, key) => {
194
+ responseHeaders[key] = value;
195
+ });
196
+ logger.logApiResponse({
197
+ status: res.status,
198
+ statusText: res.statusText,
199
+ headers: responseHeaders,
200
+ error: `Kiro Error: ${res.status}`,
201
+ conversationId: prep.conversationId,
202
+ model: prep.effectiveModel
203
+ }, apiTimestamp);
204
+ }
158
205
  throw new Error(`Kiro Error: ${res.status}`);
159
206
  }
160
207
  catch (e) {
208
+ if (config.enable_log_api_request && apiTimestamp) {
209
+ logger.logApiResponse({
210
+ error: String(e),
211
+ conversationId: prep.conversationId,
212
+ model: prep.effectiveModel
213
+ }, apiTimestamp);
214
+ }
161
215
  if (isNetworkError(e) && retry < config.rate_limit_max_retries) {
162
216
  const delay = 5000 * Math.pow(2, retry);
163
217
  showToast(`Network error. Retrying in ${Math.ceil(delay / 1000)}s...`, 'warning');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhafron/opencode-kiro-auth",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "OpenCode plugin for AWS Kiro (CodeWhisperer) providing access to Claude models",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",