@arvoretech/pi-kiro-provider 0.8.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.
Files changed (74) hide show
  1. package/README.md +121 -0
  2. package/dist/bracket-tool-parser.d.ts +12 -0
  3. package/dist/bracket-tool-parser.d.ts.map +1 -0
  4. package/dist/bracket-tool-parser.js +78 -0
  5. package/dist/bracket-tool-parser.js.map +1 -0
  6. package/dist/debug.d.ts +3 -0
  7. package/dist/debug.d.ts.map +1 -0
  8. package/dist/debug.js +49 -0
  9. package/dist/debug.js.map +1 -0
  10. package/dist/event-parser.d.ts +44 -0
  11. package/dist/event-parser.d.ts.map +1 -0
  12. package/dist/event-parser.js +66 -0
  13. package/dist/event-parser.js.map +1 -0
  14. package/dist/history.d.ts +13 -0
  15. package/dist/history.d.ts.map +1 -0
  16. package/dist/history.js +121 -0
  17. package/dist/history.js.map +1 -0
  18. package/dist/index.d.ts +6 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +44 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/kiro-cli.d.ts +32 -0
  23. package/dist/kiro-cli.d.ts.map +1 -0
  24. package/dist/kiro-cli.js +271 -0
  25. package/dist/kiro-cli.js.map +1 -0
  26. package/dist/kiro-ide.d.ts +13 -0
  27. package/dist/kiro-ide.d.ts.map +1 -0
  28. package/dist/kiro-ide.js +74 -0
  29. package/dist/kiro-ide.js.map +1 -0
  30. package/dist/login-ui.d.ts +18 -0
  31. package/dist/login-ui.d.ts.map +1 -0
  32. package/dist/login-ui.js +124 -0
  33. package/dist/login-ui.js.map +1 -0
  34. package/dist/login.d.ts +16 -0
  35. package/dist/login.d.ts.map +1 -0
  36. package/dist/login.js +217 -0
  37. package/dist/login.js.map +1 -0
  38. package/dist/models.d.ts +72 -0
  39. package/dist/models.d.ts.map +1 -0
  40. package/dist/models.js +461 -0
  41. package/dist/models.js.map +1 -0
  42. package/dist/oauth.d.ts +30 -0
  43. package/dist/oauth.d.ts.map +1 -0
  44. package/dist/oauth.js +226 -0
  45. package/dist/oauth.js.map +1 -0
  46. package/dist/retry.d.ts +21 -0
  47. package/dist/retry.d.ts.map +1 -0
  48. package/dist/retry.js +51 -0
  49. package/dist/retry.js.map +1 -0
  50. package/dist/stream.d.ts +5 -0
  51. package/dist/stream.d.ts.map +1 -0
  52. package/dist/stream.js +858 -0
  53. package/dist/stream.js.map +1 -0
  54. package/dist/thinking-parser.d.ts +24 -0
  55. package/dist/thinking-parser.d.ts.map +1 -0
  56. package/dist/thinking-parser.js +205 -0
  57. package/dist/thinking-parser.js.map +1 -0
  58. package/dist/tokenizer.d.ts +2 -0
  59. package/dist/tokenizer.d.ts.map +1 -0
  60. package/dist/tokenizer.js +16 -0
  61. package/dist/tokenizer.js.map +1 -0
  62. package/dist/transform.d.ts +63 -0
  63. package/dist/transform.d.ts.map +1 -0
  64. package/dist/transform.js +200 -0
  65. package/dist/transform.js.map +1 -0
  66. package/dist/truncation.d.ts +4 -0
  67. package/dist/truncation.d.ts.map +1 -0
  68. package/dist/truncation.js +13 -0
  69. package/dist/truncation.js.map +1 -0
  70. package/dist/usage.d.ts +90 -0
  71. package/dist/usage.d.ts.map +1 -0
  72. package/dist/usage.js +169 -0
  73. package/dist/usage.js.map +1 -0
  74. package/package.json +61 -0
