@takara-ai/miru-code 1.5.2 → 1.5.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.
- package/package.json +1 -1
- package/src/credentials.ts +43 -37
- package/src/embeddings/validate.ts +2 -2
- package/src/setup.ts +6 -6
package/package.json
CHANGED
package/src/credentials.ts
CHANGED
|
@@ -61,13 +61,6 @@ export async function readStoredCredentials(): Promise<StoredCredentials | null>
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
function hydrateSageMakerEnv(sagemaker: StoredSageMakerCredentials): void {
|
|
65
|
-
process.env.MIRU_SAGEMAKER_ENDPOINT_ARN = sagemaker.endpoint_arn;
|
|
66
|
-
if (sagemaker.profile && !process.env.AWS_PROFILE) {
|
|
67
|
-
process.env.AWS_PROFILE = sagemaker.profile;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
64
|
function clearSageMakerEnv(sagemaker?: StoredSageMakerCredentials): void {
|
|
72
65
|
delete process.env.MIRU_SAGEMAKER_ENDPOINT_ARN;
|
|
73
66
|
delete process.env.MIRU_SAGEMAKER_ENDPOINT_NAME;
|
|
@@ -81,6 +74,36 @@ function clearTakaraEnv(): void {
|
|
|
81
74
|
delete process.env.TAKARA_API_KEY;
|
|
82
75
|
}
|
|
83
76
|
|
|
77
|
+
function hydrateSageMakerEnv(sagemaker: StoredSageMakerCredentials): void {
|
|
78
|
+
process.env.MIRU_SAGEMAKER_ENDPOINT_ARN = sagemaker.endpoint_arn;
|
|
79
|
+
if (sagemaker.profile && !process.env.AWS_PROFILE) {
|
|
80
|
+
process.env.AWS_PROFILE = sagemaker.profile;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Drop the other backend from env so setup validation cannot see a stale mode. */
|
|
85
|
+
export async function beginModeSwitch(to: "takara" | "sagemaker"): Promise<void> {
|
|
86
|
+
const stored = await readStoredCredentials();
|
|
87
|
+
if (to === "takara") {
|
|
88
|
+
clearSageMakerEnv(stored?.sagemaker);
|
|
89
|
+
} else {
|
|
90
|
+
clearTakaraEnv();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function writeExclusive(payload: StoredCredentials): Promise<string> {
|
|
95
|
+
const dir = resolveCredentialsDir();
|
|
96
|
+
const path = resolveCredentialsPath();
|
|
97
|
+
await mkdir(dir, { recursive: true, mode: 0o700 });
|
|
98
|
+
await Bun.write(path, `${JSON.stringify(payload, null, 2)}\n`, { mode: 0o600 });
|
|
99
|
+
try {
|
|
100
|
+
await chmod(path, 0o600);
|
|
101
|
+
} catch {
|
|
102
|
+
// Windows may not support Unix mode bits on all filesystems.
|
|
103
|
+
}
|
|
104
|
+
return path;
|
|
105
|
+
}
|
|
106
|
+
|
|
84
107
|
/** Apply credentials.json as the sole mode — never leave Takara and SageMaker both active. */
|
|
85
108
|
export async function loadStoredCredentials(): Promise<boolean> {
|
|
86
109
|
normalizeTakaraApiKeyEnv();
|
|
@@ -89,8 +112,8 @@ export async function loadStoredCredentials(): Promise<boolean> {
|
|
|
89
112
|
return false;
|
|
90
113
|
}
|
|
91
114
|
|
|
92
|
-
let changed = false;
|
|
93
115
|
if (stored.takara_api_key) {
|
|
116
|
+
let changed = false;
|
|
94
117
|
if (!hasTakaraApiKeyInEnv()) {
|
|
95
118
|
process.env.TAKARA_API_KEY = stored.takara_api_key;
|
|
96
119
|
changed = true;
|
|
@@ -103,6 +126,7 @@ export async function loadStoredCredentials(): Promise<boolean> {
|
|
|
103
126
|
}
|
|
104
127
|
|
|
105
128
|
if (stored.sagemaker) {
|
|
129
|
+
let changed = false;
|
|
106
130
|
if (!process.env.MIRU_SAGEMAKER_ENDPOINT_ARN?.trim()) {
|
|
107
131
|
hydrateSageMakerEnv(stored.sagemaker);
|
|
108
132
|
changed = true;
|
|
@@ -111,46 +135,28 @@ export async function loadStoredCredentials(): Promise<boolean> {
|
|
|
111
135
|
clearTakaraEnv();
|
|
112
136
|
changed = true;
|
|
113
137
|
}
|
|
138
|
+
return changed;
|
|
114
139
|
}
|
|
115
|
-
return
|
|
140
|
+
return false;
|
|
116
141
|
}
|
|
117
142
|
|
|
118
143
|
export async function saveStoredCredentials(apiKey: string): Promise<string> {
|
|
119
|
-
const
|
|
120
|
-
const path =
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const payload: StoredCredentials = {
|
|
124
|
-
version: CREDENTIALS_VERSION,
|
|
125
|
-
takara_api_key: apiKey,
|
|
126
|
-
};
|
|
127
|
-
await Bun.write(path, `${JSON.stringify(payload, null, 2)}\n`, { mode: 0o600 });
|
|
128
|
-
try {
|
|
129
|
-
await chmod(path, 0o600);
|
|
130
|
-
} catch {
|
|
131
|
-
// Windows may not support Unix mode bits on all filesystems.
|
|
132
|
-
}
|
|
133
|
-
clearSageMakerEnv(previousSageMaker);
|
|
144
|
+
const previous = await readStoredCredentials();
|
|
145
|
+
const path = await writeExclusive({ version: CREDENTIALS_VERSION, takara_api_key: apiKey });
|
|
146
|
+
process.env.TAKARA_API_KEY = apiKey;
|
|
147
|
+
clearSageMakerEnv(previous?.sagemaker);
|
|
134
148
|
return path;
|
|
135
149
|
}
|
|
136
150
|
|
|
137
151
|
export async function saveStoredSageMakerCredentials(
|
|
138
152
|
sagemaker: StoredSageMakerCredentials,
|
|
139
153
|
): Promise<string> {
|
|
140
|
-
const
|
|
141
|
-
const path = resolveCredentialsPath();
|
|
142
|
-
await mkdir(dir, { recursive: true, mode: 0o700 });
|
|
143
|
-
const payload: StoredCredentials = {
|
|
144
|
-
version: CREDENTIALS_VERSION,
|
|
145
|
-
sagemaker,
|
|
146
|
-
};
|
|
147
|
-
await Bun.write(path, `${JSON.stringify(payload, null, 2)}\n`, { mode: 0o600 });
|
|
148
|
-
try {
|
|
149
|
-
await chmod(path, 0o600);
|
|
150
|
-
} catch {
|
|
151
|
-
// Windows may not support Unix mode bits on all filesystems.
|
|
152
|
-
}
|
|
154
|
+
const path = await writeExclusive({ version: CREDENTIALS_VERSION, sagemaker });
|
|
153
155
|
clearTakaraEnv();
|
|
156
|
+
process.env.MIRU_SAGEMAKER_ENDPOINT_ARN = sagemaker.endpoint_arn;
|
|
157
|
+
if (sagemaker.profile) {
|
|
158
|
+
process.env.AWS_PROFILE = sagemaker.profile;
|
|
159
|
+
}
|
|
154
160
|
return path;
|
|
155
161
|
}
|
|
156
162
|
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
embeddingDimensions,
|
|
4
4
|
resolveEmbeddingBaseUrl,
|
|
5
5
|
resolveEmbeddingDimensions,
|
|
6
|
-
|
|
6
|
+
resolveTakaraEmbeddingModel,
|
|
7
7
|
} from "./openai.ts";
|
|
8
8
|
|
|
9
9
|
export interface ValidateApiKeyResult {
|
|
@@ -19,7 +19,7 @@ export async function validateEmbeddingApiKey(options: {
|
|
|
19
19
|
dimensions?: number;
|
|
20
20
|
}): Promise<ValidateApiKeyResult> {
|
|
21
21
|
const baseUrl = (options.baseUrl ?? resolveEmbeddingBaseUrl()).replace(/\/$/, "");
|
|
22
|
-
const model = options.model ??
|
|
22
|
+
const model = options.model ?? resolveTakaraEmbeddingModel();
|
|
23
23
|
const dimensions = options.dimensions ?? resolveEmbeddingDimensions(model);
|
|
24
24
|
const endpoint = `${baseUrl}/embeddings`;
|
|
25
25
|
|
package/src/setup.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { divider, fail, hint, info, printBrandBanner, success, writeStdout } from "./cli-ui.ts";
|
|
2
2
|
import {
|
|
3
|
+
beginModeSwitch,
|
|
3
4
|
clearStoredCredentials,
|
|
4
5
|
loadStoredCredentials,
|
|
5
6
|
readStoredCredentials,
|
|
@@ -163,6 +164,7 @@ export async function runSageMakerSetup(options: RunSetupOptions = {}): Promise<
|
|
|
163
164
|
profile = await promptAwsProfile();
|
|
164
165
|
}
|
|
165
166
|
|
|
167
|
+
await beginModeSwitch("sagemaker");
|
|
166
168
|
process.env.MIRU_SAGEMAKER_ENDPOINT_ARN = arnInput;
|
|
167
169
|
process.env.AWS_PROFILE = profile;
|
|
168
170
|
|
|
@@ -207,14 +209,12 @@ export async function runSetup(options: RunSetupOptions = {}): Promise<RunSetupR
|
|
|
207
209
|
const path = resolveCredentialsPath();
|
|
208
210
|
const stored = await readStoredCredentials();
|
|
209
211
|
if (stored?.sagemaker) {
|
|
210
|
-
const
|
|
211
|
-
await saveStoredCredentials(apiKey);
|
|
212
|
-
process.env.TAKARA_API_KEY = apiKey;
|
|
212
|
+
const saved = await saveStoredCredentials(resolveEmbeddingApiKey());
|
|
213
213
|
writeStdout("");
|
|
214
|
-
success(`Saved credentials to ${
|
|
214
|
+
success(`Saved credentials to ${saved}`);
|
|
215
215
|
hint("Removed the stored SageMaker endpoint — Miru now embeds only via Takara.");
|
|
216
216
|
writeStdout("");
|
|
217
|
-
return { path, newlySaved: true };
|
|
217
|
+
return { path: saved, newlySaved: true };
|
|
218
218
|
}
|
|
219
219
|
if (stored?.takara_api_key) {
|
|
220
220
|
info(`API key already configured (env + ${path}). Use --force to replace stored key.`);
|
|
@@ -246,6 +246,7 @@ export async function runSetup(options: RunSetupOptions = {}): Promise<RunSetupR
|
|
|
246
246
|
|
|
247
247
|
const apiKey = options.apiKey ?? (await promptApiKey());
|
|
248
248
|
|
|
249
|
+
await beginModeSwitch("takara");
|
|
249
250
|
if (!options.skipValidation) {
|
|
250
251
|
const spinner = new Spinner("Validating API key");
|
|
251
252
|
spinner.start();
|
|
@@ -259,7 +260,6 @@ export async function runSetup(options: RunSetupOptions = {}): Promise<RunSetupR
|
|
|
259
260
|
|
|
260
261
|
const hadSageMaker = Boolean((await readStoredCredentials())?.sagemaker);
|
|
261
262
|
const path = await saveStoredCredentials(apiKey);
|
|
262
|
-
process.env.TAKARA_API_KEY = apiKey;
|
|
263
263
|
writeStdout("");
|
|
264
264
|
success(`Saved credentials to ${path}`);
|
|
265
265
|
if (hadSageMaker) {
|