@algolia/wizard 0.91.0 → 0.93.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.
Files changed (2) hide show
  1. package/dist/main.js +91 -26
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -1817,7 +1817,21 @@ function agentRunMetrics(event, values, tags) {
1817
1817
  value: Number(event.attempt > FIRST_ATTEMPT),
1818
1818
  type: COUNT_METRIC,
1819
1819
  tags: runTags
1820
- }
1820
+ },
1821
+ ...event.stepCount === void 0 ? [] : [
1822
+ {
1823
+ name: "wizard.agent.step_count",
1824
+ value: event.stepCount,
1825
+ type: GAUGE_METRIC,
1826
+ tags: runTags
1827
+ },
1828
+ {
1829
+ name: "wizard.agent.step_limit_hit",
1830
+ value: Number(event.hitStepLimit === true),
1831
+ type: COUNT_METRIC,
1832
+ tags: runTags
1833
+ }
1834
+ ]
1821
1835
  ];
1822
1836
  }
1823
1837
  function trackAgentRun(event) {
@@ -1845,6 +1859,9 @@ function trackAgentRun(event) {
1845
1859
  thinking: profile.thinking,
1846
1860
  attempt: event.attempt,
1847
1861
  durationMs: event.durationMs,
1862
+ stepCount: event.stepCount,
1863
+ hitStepLimit: event.hitStepLimit,
1864
+ finishReason: event.finishReason,
1848
1865
  workflow_id: AGENT_TELEMETRY_CONTEXT.workflowId,
1849
1866
  app_id: AGENT_TELEMETRY_CONTEXT.appId,
1850
1867
  ...values
@@ -2367,7 +2384,7 @@ async function ensureApplication(resumeAppId) {
2367
2384
  // package.json
2368
2385
  var package_default = {
2369
2386
  name: "@algolia/wizard",
2370
- version: "0.91.0",
2387
+ version: "0.93.0",
2371
2388
  description: "Magically implement Algolia functionality in your codebase",
2372
2389
  type: "module",
2373
2390
  engines: {
@@ -5265,13 +5282,37 @@ function isProxyInactivityRejection(err) {
5265
5282
  const cause = RetryError.isInstance(err) ? err.lastError : err;
5266
5283
  return APICallError.isInstance(cause) && cause.statusCode === 401 && cause.responseBody === PROXY_REJECTION_BODY && cause.responseHeaders?.[PROXY_AUTH_REJECTED_HEADER2] === void 0;
5267
5284
  }
5285
+ var INCOMPLETE_CAUSES = {
5286
+ stepLimit: {
5287
+ kind: "missingReportAtStepLimit",
5288
+ reason: "reached its step limit"
5289
+ },
5290
+ truncated: {
5291
+ kind: "missingReportTruncated",
5292
+ reason: "was cut off by the output token limit"
5293
+ },
5294
+ stopped: {
5295
+ kind: "missingReportStopped",
5296
+ reason: "stopped before it finished"
5297
+ }
5298
+ };
5299
+ var INCOMPLETE_CAUSE_ENTRIES = Object.values(INCOMPLETE_CAUSES);
5300
+ function incompleteReasonOf(kind) {
5301
+ return INCOMPLETE_CAUSE_ENTRIES.find((entry) => entry.kind === kind)?.reason;
5302
+ }
5268
5303
  var MissingReportError = class extends Error {
5269
- atStepLimit;
5270
- constructor(atStepLimit) {
5304
+ incompleteCause;
5305
+ constructor(incompleteCause) {
5271
5306
  super(MISSING_REPORT_STATUS_ERROR_MESSAGE);
5272
- this.atStepLimit = atStepLimit;
5307
+ this.incompleteCause = incompleteCause;
5273
5308
  }
5274
5309
  };
5310
+ function incompleteCauseOf(stepCount, maxSteps, finishReason) {
5311
+ if (stepCount >= maxSteps) return "stepLimit";
5312
+ if (finishReason === "length") return "truncated";
5313
+ if (finishReason !== "stop") return "stopped";
5314
+ return null;
5315
+ }
5275
5316
  var AgentReportedFailureError = class extends Error {
5276
5317
  reason;
5277
5318
  constructor(reason) {
@@ -5297,11 +5338,11 @@ function withCachedHistory(messages) {
5297
5338
  ];
5298
5339
  }
5299
5340
  function isMissingReportRetry(kind) {
5300
- return kind === "missingReport" || kind === "missingReportAtStepLimit";
5341
+ return kind === "missingReport" || incompleteReasonOf(kind) !== void 0;
5301
5342
  }
5302
5343
  function retryKind(err) {
5303
5344
  if (err instanceof MissingReportError) {
5304
- return err.atStepLimit ? "missingReportAtStepLimit" : "missingReport";
5345
+ return err.incompleteCause ? INCOMPLETE_CAUSES[err.incompleteCause].kind : "missingReport";
5305
5346
  }
5306
5347
  if (NoOutputGeneratedError.isInstance(err)) return "transientProvider";
5307
5348
  if (APICallError.isInstance(err) && err.isRetryable) {
@@ -5335,7 +5376,9 @@ async function runAgentAttempt(req, attempt, retryReason) {
5335
5376
  const profileName = req.modelProfile ?? "implementation" /* implementation */;
5336
5377
  const profile = getModelProfile(profileName);
5337
5378
  const profileOptions = providerOptionsForProfile(profileName);
5379
+ const maxSteps = req.maxSteps ?? profile.maxSteps;
5338
5380
  const forceReport = retryReason === "missingReport";
5381
+ const incompleteReason = incompleteReasonOf(retryReason);
5339
5382
  const modelOptions = forceReport ? { thinking: { type: "disabled" } } : profileOptions;
5340
5383
  logger.info(
5341
5384
  {
@@ -5376,8 +5419,8 @@ async function runAgentAttempt(req, attempt, retryReason) {
5376
5419
  "The previous attempt ended without reportStatus. Do not repeat side effects. Use the available read tools to inspect existing work if needed, then call reportStatus."
5377
5420
  ] : [
5378
5421
  "The previous attempt ended without reportStatus. Do not repeat side effects. Call reportStatus now."
5379
- ] : retryReason === "missingReportAtStepLimit" ? [
5380
- "The previous attempt reached its step limit without reportStatus and may be incomplete. Inspect existing work, finish only the remaining work, avoid repeated side effects, and call reportStatus."
5422
+ ] : incompleteReason ? [
5423
+ `The previous attempt ${incompleteReason} without reportStatus and may be incomplete. Inspect existing work, finish only the remaining work, avoid repeated side effects, and call reportStatus.`
5381
5424
  ] : attempt > 0 ? [
5382
5425
  "This run is a retry after a transient AI service error. Files, shell commands, or ingestion may already have been applied in this workspace \u2014 inspect what is already there and continue from it rather than repeating that work."
5383
5426
  ] : []
@@ -5415,11 +5458,11 @@ async function runAgentAttempt(req, attempt, retryReason) {
5415
5458
  toolChoice: "required",
5416
5459
  stopWhen: [
5417
5460
  hasToolCall("reportStatus"),
5418
- stepCountIs(profile.maxSteps)
5461
+ stepCountIs(maxSteps)
5419
5462
  ],
5420
5463
  prepareStep: ({ stepNumber, messages }) => ({
5421
5464
  messages: withCachedHistory(messages),
5422
- ...stepNumber >= profile.maxSteps - 1 && {
5465
+ ...stepNumber >= maxSteps - 1 && {
5423
5466
  activeTools: ["reportStatus"]
5424
5467
  }
5425
5468
  }),
@@ -5459,12 +5502,20 @@ async function runAgentAttempt(req, attempt, retryReason) {
5459
5502
  }
5460
5503
  const end = Date.now();
5461
5504
  const usage = await stream.totalUsage;
5505
+ const steps = await stream.steps;
5506
+ const stepCount = steps.length;
5507
+ const hitStepLimit = stepCount >= maxSteps;
5508
+ const lastStep = steps[steps.length - 1];
5509
+ const finishReason = lastStep?.finishReason;
5462
5510
  trackAgentRun({
5463
5511
  operation: req.operation,
5464
5512
  profile: profileName,
5465
5513
  attempt: attempt + ATTEMPT_NUMBER_OFFSET,
5466
5514
  durationMs: end - start,
5467
- usage
5515
+ usage,
5516
+ stepCount,
5517
+ hitStepLimit,
5518
+ finishReason
5468
5519
  });
5469
5520
  logger.info(
5470
5521
  {
@@ -5473,7 +5524,11 @@ async function runAgentAttempt(req, attempt, retryReason) {
5473
5524
  operation: req.operation,
5474
5525
  profile: profileName,
5475
5526
  model: profile.model,
5476
- usage
5527
+ usage,
5528
+ stepCount,
5529
+ maxSteps,
5530
+ hitStepLimit,
5531
+ finishReason
5477
5532
  },
5478
5533
  "runAgent finished"
5479
5534
  );
@@ -5488,27 +5543,25 @@ async function runAgentAttempt(req, attempt, retryReason) {
5488
5543
  const toolResults = await stream.toolResults;
5489
5544
  const report = [...toolResults].reverse().find((r) => r.toolName === "reportStatus");
5490
5545
  if (!report) {
5491
- const steps = await stream.steps;
5492
- const lastStep = steps[steps.length - 1];
5493
5546
  logger.error(
5494
5547
  {
5495
- finishReason: lastStep?.finishReason,
5548
+ finishReason,
5496
5549
  rawFinishReason: lastStep?.rawFinishReason,
5497
- stepCount: steps.length,
5550
+ stepCount,
5498
5551
  lastStepToolCalls: lastStep?.toolCalls?.map((c) => c.toolName)
5499
5552
  },
5500
5553
  "Agent finished without calling reportStatus"
5501
5554
  );
5502
- const incomplete = steps.length >= profile.maxSteps || lastStep?.finishReason !== "stop";
5503
- throw new MissingReportError(incomplete);
5555
+ throw new MissingReportError(
5556
+ incompleteCauseOf(stepCount, maxSteps, finishReason)
5557
+ );
5504
5558
  }
5505
5559
  const result = report.output;
5506
5560
  if (result.status !== "success") {
5507
- const steps = await stream.steps;
5508
5561
  logger.warn(
5509
5562
  {
5510
5563
  reason: result.reason,
5511
- stepCount: steps.length,
5564
+ stepCount,
5512
5565
  recentSteps: steps.slice(-RECENT_STEPS_LOGGED).map((s) => ({
5513
5566
  text: s.text?.slice(0, LOGGED_CHARS),
5514
5567
  toolCalls: s.toolCalls?.map((c) => c.toolName),
@@ -6285,6 +6338,7 @@ var validationOutputSchema = z29.object({
6285
6338
  unrelatedFailure: z29.string().optional()
6286
6339
  });
6287
6340
  var MAX_IMPLEMENT_VALIDATION_ATTEMPTS = 3;
6341
+ var INGESTION_MAX_STEPS = 96;
6288
6342
  var FIRST_IMPLEMENTATION_ATTEMPT = 1;
6289
6343
  var DEFAULT_IMPLEMENT_USE_CASES = ["ingestion", "search"];
6290
6344
  var INGEST_DIR = ".algolia-wizard";
@@ -6670,10 +6724,15 @@ function ingestOutcome(executions, repoRoot, ingestCommand) {
6670
6724
  const succeeded = newestFirst.filter(
6671
6725
  (e) => e.approved && e.exitCode === 0 && !e.timedOut
6672
6726
  );
6727
+ const run2 = succeeded.find(matchesReportedCommand) ?? succeeded.find((e) => withCount.includes(e));
6728
+ const runs = executions.filter(
6729
+ (e) => e.approved && matchesReportedCommand(e)
6730
+ ).length;
6673
6731
  return {
6674
- run: succeeded.find(matchesReportedCommand) ?? succeeded.find((e) => withCount.includes(e)),
6732
+ run: run2,
6675
6733
  attempt: ingestCommand ? newestFirst.find(matchesReportedCommand) : void 0,
6676
- recordCount: parseIngestRecordCount(withCount[0]?.output ?? "")
6734
+ recordCount: parseIngestRecordCount(withCount[0]?.output ?? ""),
6735
+ attempts: run2 && !matchesReportedCommand(run2) ? runs + 1 : runs
6677
6736
  };
6678
6737
  }
6679
6738
  var INGEST_OUTPUT_TAIL_CHARS = 400;
@@ -7048,6 +7107,9 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES) {
7048
7107
  tools: toolsForUseCase(currentUseCase, input.ingestionSource),
7049
7108
  outputSchema: implementationOutputSchema,
7050
7109
  modelProfile: isRetry ? "implementationRetry" /* implementationRetry */ : "implementation" /* implementation */,
7110
+ ...currentUseCase === "ingestion" && {
7111
+ maxSteps: INGESTION_MAX_STEPS
7112
+ },
7051
7113
  toolContext
7052
7114
  });
7053
7115
  } catch (err) {
@@ -7181,7 +7243,8 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES) {
7181
7243
  const {
7182
7244
  run: ingestRun,
7183
7245
  attempt: ingestAttempt,
7184
- recordCount
7246
+ recordCount,
7247
+ attempts: ingestRunAttempts
7185
7248
  } = outcome;
7186
7249
  let ingestCwd = ".";
7187
7250
  if (ingestAttempt) {
@@ -7214,7 +7277,8 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES) {
7214
7277
  record_count: ingestRecordCount,
7215
7278
  duration_ms: ingestDurationMs ?? 0,
7216
7279
  index_name: targetIndex,
7217
- record_schema: recordSchema(sample, confirmed2?.[0]?.attributes ?? [])
7280
+ record_schema: recordSchema(sample, confirmed2?.[0]?.attributes ?? []),
7281
+ attempts: ingestRunAttempts
7218
7282
  });
7219
7283
  } else {
7220
7284
  logger.warn(
@@ -7250,6 +7314,7 @@ ${detail}` : ""}`
7250
7314
  error_message: `ingestion did not complete: ${reason}`,
7251
7315
  error_type: "Ingest Records",
7252
7316
  product_area: "AI Wizard",
7317
+ attempts: ingestRunAttempts,
7253
7318
  ...ingestAttempt?.exitCode != null ? { error_code: String(ingestAttempt.exitCode) } : {}
7254
7319
  });
7255
7320
  }
@@ -9794,7 +9859,7 @@ async function resetProjectState() {
9794
9859
  // package.json with { type: 'json' }
9795
9860
  var package_default2 = {
9796
9861
  name: "@algolia/wizard",
9797
- version: "0.91.0",
9862
+ version: "0.93.0",
9798
9863
  description: "Magically implement Algolia functionality in your codebase",
9799
9864
  type: "module",
9800
9865
  engines: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@algolia/wizard",
3
- "version": "0.91.0",
3
+ "version": "0.93.0",
4
4
  "description": "Magically implement Algolia functionality in your codebase",
5
5
  "type": "module",
6
6
  "engines": {