@algolia/wizard 0.119.0 → 0.121.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/dist/main.js +106 -19
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -325,6 +325,7 @@ var useWizard = create((set, get) => ({
|
|
|
325
325
|
logs: [],
|
|
326
326
|
_outputLogCount: 0,
|
|
327
327
|
error: null,
|
|
328
|
+
exitRequested: false,
|
|
328
329
|
inputReq: null,
|
|
329
330
|
_resolve: null,
|
|
330
331
|
settingUpAppId: null,
|
|
@@ -488,7 +489,15 @@ var useWizard = create((set, get) => ({
|
|
|
488
489
|
get().logEnd(id, "success");
|
|
489
490
|
},
|
|
490
491
|
setDone: () => set({ phase: "done", loadingMessage: null }),
|
|
491
|
-
setError: (message) =>
|
|
492
|
+
setError: (message, options) => {
|
|
493
|
+
if (options?.exit) get()._clearNoticeQueue();
|
|
494
|
+
set({
|
|
495
|
+
phase: "error",
|
|
496
|
+
error: message,
|
|
497
|
+
loadingMessage: null,
|
|
498
|
+
exitRequested: options?.exit ?? false
|
|
499
|
+
});
|
|
500
|
+
},
|
|
492
501
|
reset: () => {
|
|
493
502
|
get()._clearNoticeQueue();
|
|
494
503
|
get()._resolve?.(false);
|
|
@@ -508,6 +517,7 @@ var useWizard = create((set, get) => ({
|
|
|
508
517
|
logs: [],
|
|
509
518
|
_outputLogCount: 0,
|
|
510
519
|
error: null,
|
|
520
|
+
exitRequested: false,
|
|
511
521
|
inputReq: null,
|
|
512
522
|
_resolve: null,
|
|
513
523
|
settingUpAppId: null,
|
|
@@ -1460,12 +1470,13 @@ function EnterToContinuePrompt({
|
|
|
1460
1470
|
] });
|
|
1461
1471
|
}
|
|
1462
1472
|
function PromptInput() {
|
|
1463
|
-
const { phase, inputReq, submitInput } = useWizard();
|
|
1473
|
+
const { phase, inputReq, submitInput, exitRequested } = useWizard();
|
|
1464
1474
|
const [draft, setDraft] = useState9("");
|
|
1465
1475
|
const [submittedReq, setSubmittedReq] = useState9(null);
|
|
1466
1476
|
const promptKey = inputReq && `${inputReq.promptType}:${inputReq.prompt}`;
|
|
1467
1477
|
const submitting = inputReq != null && submittedReq === inputReq;
|
|
1468
1478
|
if (phase === "done" || phase === "error") {
|
|
1479
|
+
if (exitRequested) return null;
|
|
1469
1480
|
return /* @__PURE__ */ jsx10(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text12, { color: "gray", dimColor: true, children: "Press Enter or Esc to exit" }) });
|
|
1470
1481
|
}
|
|
1471
1482
|
if (phase !== "awaitingInput" || !inputReq) return null;
|
|
@@ -2544,10 +2555,24 @@ async function ensureApplication(resumeAppId) {
|
|
|
2544
2555
|
}
|
|
2545
2556
|
}
|
|
2546
2557
|
|
|
2558
|
+
// src/lib/rateLimit.ts
|
|
2559
|
+
var RateLimitError = class extends Error {
|
|
2560
|
+
constructor(retryAfterSeconds, options) {
|
|
2561
|
+
super(rateLimitMessage(retryAfterSeconds), options);
|
|
2562
|
+
this.retryAfterSeconds = retryAfterSeconds;
|
|
2563
|
+
this.name = "RateLimitError";
|
|
2564
|
+
}
|
|
2565
|
+
retryAfterSeconds;
|
|
2566
|
+
};
|
|
2567
|
+
function rateLimitMessage(retryAfterSeconds) {
|
|
2568
|
+
const when = retryAfterSeconds === void 0 ? "in a moment" : `in ${retryAfterSeconds} ${retryAfterSeconds === 1 ? "second" : "seconds"}`;
|
|
2569
|
+
return `You've hit the rate limit. Try again ${when}.`;
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2547
2572
|
// package.json
|
|
2548
2573
|
var package_default = {
|
|
2549
2574
|
name: "@algolia/wizard",
|
|
2550
|
-
version: "0.
|
|
2575
|
+
version: "0.121.0",
|
|
2551
2576
|
description: "Magically implement Algolia functionality in your codebase",
|
|
2552
2577
|
type: "module",
|
|
2553
2578
|
engines: {
|
|
@@ -2638,6 +2663,16 @@ var RestartWorkflowSignal = class extends Error {
|
|
|
2638
2663
|
}
|
|
2639
2664
|
appId;
|
|
2640
2665
|
};
|
|
2666
|
+
var ExitWizardSignal = class extends Error {
|
|
2667
|
+
constructor(original) {
|
|
2668
|
+
super(original instanceof Error ? original.message : String(original), {
|
|
2669
|
+
cause: original
|
|
2670
|
+
});
|
|
2671
|
+
this.original = original;
|
|
2672
|
+
this.name = "ExitWizardSignal";
|
|
2673
|
+
}
|
|
2674
|
+
original;
|
|
2675
|
+
};
|
|
2641
2676
|
function ensureExecutedStepCount(state) {
|
|
2642
2677
|
if (state.executedStepCount == null) {
|
|
2643
2678
|
state.executedStepCount = state.steps.filter(
|
|
@@ -2828,6 +2863,29 @@ async function rewindTo(state, targetIndex, fromIndex) {
|
|
|
2828
2863
|
store.syncSteps([...state.steps], targetIndex);
|
|
2829
2864
|
await persistState(state);
|
|
2830
2865
|
}
|
|
2866
|
+
var RATE_LIMIT_RETRY_OPTION = "Retry";
|
|
2867
|
+
var RATE_LIMIT_EXIT_OPTION = "Exit";
|
|
2868
|
+
async function runStepWithRateLimitRecovery(state, step, ctx) {
|
|
2869
|
+
for (; ; ) {
|
|
2870
|
+
try {
|
|
2871
|
+
return await step.run(ctx);
|
|
2872
|
+
} catch (err) {
|
|
2873
|
+
if (!(err instanceof RateLimitError)) throw err;
|
|
2874
|
+
const choice = await useWizard.getState().requestUserInput({
|
|
2875
|
+
prompt: "Retry the step, or exit the wizard?",
|
|
2876
|
+
promptType: "multipleChoice",
|
|
2877
|
+
options: [RATE_LIMIT_RETRY_OPTION, RATE_LIMIT_EXIT_OPTION],
|
|
2878
|
+
alert: {
|
|
2879
|
+
variant: "error",
|
|
2880
|
+
title: "Too many requests",
|
|
2881
|
+
message: err.message
|
|
2882
|
+
}
|
|
2883
|
+
});
|
|
2884
|
+
if (choice !== RATE_LIMIT_RETRY_OPTION) throw new ExitWizardSignal(err);
|
|
2885
|
+
ctx = await makeContext(state, true);
|
|
2886
|
+
}
|
|
2887
|
+
}
|
|
2888
|
+
}
|
|
2831
2889
|
async function runStep(state, index, step) {
|
|
2832
2890
|
const store = useWizard.getState();
|
|
2833
2891
|
const record = state.steps[index];
|
|
@@ -2854,7 +2912,7 @@ async function runStep(state, index, step) {
|
|
|
2854
2912
|
const stopSavingCost = saveCostDuringStep(state);
|
|
2855
2913
|
let output;
|
|
2856
2914
|
try {
|
|
2857
|
-
const raw = await step
|
|
2915
|
+
const raw = await runStepWithRateLimitRecovery(state, step, ctx);
|
|
2858
2916
|
output = step.outputSchema.parse(raw);
|
|
2859
2917
|
await step.onStepComplete?.(output, ctx);
|
|
2860
2918
|
} catch (err) {
|
|
@@ -3014,7 +3072,9 @@ async function runWorkflow(workflow, startWorkflowAppId, options) {
|
|
|
3014
3072
|
await recordWorkflowRun(workflow.id, nowIso());
|
|
3015
3073
|
await clearWorkflowState(workflow.id);
|
|
3016
3074
|
store.setDone();
|
|
3017
|
-
} catch (
|
|
3075
|
+
} catch (thrown) {
|
|
3076
|
+
const exitRequested = thrown instanceof ExitWizardSignal;
|
|
3077
|
+
const err = exitRequested ? thrown.original : thrown;
|
|
3018
3078
|
const message = err instanceof Error ? err.message : String(err);
|
|
3019
3079
|
const failed = await loadWorkflowState(workflow.id);
|
|
3020
3080
|
const failedAppId = failed ? runAppId(failed) : startWorkflowAppId;
|
|
@@ -3063,7 +3123,7 @@ async function runWorkflow(workflow, startWorkflowAppId, options) {
|
|
|
3063
3123
|
...errorType ? { error_type: errorType } : {},
|
|
3064
3124
|
...errorCode2 ? { error_code: errorCode2 } : {}
|
|
3065
3125
|
});
|
|
3066
|
-
store.setError(message);
|
|
3126
|
+
store.setError(message, { exit: exitRequested });
|
|
3067
3127
|
}
|
|
3068
3128
|
}
|
|
3069
3129
|
|
|
@@ -5559,6 +5619,7 @@ var GLOBAL_BUDGET_USER_MESSAGE = "The wizard reached its daily AI usage limit fo
|
|
|
5559
5619
|
var PROXY_AUTH_REJECTED_HEADER2 = "x-wizard-proxy-auth";
|
|
5560
5620
|
var PROXY_REJECTION_BODY = "You shall not pass!";
|
|
5561
5621
|
var BUDGET_EXCEEDED_HEADER = "x-wizard-budget-exceeded";
|
|
5622
|
+
var RETRY_AFTER_HEADER = "x-wizard-retry-after";
|
|
5562
5623
|
function lastCallError(err) {
|
|
5563
5624
|
const cause = RetryError.isInstance(err) ? err.lastError : err;
|
|
5564
5625
|
return APICallError.isInstance(cause) ? cause : void 0;
|
|
@@ -5574,6 +5635,17 @@ function budgetExceededMessage(err) {
|
|
|
5574
5635
|
if (scope === "global") return GLOBAL_BUDGET_USER_MESSAGE;
|
|
5575
5636
|
return void 0;
|
|
5576
5637
|
}
|
|
5638
|
+
function rateLimitError(err) {
|
|
5639
|
+
const cause = lastCallError(err);
|
|
5640
|
+
if (cause?.statusCode !== 429) return void 0;
|
|
5641
|
+
const headers = cause.responseHeaders;
|
|
5642
|
+
const seconds = Number(
|
|
5643
|
+
headers?.[RETRY_AFTER_HEADER] ?? headers?.["retry-after"]
|
|
5644
|
+
);
|
|
5645
|
+
return new RateLimitError(seconds > 0 ? Math.ceil(seconds) : void 0, {
|
|
5646
|
+
cause: err
|
|
5647
|
+
});
|
|
5648
|
+
}
|
|
5577
5649
|
var INCOMPLETE_CAUSES = {
|
|
5578
5650
|
stepLimit: {
|
|
5579
5651
|
kind: "missingReportAtStepLimit",
|
|
@@ -5799,7 +5871,7 @@ async function runAgentAttempt(req, attempt, retryReason, continuation) {
|
|
|
5799
5871
|
...continuation.messages,
|
|
5800
5872
|
{ role: "user", content: ENDED_TURN_NUDGE }
|
|
5801
5873
|
] : [{ role: "user", content: INITIAL_PROMPT }];
|
|
5802
|
-
const stream = await agent.stream({ prompt });
|
|
5874
|
+
const stream = await agent.stream({ prompt, abortSignal: req.abortSignal });
|
|
5803
5875
|
let chunks = [];
|
|
5804
5876
|
const chunkLimit = 5;
|
|
5805
5877
|
let streamError;
|
|
@@ -5820,6 +5892,10 @@ async function runAgentAttempt(req, attempt, retryReason, continuation) {
|
|
|
5820
5892
|
if (chunks.length) {
|
|
5821
5893
|
logger.debug(chunks.join(""));
|
|
5822
5894
|
}
|
|
5895
|
+
if (req.abortSignal?.aborted) {
|
|
5896
|
+
logger.info({ operation: req.operation }, "runAgent aborted");
|
|
5897
|
+
req.abortSignal.throwIfAborted();
|
|
5898
|
+
}
|
|
5823
5899
|
if (streamError !== void 0) {
|
|
5824
5900
|
logger.error({ err: streamError }, "agent stream reported an error");
|
|
5825
5901
|
if (isProxyInactivityRejection(streamError)) {
|
|
@@ -5827,7 +5903,7 @@ async function runAgentAttempt(req, attempt, retryReason, continuation) {
|
|
|
5827
5903
|
}
|
|
5828
5904
|
const budgetMessage = budgetExceededMessage(streamError);
|
|
5829
5905
|
if (budgetMessage) throw new Error(budgetMessage, { cause: streamError });
|
|
5830
|
-
throw streamError;
|
|
5906
|
+
throw rateLimitError(streamError) ?? streamError;
|
|
5831
5907
|
}
|
|
5832
5908
|
const end = Date.now();
|
|
5833
5909
|
const usage = await stream.totalUsage;
|
|
@@ -5960,9 +6036,10 @@ function prioritizeFrontendFrameworks(result) {
|
|
|
5960
6036
|
);
|
|
5961
6037
|
return { ...result, frameworks: [...frontend, ...remaining] };
|
|
5962
6038
|
}
|
|
5963
|
-
var detectLanguage = async () => {
|
|
6039
|
+
var detectLanguage = async (abortSignal) => {
|
|
5964
6040
|
const result = await runAgent({
|
|
5965
6041
|
operation: "language-detection",
|
|
6042
|
+
abortSignal,
|
|
5966
6043
|
instructions: [
|
|
5967
6044
|
"Analyze the codebase and determine the programming languages and frameworks used",
|
|
5968
6045
|
"If a superset language is found, exclude the subset language (e.g. TypeScript over JavaScript).",
|
|
@@ -6058,20 +6135,21 @@ var MODE_CONFIG = {
|
|
|
6058
6135
|
outputSchema: verificationSchema
|
|
6059
6136
|
}
|
|
6060
6137
|
};
|
|
6061
|
-
function runMode(mode, extraInstructions = []) {
|
|
6138
|
+
function runMode(mode, extraInstructions = [], abortSignal) {
|
|
6062
6139
|
const { instructions, outputSchema } = MODE_CONFIG[mode];
|
|
6063
6140
|
return runAgent({
|
|
6064
6141
|
operation: `code-analysis-${mode}`,
|
|
6065
6142
|
instructions: [...instructions, ...extraInstructions],
|
|
6066
6143
|
tools: READONLY_TOOLS,
|
|
6067
6144
|
outputSchema,
|
|
6068
|
-
modelProfile: "analysis" /* analysis
|
|
6145
|
+
modelProfile: "analysis" /* analysis */,
|
|
6146
|
+
abortSignal
|
|
6069
6147
|
});
|
|
6070
6148
|
}
|
|
6071
|
-
async function runAnalysis(mode, extraInstructions = []) {
|
|
6149
|
+
async function runAnalysis(mode, extraInstructions = [], abortSignal) {
|
|
6072
6150
|
const modes = mode ? [mode] : ["ingestion", "searchImplementation", "verification"];
|
|
6073
6151
|
const results = await Promise.all(
|
|
6074
|
-
modes.map((m) => runMode(m, extraInstructions))
|
|
6152
|
+
modes.map((m) => runMode(m, extraInstructions, abortSignal))
|
|
6075
6153
|
);
|
|
6076
6154
|
return Object.assign({}, ...results);
|
|
6077
6155
|
}
|
|
@@ -6085,9 +6163,14 @@ var projectScanSchema = detectLanguageSchema.extend({
|
|
|
6085
6163
|
});
|
|
6086
6164
|
async function projectScan(ctx) {
|
|
6087
6165
|
const startedAt = Date.now();
|
|
6166
|
+
const controller = new AbortController();
|
|
6167
|
+
const abortOthersOnFailure = (run2) => run2.catch((err) => {
|
|
6168
|
+
controller.abort();
|
|
6169
|
+
throw err;
|
|
6170
|
+
});
|
|
6088
6171
|
const [detected, analyses] = await Promise.all([
|
|
6089
|
-
detectLanguage(),
|
|
6090
|
-
runAnalysis()
|
|
6172
|
+
abortOthersOnFailure(detectLanguage(controller.signal)),
|
|
6173
|
+
abortOthersOnFailure(runAnalysis(void 0, [], controller.signal))
|
|
6091
6174
|
]);
|
|
6092
6175
|
const entities = toEntitySummary(analyses.ingestionAnalysis ?? []);
|
|
6093
6176
|
track("AI Wizard Scan Completed", {
|
|
@@ -10501,7 +10584,7 @@ function Ribbon() {
|
|
|
10501
10584
|
}
|
|
10502
10585
|
|
|
10503
10586
|
// src/ui/App.tsx
|
|
10504
|
-
import { useState as useState14 } from "react";
|
|
10587
|
+
import { useEffect as useEffect5, useState as useState14 } from "react";
|
|
10505
10588
|
|
|
10506
10589
|
// src/ui/Logs.tsx
|
|
10507
10590
|
import { Box as Box21, Text as Text22, useInput as useInput9 } from "ink";
|
|
@@ -11135,9 +11218,13 @@ function App() {
|
|
|
11135
11218
|
workflow,
|
|
11136
11219
|
settingUpAppId,
|
|
11137
11220
|
loadingMessage,
|
|
11138
|
-
review: review2
|
|
11221
|
+
review: review2,
|
|
11222
|
+
exitRequested
|
|
11139
11223
|
} = useWizard();
|
|
11140
11224
|
const { exit } = useApp2();
|
|
11225
|
+
useEffect5(() => {
|
|
11226
|
+
if (exitRequested) exit();
|
|
11227
|
+
}, [exitRequested, exit]);
|
|
11141
11228
|
const { columns, rows } = useWindowSize8();
|
|
11142
11229
|
useRepaintOnResize();
|
|
11143
11230
|
const compactRun = isCompactTerminal(columns, rows);
|
|
@@ -11158,7 +11245,7 @@ function App() {
|
|
|
11158
11245
|
const holdForTip = !compactRun && tipsActive && isAwaitingUserInput && tipState === "typing";
|
|
11159
11246
|
const showTips = !compactRun && tipsActive && (phase === "running" && currentStep?.status === "running" && !loadingMessage && !settingUpAppId || holdForTip);
|
|
11160
11247
|
const showNoticesInMain = !tipsActive;
|
|
11161
|
-
const showNotices = !compactRun && (!isAwaitingUserInput || holdForTip) && !review2;
|
|
11248
|
+
const showNotices = !compactRun && (!isAwaitingUserInput || holdForTip) && !review2 && !exitRequested;
|
|
11162
11249
|
useInput10(
|
|
11163
11250
|
(_input, key) => {
|
|
11164
11251
|
if (key.return) {
|
|
@@ -11572,7 +11659,7 @@ async function promptResumeOrStartNew(session, next) {
|
|
|
11572
11659
|
// package.json with { type: 'json' }
|
|
11573
11660
|
var package_default2 = {
|
|
11574
11661
|
name: "@algolia/wizard",
|
|
11575
|
-
version: "0.
|
|
11662
|
+
version: "0.121.0",
|
|
11576
11663
|
description: "Magically implement Algolia functionality in your codebase",
|
|
11577
11664
|
type: "module",
|
|
11578
11665
|
engines: {
|