@nodeint/migent 0.1.5 → 0.1.7
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/README.md +195 -151
- package/dist/commands/agent.d.ts +8 -1
- package/dist/commands/agent.js +292 -19
- package/dist/commands/config.d.ts +3 -3
- package/dist/commands/config.js +57 -55
- package/dist/commands/doctor.js +2 -2
- package/dist/commands/execute.d.ts +1 -2
- package/dist/commands/execute.js +95 -26
- package/dist/commands/init.d.ts +3 -3
- package/dist/commands/init.js +20 -20
- package/dist/commands/prepare.js +1 -0
- package/dist/commands/provider.d.ts +10 -0
- package/dist/commands/provider.js +77 -0
- package/dist/commands/sessions.js +11 -10
- package/dist/commands/skill.js +8 -1
- package/dist/display.d.ts +17 -0
- package/dist/display.js +43 -1
- package/dist/exits.d.ts +3 -1
- package/dist/exits.js +9 -2
- package/dist/hooks.d.ts +2 -0
- package/dist/hooks.js +1 -0
- package/dist/index.js +1 -0
- package/dist/migrate.d.ts +3 -3
- package/dist/migrate.js +26 -24
- package/dist/program.js +78 -31
- package/dist/provider.d.ts +13 -11
- package/dist/provider.js +38 -33
- package/dist/session-row.d.ts +2 -0
- package/dist/session-row.js +2 -0
- package/dist/templates/migent/SKILL.md +159 -157
- package/dist/templates/migent/references/config.md +56 -0
- package/dist/templates/migent/references/inspect.md +32 -0
- package/dist/templates/migent/references/schema-config.yaml +10 -1
- package/dist/templates/migent/references/schema-workflow.yaml +12 -2
- package/dist/templates/migent/references/sessions.md +65 -0
- package/package.json +4 -4
package/dist/commands/agent.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
1
2
|
import path from "node:path";
|
|
2
|
-
import { AgentToolRunner, CancellationRequested, ConfigurationError, createAgentSession, loadRoleInstructions, loadYamlMapping, log, prependRoleInstructions, requireAgentSession, isSessionLockLost, repairSessionUnlocked, SessionLock, resolveRoleTarget,
|
|
3
|
-
import { printAgent, printError, printNotice } from "../display.js";
|
|
3
|
+
import { AgentToolRunner, CancellationRequested, ConfigurationError, ProviderEventReporter, SessionStore, createAgentSession, loadRoleInstructions, loadYamlMapping, log, prependRoleInstructions, requireAgentSession, isSessionLockLost, repairSessionUnlocked, SessionLock, stringOptions, resolveRoleTarget, waitUntil, } from "@nodeint/migent-kernel";
|
|
4
|
+
import { printAgent, printError, printNotice, printResumeCommand } from "../display.js";
|
|
4
5
|
import { cliHooks } from "../hooks.js";
|
|
5
6
|
import { requireCurrentSchema } from "../migrate.js";
|
|
6
7
|
import { bindCancellationSignals } from "../signals.js";
|
|
7
|
-
import {
|
|
8
|
+
import { providerMap, parseOptions } from "../provider.js";
|
|
8
9
|
import { resolvePrompt } from "../workspace.js";
|
|
9
10
|
export async function dispatchAgent(workspace, args) {
|
|
10
11
|
requireCurrentSchema(workspace);
|
|
@@ -64,7 +65,18 @@ export async function dispatchAgent(workspace, args) {
|
|
|
64
65
|
let result;
|
|
65
66
|
let resumedMany = null;
|
|
66
67
|
try {
|
|
67
|
-
const runner = args.runner ?? cliHooks.runner ?? new AgentToolRunner(
|
|
68
|
+
const runner = args.runner ?? cliHooks.runner ?? new AgentToolRunner(providerMap());
|
|
69
|
+
const waitedUntil = new Map();
|
|
70
|
+
const rerun = (prompt, resumeId) => runner.run({
|
|
71
|
+
provider: target.provider,
|
|
72
|
+
model: target.model,
|
|
73
|
+
options: { ...target.options },
|
|
74
|
+
prompt,
|
|
75
|
+
workspace,
|
|
76
|
+
sessionId: resolvedSessionId,
|
|
77
|
+
resumeExecutionId: resumeId,
|
|
78
|
+
stageId: args.role,
|
|
79
|
+
});
|
|
68
80
|
if (resumeCancelled) {
|
|
69
81
|
const reopened = new SessionStore(workspace).reopenCancelledExecutions(resolvedSessionId);
|
|
70
82
|
for (const item of reopened) {
|
|
@@ -78,32 +90,37 @@ export async function dispatchAgent(workspace, args) {
|
|
|
78
90
|
if (continued.length === 0) {
|
|
79
91
|
throw new ConfigurationError(`Session ${resolvedSessionId} is cancelled without an execution.`);
|
|
80
92
|
}
|
|
81
|
-
|
|
82
|
-
|
|
93
|
+
const finished = [];
|
|
94
|
+
for (const item of continued) {
|
|
95
|
+
finished.push(await rerunQuota(workspace, resolvedSessionId, item, (current) => lastUserPrompt(workspace, resolvedSessionId, current.execution_id), rerun, waitedUntil, args.waitHooks));
|
|
96
|
+
}
|
|
97
|
+
if (finished.length === 1)
|
|
98
|
+
result = finished[0];
|
|
83
99
|
else
|
|
84
|
-
resumedMany =
|
|
100
|
+
resumedMany = finished;
|
|
85
101
|
}
|
|
86
102
|
else {
|
|
87
|
-
|
|
103
|
+
const prompt = prependRoleInstructions(loadRoleInstructions(loadYamlMapping(path.join(workspace, ".migent", "config.yaml")), args.role), resolvePrompt({
|
|
104
|
+
prompt: args.prompt ?? null,
|
|
105
|
+
promptFile: args.promptFile ?? null,
|
|
106
|
+
promptStdin: args.promptStdin ?? false,
|
|
107
|
+
}));
|
|
108
|
+
result = await rerunQuota(workspace, resolvedSessionId, await runner.run({
|
|
88
109
|
provider: target.provider,
|
|
89
110
|
model: target.model,
|
|
90
111
|
options: { ...target.options },
|
|
91
|
-
prompt
|
|
92
|
-
prompt: args.prompt ?? null,
|
|
93
|
-
promptFile: args.promptFile ?? null,
|
|
94
|
-
promptStdin: args.promptStdin ?? false,
|
|
95
|
-
})),
|
|
112
|
+
prompt,
|
|
96
113
|
workspace,
|
|
97
114
|
sessionId: resolvedSessionId,
|
|
98
115
|
resumeExecutionId,
|
|
99
116
|
stageId: args.role,
|
|
100
|
-
});
|
|
117
|
+
}), () => prompt, rerun, waitedUntil, args.waitHooks);
|
|
101
118
|
}
|
|
102
119
|
}
|
|
103
120
|
catch (error) {
|
|
104
121
|
if (error instanceof CancellationRequested) {
|
|
105
122
|
log(error.message);
|
|
106
|
-
return 130;
|
|
123
|
+
return finishRole(resolvedSessionId, 130);
|
|
107
124
|
}
|
|
108
125
|
if (error instanceof ConfigurationError)
|
|
109
126
|
throw error;
|
|
@@ -123,9 +140,10 @@ export async function dispatchAgent(workspace, args) {
|
|
|
123
140
|
for (const item of resumedMany)
|
|
124
141
|
printAgent({ ...item }, args.role, target.provider, target.model);
|
|
125
142
|
}
|
|
126
|
-
if (resumedMany.some((item) => item.failure_reason === "verify_exhausted"))
|
|
127
|
-
return 6;
|
|
128
|
-
|
|
143
|
+
if (resumedMany.some((item) => item.failure_reason === "verify_exhausted")) {
|
|
144
|
+
return finishRole(resolvedSessionId, 6);
|
|
145
|
+
}
|
|
146
|
+
return finishRole(resolvedSessionId, resumedMany.every((item) => item.outcome_status === "complete") ? 0 : 1);
|
|
129
147
|
}
|
|
130
148
|
if (result === undefined)
|
|
131
149
|
throw new Error("Agent run produced no result.");
|
|
@@ -133,7 +151,262 @@ export async function dispatchAgent(workspace, args) {
|
|
|
133
151
|
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
134
152
|
else
|
|
135
153
|
printAgent({ ...result }, args.role, target.provider, target.model);
|
|
136
|
-
return result.outcome_status === "complete" ? 0 : 1;
|
|
154
|
+
return finishRole(resolvedSessionId, result.outcome_status === "complete" ? 0 : 1);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
export async function continueAgent(workspace, args) {
|
|
158
|
+
requireCurrentSchema(workspace);
|
|
159
|
+
requireAgentSession(workspace, args.sessionId);
|
|
160
|
+
let lock;
|
|
161
|
+
try {
|
|
162
|
+
lock = SessionLock.acquire(path.join(workspace, ".migent", "sessions", args.sessionId));
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
if (error instanceof Error) {
|
|
166
|
+
printError(error.message);
|
|
167
|
+
return 2;
|
|
168
|
+
}
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
return await continueLocked();
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
if (isSessionLockLost(error)) {
|
|
176
|
+
printError(error.message);
|
|
177
|
+
return 2;
|
|
178
|
+
}
|
|
179
|
+
throw error;
|
|
180
|
+
}
|
|
181
|
+
finally {
|
|
182
|
+
lock.release();
|
|
183
|
+
}
|
|
184
|
+
async function continueLocked() {
|
|
185
|
+
repairSessionUnlocked(workspace, args.sessionId);
|
|
186
|
+
const store = new SessionStore(workspace);
|
|
187
|
+
const status = store.readSessionStatus(args.sessionId);
|
|
188
|
+
const sessionStatus = typeof status.status === "string" ? status.status : "";
|
|
189
|
+
const role = typeof status.role === "string" ? status.role : "";
|
|
190
|
+
if (role === "")
|
|
191
|
+
throw new ConfigurationError(`Session ${args.sessionId} has no role.`);
|
|
192
|
+
if (sessionStatus === "completed" && args.reply === null) {
|
|
193
|
+
printNotice(`Session ${args.sessionId} is completed.`);
|
|
194
|
+
return 0;
|
|
195
|
+
}
|
|
196
|
+
if (sessionStatus === "cancelled" && args.reply !== null) {
|
|
197
|
+
throw new ConfigurationError(`Session ${args.sessionId} was cancelled. session continue resumes that execution. Omit --reply.`);
|
|
198
|
+
}
|
|
199
|
+
const latest = store.latestExecution(args.sessionId);
|
|
200
|
+
if (latest === null)
|
|
201
|
+
throw new ConfigurationError(`Session ${args.sessionId} has no execution.`);
|
|
202
|
+
const profile = executionProfile(latest.directory, latest.executionId);
|
|
203
|
+
const optionLabel = Object.entries(profile.options)
|
|
204
|
+
.map(([key, value]) => `${key}: ${value}`)
|
|
205
|
+
.join(", ") || "default";
|
|
206
|
+
printNotice(`agent ${role} · ${profile.provider}/${profile.model} (${optionLabel}).`);
|
|
207
|
+
const unbind = bindCancellationSignals();
|
|
208
|
+
try {
|
|
209
|
+
const runner = args.runner ?? cliHooks.runner ?? new AgentToolRunner(providerMap());
|
|
210
|
+
if (sessionStatus === "cancelled") {
|
|
211
|
+
return await runCancelledRole(workspace, args.sessionId, role, profile, runner, false, args.waitHooks);
|
|
212
|
+
}
|
|
213
|
+
let prompt;
|
|
214
|
+
if (args.reply !== null) {
|
|
215
|
+
prompt = rolePrompt(workspace, role, args.reply);
|
|
216
|
+
}
|
|
217
|
+
else if (sessionStatus === "blocked") {
|
|
218
|
+
const blocker = executionBlocker(latest.directory);
|
|
219
|
+
const resumed = store.resumeBlockedSession(args.sessionId);
|
|
220
|
+
for (const item of resumed) {
|
|
221
|
+
log(`session ${args.sessionId} was blocked by ${item.executionId}. Resuming ${role}.`);
|
|
222
|
+
}
|
|
223
|
+
const lines = ["Previous attempt:", `- execution: ${latest.executionId}`];
|
|
224
|
+
if (blocker)
|
|
225
|
+
lines.push(`- blocker: ${blocker}`);
|
|
226
|
+
lines.push("That attempt ended blocked. The blocker was handled outside this session. Continue.");
|
|
227
|
+
prompt = rolePrompt(workspace, role, lines.join("\n"));
|
|
228
|
+
}
|
|
229
|
+
else if (sessionStatus === "active") {
|
|
230
|
+
log(`session ${args.sessionId} is active. Resuming ${role} with its last prompt.`);
|
|
231
|
+
prompt = lastUserPrompt(workspace, args.sessionId, latest.executionId);
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
throw new ConfigurationError(`Session ${args.sessionId} is ${sessionStatus || "unknown"}.`);
|
|
235
|
+
}
|
|
236
|
+
const waitedUntil = new Map();
|
|
237
|
+
const rerun = (nextPrompt, resumeId) => runner.run({
|
|
238
|
+
provider: profile.provider,
|
|
239
|
+
model: profile.model,
|
|
240
|
+
options: { ...profile.options },
|
|
241
|
+
prompt: nextPrompt,
|
|
242
|
+
workspace,
|
|
243
|
+
sessionId: args.sessionId,
|
|
244
|
+
resumeExecutionId: resumeId,
|
|
245
|
+
stageId: role,
|
|
246
|
+
});
|
|
247
|
+
const result = await rerunQuota(workspace, args.sessionId, await rerun(prompt, latest.executionId), () => prompt, rerun, waitedUntil, args.waitHooks);
|
|
248
|
+
printAgent({ ...result }, role, profile.provider, profile.model);
|
|
249
|
+
return finishRole(args.sessionId, result.outcome_status === "complete" ? 0 : 1);
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
if (error instanceof CancellationRequested) {
|
|
253
|
+
log(error.message);
|
|
254
|
+
return finishRole(args.sessionId, 130);
|
|
255
|
+
}
|
|
256
|
+
if (error instanceof ConfigurationError)
|
|
257
|
+
throw error;
|
|
258
|
+
if (error instanceof Error) {
|
|
259
|
+
printError(error.message);
|
|
260
|
+
return 2;
|
|
261
|
+
}
|
|
262
|
+
throw error;
|
|
263
|
+
}
|
|
264
|
+
finally {
|
|
265
|
+
unbind();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
async function runCancelledRole(workspace, sessionId, role, profile, runner, asJson, waitHooks) {
|
|
270
|
+
const reopened = new SessionStore(workspace).reopenCancelledExecutions(sessionId);
|
|
271
|
+
for (const item of reopened) {
|
|
272
|
+
log(`session ${sessionId} was cancelled during ${item.executionId}. Resuming that execution.`);
|
|
273
|
+
}
|
|
274
|
+
const waitedUntil = new Map();
|
|
275
|
+
const rerun = (prompt, resumeId) => runner.run({
|
|
276
|
+
provider: profile.provider,
|
|
277
|
+
model: profile.model,
|
|
278
|
+
options: { ...profile.options },
|
|
279
|
+
prompt,
|
|
280
|
+
workspace,
|
|
281
|
+
sessionId,
|
|
282
|
+
resumeExecutionId: resumeId,
|
|
283
|
+
stageId: role,
|
|
284
|
+
});
|
|
285
|
+
const settled = await Promise.allSettled(reopened.map((item) => runner.continueCancelled(workspace, sessionId, item.executionId)));
|
|
286
|
+
const rejected = settled.find((item) => item.status === "rejected");
|
|
287
|
+
if (rejected && rejected.status === "rejected")
|
|
288
|
+
throw rejected.reason;
|
|
289
|
+
const continued = settled.flatMap((item) => (item.status === "fulfilled" ? [item.value] : []));
|
|
290
|
+
if (continued.length === 0) {
|
|
291
|
+
throw new ConfigurationError(`Session ${sessionId} is cancelled without an execution.`);
|
|
292
|
+
}
|
|
293
|
+
const finished = [];
|
|
294
|
+
for (const item of continued) {
|
|
295
|
+
finished.push(await rerunQuota(workspace, sessionId, item, (current) => lastUserPrompt(workspace, sessionId, current.execution_id), rerun, waitedUntil, waitHooks));
|
|
296
|
+
}
|
|
297
|
+
if (finished.length === 1) {
|
|
298
|
+
const result = finished[0];
|
|
299
|
+
if (result === undefined)
|
|
300
|
+
throw new Error("Agent run produced no result.");
|
|
301
|
+
if (asJson)
|
|
302
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
303
|
+
else
|
|
304
|
+
printAgent({ ...result }, role, profile.provider, profile.model);
|
|
305
|
+
return finishRole(sessionId, result.outcome_status === "complete" ? 0 : 1);
|
|
306
|
+
}
|
|
307
|
+
if (asJson)
|
|
308
|
+
process.stdout.write(`${JSON.stringify(finished)}\n`);
|
|
309
|
+
else {
|
|
310
|
+
for (const item of finished)
|
|
311
|
+
printAgent({ ...item }, role, profile.provider, profile.model);
|
|
312
|
+
}
|
|
313
|
+
if (finished.some((item) => item.failure_reason === "verify_exhausted"))
|
|
314
|
+
return finishRole(sessionId, 6);
|
|
315
|
+
return finishRole(sessionId, finished.every((item) => item.outcome_status === "complete") ? 0 : 1);
|
|
316
|
+
}
|
|
317
|
+
async function rerunQuota(workspace, sessionId, initial, promptFor, run, waitedUntil, hooks) {
|
|
318
|
+
let current = initial;
|
|
319
|
+
let armed = null;
|
|
320
|
+
while (current.failure_kind === "quota" && current.reset_at !== "") {
|
|
321
|
+
if (armed !== null && !laterInstant(current.reset_at, armed))
|
|
322
|
+
return current;
|
|
323
|
+
const resetAt = current.reset_at;
|
|
324
|
+
const provider = current.provider;
|
|
325
|
+
const shared = waitedUntil.get(provider);
|
|
326
|
+
const now = hooks?.now ?? Date.now;
|
|
327
|
+
const past = !Number.isFinite(Date.parse(resetAt)) || now() >= Date.parse(resetAt);
|
|
328
|
+
if (!past && (shared === undefined || laterInstant(resetAt, shared))) {
|
|
329
|
+
emitRoleQuota(workspace, sessionId, current);
|
|
330
|
+
await waitUntil(resetAt, hooks).promise;
|
|
331
|
+
}
|
|
332
|
+
waitedUntil.set(provider, resetAt);
|
|
333
|
+
armed = resetAt;
|
|
334
|
+
current = await run(promptFor(current), current.execution_id);
|
|
335
|
+
}
|
|
336
|
+
return current;
|
|
337
|
+
}
|
|
338
|
+
function laterInstant(next, previous) {
|
|
339
|
+
const left = Date.parse(next);
|
|
340
|
+
const right = Date.parse(previous);
|
|
341
|
+
if (Number.isFinite(left) && Number.isFinite(right))
|
|
342
|
+
return left > right;
|
|
343
|
+
return next > previous;
|
|
344
|
+
}
|
|
345
|
+
function emitRoleQuota(workspace, sessionId, result) {
|
|
346
|
+
const store = new SessionStore(workspace);
|
|
347
|
+
const context = store.executionContext(sessionId, result.execution_id);
|
|
348
|
+
if (context === null)
|
|
349
|
+
return;
|
|
350
|
+
let model = "";
|
|
351
|
+
try {
|
|
352
|
+
const metadata = JSON.parse(readFileSync(path.join(context.directory, "execution.json"), "utf8"));
|
|
353
|
+
if (isRecord(metadata) && typeof metadata.model === "string")
|
|
354
|
+
model = metadata.model;
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
model = "";
|
|
358
|
+
}
|
|
359
|
+
const summary = [result.response, result.reset_at].filter((item) => item !== "").join(" ");
|
|
360
|
+
new ProviderEventReporter(store, context, result.provider, model).emit("provider.quota", summary, {
|
|
361
|
+
retry_at: result.reset_at,
|
|
362
|
+
provider: result.provider,
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
function lastUserPrompt(workspace, sessionId, executionId) {
|
|
366
|
+
const context = new SessionStore(workspace).executionContext(sessionId, executionId);
|
|
367
|
+
if (context === null)
|
|
368
|
+
throw new ConfigurationError(`Execution ${executionId} was not found.`);
|
|
369
|
+
const raw = JSON.parse(readFileSync(context.conversationReadPath, "utf8"));
|
|
370
|
+
const history = Array.isArray(raw) ? raw : isRecord(raw) && Array.isArray(raw.history) ? raw.history : [];
|
|
371
|
+
for (let index = history.length - 1; index >= 0; index -= 1) {
|
|
372
|
+
const entry = history[index];
|
|
373
|
+
if (isRecord(entry) && entry.role === "user" && typeof entry.content === "string" && entry.content !== "") {
|
|
374
|
+
return entry.content;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
throw new ConfigurationError(`Execution ${executionId} has no prompt to resume.`);
|
|
378
|
+
}
|
|
379
|
+
function isRecord(value) {
|
|
380
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
381
|
+
}
|
|
382
|
+
function finishRole(sessionId, code) {
|
|
383
|
+
if (code === 1 || code === 6 || code === 130)
|
|
384
|
+
printResumeCommand(sessionId);
|
|
385
|
+
return code;
|
|
386
|
+
}
|
|
387
|
+
function rolePrompt(workspace, role, text) {
|
|
388
|
+
return prependRoleInstructions(loadRoleInstructions(loadYamlMapping(path.join(workspace, ".migent", "config.yaml")), role), text);
|
|
389
|
+
}
|
|
390
|
+
function executionProfile(directory, executionId) {
|
|
391
|
+
const raw = JSON.parse(readFileSync(path.join(directory, "execution.json"), "utf8"));
|
|
392
|
+
if (!isRecord(raw) ||
|
|
393
|
+
typeof raw.provider !== "string" ||
|
|
394
|
+
raw.provider === "" ||
|
|
395
|
+
typeof raw.model !== "string" ||
|
|
396
|
+
raw.model === "") {
|
|
397
|
+
throw new ConfigurationError(`Execution ${executionId} has no provider.`);
|
|
398
|
+
}
|
|
399
|
+
return { provider: raw.provider, model: raw.model, options: stringOptions(raw.options) };
|
|
400
|
+
}
|
|
401
|
+
function executionBlocker(directory) {
|
|
402
|
+
try {
|
|
403
|
+
const raw = JSON.parse(readFileSync(path.join(directory, "execution.json"), "utf8"));
|
|
404
|
+
if (!isRecord(raw) || !isRecord(raw.outcome))
|
|
405
|
+
return null;
|
|
406
|
+
return typeof raw.outcome.blocker === "string" && raw.outcome.blocker !== "" ? raw.outcome.blocker : null;
|
|
407
|
+
}
|
|
408
|
+
catch {
|
|
409
|
+
return null;
|
|
137
410
|
}
|
|
138
411
|
}
|
|
139
412
|
function resolveSession(workspace, sessionId, role, task) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type Provider } from "@nodeint/migent-kernel";
|
|
2
2
|
import { type RunCommand, type Which } from "../provider.js";
|
|
3
3
|
export interface ConfigPrompter {
|
|
4
4
|
select(message: string, choices: ReadonlyArray<readonly [string, string]>, defaultValue?: string | null): string | Promise<string>;
|
|
@@ -14,7 +14,7 @@ export declare function runConfigModel(workspace: string, options?: {
|
|
|
14
14
|
clearOptions?: readonly string[];
|
|
15
15
|
asJson?: boolean;
|
|
16
16
|
interactive?: boolean;
|
|
17
|
-
|
|
17
|
+
providers?: Record<string, Provider> | null;
|
|
18
18
|
which?: Which | null;
|
|
19
19
|
prompter?: ConfigPrompter | null;
|
|
20
20
|
runCommand?: RunCommand | null;
|
|
@@ -28,7 +28,7 @@ export declare function runConfigRole(workspace: string, options?: {
|
|
|
28
28
|
clearOptions?: readonly string[];
|
|
29
29
|
asJson?: boolean;
|
|
30
30
|
interactive?: boolean;
|
|
31
|
-
|
|
31
|
+
providers?: Record<string, Provider> | null;
|
|
32
32
|
which?: Which | null;
|
|
33
33
|
prompter?: ConfigPrompter | null;
|
|
34
34
|
runCommand?: RunCommand | null;
|