package/dist/oauth.js ADDED
@@ -0,0 +1,226 @@
1
+ // Feature 3: OAuth — Kiro Authentication
2
+ //
3
+ // Supports multiple auth methods:
4
+ // - "idc": AWS Builder ID or IAM Identity Center (SSO) via device code flow
5
+ // - "desktop": Google/GitHub social login via Kiro auth service (delegates to kiro-cli)
6
+ //
7
+ // When no existing credentials are found (no Kiro IDE, no kiro-cli), falls back
8
+ // to the interactive login flow in login.ts (Feature 10).
9
+ import { getKiroIdeCredentials, getKiroIdeCredentialsAllowExpired, } from "./kiro-ide.js";
10
+ import { interactiveLogin, loginViaKiroCli } from "./login.js";
11
+ export const SSO_OIDC_ENDPOINT = "https://oidc.us-east-1.amazonaws.com";
12
+ export const BUILDER_ID_START_URL = "https://view.awsapps.com/start";
13
+ export const KIRO_DESKTOP_REFRESH_URL = "https://prod.{region}.auth.desktop.kiro.dev/refreshToken";
14
+ export const SSO_SCOPES = [
15
+ "codewhisperer:completions",
16
+ "codewhisperer:analysis",
17
+ "codewhisperer:conversations",
18
+ "codewhisperer:transformations",
19
+ "codewhisperer:taskassist",
20
+ ];
21
+ /**
22
+ * Login to Kiro using the specified method.
23
+ *
24
+ * - "auto": Use existing kiro-cli credentials if available (any method)
25
+ * - "builder-id": AWS Builder ID via device code flow
26
+ * - "google" | "github": Social login via kiro-cli (requires kiro-cli installed)
27
+ */
28
+ export async function loginKiro(callbacks, preferredMethod = "auto") {
29
+ const creds = await loginKiroInternal(callbacks, preferredMethod);
30
+ if (!process.env.VITEST) {
31
+ try {
32
+ const { resolveApiRegion, updateKiroModelsCache } = await import("./models.js");
33
+ const region = resolveApiRegion(creds.region);
34
+ updateKiroModelsCache(creds.access, region, creds.profileArn).catch(() => { });
35
+ }
36
+ catch {
37
+ // Ignore cache errors
38
+ }
39
+ }
40
+ return creds;
41
+ }
42
+ async function loginKiroInternal(callbacks, preferredMethod = "auto") {
43
+ const { getKiroCliCredentials, getKiroCliCredentialsAllowExpired, saveKiroCliCredentials, getKiroCliSocialToken, } = await import("./kiro-cli.js");
44
+ // If user explicitly wants social login, delegate to kiro-cli
45
+ if (preferredMethod === "google" || preferredMethod === "github") {
46
+ return loginViaKiroCli(callbacks, preferredMethod);
47
+ }
48
+ // 1. Kiro IDE token (~/.aws/sso/cache/kiro-auth-token.json)
49
+ // Checked first because the IDE keeps it continuously fresh and it already
50
+ // covers IAM Identity Center logins — no extra prompts needed.
51
+ const ideCreds = getKiroIdeCredentials();
52
+ if (ideCreds &&
53
+ (preferredMethod === "auto" || preferredMethod === "builder-id")) {
54
+ callbacks.onProgress?.("Using existing Kiro IDE credentials");
55
+ return ideCreds;
56
+ }
57
+ // 2. kiro-cli DB credentials (social / Builder ID / IdC)
58
+ let cliCreds = getKiroCliSocialToken();
59
+ if (!cliCreds) {
60
+ cliCreds = getKiroCliCredentials();
61
+ }
62
+ if (cliCreds &&
63
+ (preferredMethod === "auto" || cliCreds.authMethod === "idc")) {
64
+ callbacks.onProgress?.(cliCreds.authMethod === "desktop"
65
+ ? "Using existing kiro-cli social credentials"
66
+ : "Using existing kiro-cli credentials");
67
+ return cliCreds;
68
+ }
69
+ // 3. Expired IDE token — attempt a silent AWS OIDC refresh
70
+ const expiredIdeCreds = getKiroIdeCredentialsAllowExpired();
71
+ if (expiredIdeCreds) {
72
+ try {
73
+ callbacks.onProgress?.("Refreshing Kiro IDE credentials...");
74
+ return await refreshKiroTokenDirect(expiredIdeCreds);
75
+ }
76
+ catch {
77
+ // Fall through to kiro-cli refresh
78
+ }
79
+ }
80
+ // 4. Expired kiro-cli credentials — attempt a silent refresh
81
+ const expiredCreds = getKiroCliCredentialsAllowExpired();
82
+ if (expiredCreds) {
83
+ try {
84
+ callbacks.onProgress?.("Refreshing expired kiro-cli credentials...");
85
+ const refreshed = await refreshKiroTokenDirect(expiredCreds);
86
+ saveKiroCliCredentials(refreshed);
87
+ return refreshed;
88
+ }
89
+ catch {
90
+ // Refresh failed, fall through to device code flow
91
+ }
92
+ }
93
+ // Fall back to interactive login (Feature 10)
94
+ return interactiveLogin(callbacks);
95
+ }
96
+ /**
97
+ * Backward-compatible alias for loginKiro with Builder ID.
98
+ * @deprecated Use loginKiro instead.
99
+ */
100
+ export async function loginKiroBuilderID(callbacks) {
101
+ return loginKiro(callbacks, "builder-id");
102
+ }
103
+ // Token refresh buffer (5 minutes) baked into our expires timestamps at creation time.
104
+ // The actual AWS token is valid for this much longer than credentials.expires indicates.
105
+ const EXPIRES_BUFFER_MS = 5 * 60 * 1000;
106
+ export async function refreshKiroToken(credentials) {
107
+ const refreshed = await refreshKiroTokenInternal(credentials);
108
+ if (!process.env.VITEST) {
109
+ try {
110
+ const { resolveApiRegion, updateKiroModelsCache } = await import("./models.js");
111
+ const region = resolveApiRegion(refreshed.region);
112
+ updateKiroModelsCache(refreshed.access, region, refreshed.profileArn).catch(() => { });
113
+ }
114
+ catch {
115
+ // Ignore cache errors
116
+ }
117
+ }
118
+ return refreshed;
119
+ }
120
+ async function refreshKiroTokenInternal(credentials) {
121
+ const { getKiroCliCredentials, getKiroCliCredentialsAllowExpired, saveKiroCliCredentials, getKiroCliSocialToken, } = await import("./kiro-cli.js");
122
+ // Layer 0: Kiro IDE token — freshest source, covers IAM Identity Center
123
+ const ideCreds = getKiroIdeCredentials();
124
+ if (ideCreds)
125
+ return ideCreds;
126
+ // Layer 1: Pre-refresh check — prefer social token if available (user logged in that way)
127
+ // Otherwise check for any valid kiro-cli token
128
+ let preCheckCreds = getKiroCliSocialToken();
129
+ if (!preCheckCreds) {
130
+ preCheckCreds = getKiroCliCredentials();
131
+ }
132
+ if (preCheckCreds) {
133
+ return preCheckCreds;
134
+ }
135
+ try {
136
+ const refreshed = await refreshKiroTokenDirect(credentials);
137
+ // Layer 2: Write refreshed tokens back to kiro-cli's SQLite DB so both stay in sync.
138
+ saveKiroCliCredentials(refreshed);
139
+ return refreshed;
140
+ }
141
+ catch (refreshError) {
142
+ // Layer 3: Refresh token may have been rotated by kiro-cli between our
143
+ // Layer 1 check and the network call. Re-read kiro-cli's DB.
144
+ const retryCreds = getKiroCliCredentials();
145
+ if (retryCreds) {
146
+ return retryCreds;
147
+ }
148
+ // Layer 4: kiro-cli may have a newer refresh token (expired access token).
149
+ // Try refreshing with those credentials instead of the stale ones from auth.json.
150
+ const expiredCliCreds = getKiroCliCredentialsAllowExpired();
151
+ if (expiredCliCreds && expiredCliCreds.refresh !== credentials.refresh) {
152
+ try {
153
+ const refreshedFromCli = await refreshKiroTokenDirect(expiredCliCreds);
154
+ saveKiroCliCredentials(refreshedFromCli);
155
+ return refreshedFromCli;
156
+ }
157
+ catch {
158
+ // Also failed, continue to remaining fallbacks
159
+ }
160
+ }
161
+ // Layer 5: Graceful degradation — our expires has a 5-min buffer, so the
162
+ // actual AWS token may still be valid. Return it to buy time.
163
+ const actualExpiry = credentials.expires + EXPIRES_BUFFER_MS;
164
+ if (credentials.access && Date.now() < actualExpiry) {
165
+ return { ...credentials, expires: actualExpiry };
166
+ }
167
+ throw refreshError;
168
+ }
169
+ }
170
+ async function refreshKiroTokenDirect(credentials) {
171
+ const parts = credentials.refresh.split("|");
172
+ const refreshToken = parts[0] ?? "";
173
+ const authMethod = (parts[parts.length - 1] ?? "idc");
174
+ const region = credentials.region || "us-east-1";
175
+ if (authMethod === "desktop") {
176
+ // Kiro desktop app tokens use a different refresh endpoint
177
+ const url = KIRO_DESKTOP_REFRESH_URL.replace("{region}", region);
178
+ const response = await fetch(url, {
179
+ method: "POST",
180
+ headers: { "Content-Type": "application/json", "User-Agent": "pi-cli" },
181
+ body: JSON.stringify({ refreshToken }),
182
+ });
183
+ if (!response.ok)
184
+ throw new Error(`Desktop token refresh failed: ${response.status}`);
185
+ const data = (await response.json());
186
+ if (!data.accessToken)
187
+ throw new Error("Desktop token refresh: missing accessToken");
188
+ return {
189
+ refresh: `${data.refreshToken || refreshToken}|desktop`,
190
+ access: data.accessToken,
191
+ expires: Date.now() + data.expiresIn * 1000 - 5 * 60 * 1000,
192
+ clientId: "",
193
+ clientSecret: "",
194
+ region,
195
+ authMethod: "desktop",
196
+ profileArn: data.profileArn || credentials.profileArn,
197
+ };
198
+ }
199
+ // IDC auth method — SSO OIDC refresh
200
+ const clientId = parts[1] ?? "";
201
+ const clientSecret = parts[2] ?? "";
202
+ const ssoEndpoint = `https://oidc.${region}.amazonaws.com`;
203
+ const response = await fetch(`${ssoEndpoint}/token`, {
204
+ method: "POST",
205
+ headers: { "Content-Type": "application/json", "User-Agent": "pi-cli" },
206
+ body: JSON.stringify({
207
+ clientId,
208
+ clientSecret,
209
+ refreshToken,
210
+ grantType: "refresh_token",
211
+ }),
212
+ });
213
+ if (!response.ok)
214
+ throw new Error(`Token refresh failed: ${response.status}`);
215
+ const data = (await response.json());
216
+ return {
217
+ refresh: `${data.refreshToken}|${clientId}|${clientSecret}|idc`,
218
+ access: data.accessToken,
219
+ expires: Date.now() + data.expiresIn * 1000 - 5 * 60 * 1000,
220
+ clientId: clientId,
221
+ clientSecret: clientSecret,
222
+ region,
223
+ authMethod: "idc",
224
+ };
225
+ }
226
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export declare const FIRST_TOKEN_TIMEOUT = 90000;
2
+ export declare function firstTokenTimeoutForModel(modelId: string): number;
3
+ export declare const retryConfig: {
4
+ firstTokenTimeoutMs: number;
5
+ };
6
+ export declare function exponentialBackoff(attempt: number, baseMs: number, maxMs: number): number;
7
+ export declare const MAX_RETRY_DELAY = 10000;
8
+ export declare const TOO_BIG_PATTERNS: string[];
9
+ export declare const CAPACITY_MAX_RETRIES = 3;
10
+ export declare const CAPACITY_BASE_DELAY_MS = 5000;
11
+ export declare const capacityRetryConfig: {
12
+ maxRetries: number;
13
+ baseDelayMs: number;
14
+ };
15
+ /** Check whether an HTTP error represents a "request too large" condition. */
16
+ export declare function isTooBigError(status: number, errorText: string): boolean;
17
+ /** Check whether the response body contains a Kiro-specific non-retryable marker. */
18
+ export declare function isNonRetryableBodyError(errorText: string): boolean;
19
+ /** Check whether the error is a transient capacity issue worth retrying. */
20
+ export declare function isCapacityError(errorText: string): boolean;
21
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAE1C,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOjE;AAGD,eAAO,MAAM,WAAW;;CAEvB,CAAC;AAEF,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACX,MAAM,CAER;AAED,eAAO,MAAM,eAAe,QAAS,CAAC;AAEtC,eAAO,MAAM,gBAAgB,UAI5B,CAAC;AAGF,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,eAAO,MAAM,sBAAsB,OAAQ,CAAC;AAG5C,eAAO,MAAM,mBAAmB;;;CAG/B,CAAC;AAEF,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAKxE;AAED,qFAAqF;AACrF,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAElE;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE1D"}
package/dist/retry.js ADDED
@@ -0,0 +1,51 @@
1
+ // ABOUTME: Stream recovery helpers and Kiro-specific error classification.
2
+ // ABOUTME: Keeps provider-local retry logic limited to auth refresh and stream quirks.
3
+ import { kiroModels } from "./models.js";
4
+ // kiro-cli uses 5-minute read/operation timeouts (DEFAULT_TIMEOUT_DURATION)
5
+ // and 5-minute stalled stream grace period. 90s matches the TUI's
6
+ // INITIAL_RESPONSE_TIMEOUT_MS for the first event from the backend.
7
+ export const FIRST_TOKEN_TIMEOUT = 90_000;
8
+ export function firstTokenTimeoutForModel(modelId) {
9
+ // Allow test overrides via retryConfig.firstTokenTimeoutMs
10
+ if (retryConfig.firstTokenTimeoutMs !== FIRST_TOKEN_TIMEOUT) {
11
+ return retryConfig.firstTokenTimeoutMs;
12
+ }
13
+ const model = kiroModels.find((m) => m.id === modelId);
14
+ return model?.firstTokenTimeout ?? FIRST_TOKEN_TIMEOUT;
15
+ }
16
+ // Mutable config for values that tests need to override
17
+ export const retryConfig = {
18
+ firstTokenTimeoutMs: FIRST_TOKEN_TIMEOUT,
19
+ };
20
+ export function exponentialBackoff(attempt, baseMs, maxMs) {
21
+ return Math.min(baseMs * 2 ** attempt, maxMs);
22
+ }
23
+ export const MAX_RETRY_DELAY = 10_000;
24
+ export const TOO_BIG_PATTERNS = [
25
+ "CONTENT_LENGTH_EXCEEDS_THRESHOLD",
26
+ "Input is too long",
27
+ "Improperly formed",
28
+ ];
29
+ const NON_RETRYABLE_BODY_PATTERNS = ["MONTHLY_REQUEST_COUNT"];
30
+ const CAPACITY_PATTERN = "INSUFFICIENT_MODEL_CAPACITY";
31
+ export const CAPACITY_MAX_RETRIES = 3;
32
+ export const CAPACITY_BASE_DELAY_MS = 5_000;
33
+ // Mutable capacity config for testing
34
+ export const capacityRetryConfig = {
35
+ maxRetries: CAPACITY_MAX_RETRIES,
36
+ baseDelayMs: CAPACITY_BASE_DELAY_MS,
37
+ };
38
+ /** Check whether an HTTP error represents a "request too large" condition. */
39
+ export function isTooBigError(status, errorText) {
40
+ return (status === 413 ||
41
+ (status === 400 && TOO_BIG_PATTERNS.some((p) => errorText.includes(p))));
42
+ }
43
+ /** Check whether the response body contains a Kiro-specific non-retryable marker. */
44
+ export function isNonRetryableBodyError(errorText) {
45
+ return NON_RETRYABLE_BODY_PATTERNS.some((p) => errorText.includes(p));
46
+ }
47
+ /** Check whether the error is a transient capacity issue worth retrying. */
48
+ export function isCapacityError(errorText) {
49
+ return errorText.includes(CAPACITY_PATTERN);
50
+ }
51
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,uFAAuF;AAEvF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,4EAA4E;AAC5E,kEAAkE;AAClE,oEAAoE;AACpE,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAE1C,MAAM,UAAU,yBAAyB,CAAC,OAAe;IACxD,2DAA2D;IAC3D,IAAI,WAAW,CAAC,mBAAmB,KAAK,mBAAmB,EAAE,CAAC;QAC7D,OAAO,WAAW,CAAC,mBAAmB,CAAC;IACxC,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IACvD,OAAO,KAAK,EAAE,iBAAiB,IAAI,mBAAmB,CAAC;AACxD,CAAC;AAED,wDAAwD;AACxD,MAAM,CAAC,MAAM,WAAW,GAAG;IAC1B,mBAAmB,EAAE,mBAAmB;CACxC,CAAC;AAEF,MAAM,UAAU,kBAAkB,CACjC,OAAe,EACf,MAAc,EACd,KAAa;IAEb,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,EAAE,KAAK,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC;AAEtC,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC/B,kCAAkC;IAClC,mBAAmB;IACnB,mBAAmB;CACnB,CAAC;AACF,MAAM,2BAA2B,GAAG,CAAC,uBAAuB,CAAC,CAAC;AAC9D,MAAM,gBAAgB,GAAG,6BAA6B,CAAC;AACvD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AACtC,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAC;AAE5C,sCAAsC;AACtC,MAAM,CAAC,MAAM,mBAAmB,GAAG;IAClC,UAAU,EAAE,oBAAoB;IAChC,WAAW,EAAE,sBAAsB;CACnC,CAAC;AAEF,8EAA8E;AAC9E,MAAM,UAAU,aAAa,CAAC,MAAc,EAAE,SAAiB;IAC9D,OAAO,CACN,MAAM,KAAK,GAAG;QACd,CAAC,MAAM,KAAK,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CACvE,CAAC;AACH,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,uBAAuB,CAAC,SAAiB;IACxD,OAAO,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,eAAe,CAAC,SAAiB;IAChD,OAAO,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Api, AssistantMessageEventStream, Context, Model, SimpleStreamOptions } from "@earendil-works/pi-ai";
2
+ /** Reset profileArn cache — exported for tests. */
3
+ export declare function resetProfileArnCache(resolved?: boolean): void;
4
+ export declare function streamKiro(model: Model<Api>, context: Context, options?: SimpleStreamOptions): AssistantMessageEventStream;
5
+ //# sourceMappingURL=stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACX,GAAG,EAEH,2BAA2B,EAC3B,OAAO,EAEP,KAAK,EACL,mBAAmB,EAInB,MAAM,uBAAuB,CAAC;AAoH/B,mDAAmD;AACnD,wBAAgB,oBAAoB,CAAC,QAAQ,UAAQ,GAAG,IAAI,CAI3D;AA+FD,wBAAgB,UAAU,CACzB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,mBAAmB,GAC3B,2BAA2B,CAmyB7B"}