Skip to content

refactor: remove the InfiniteAIAssistant command type - #1624

Open
chhoumann wants to merge 2 commits into
chhoumann/1571-exhaustive-command-dispatchfrom
chhoumann/1571-remove-infinite-ai-assistant
Open

refactor: remove the InfiniteAIAssistant command type#1624
chhoumann wants to merge 2 commits into
chhoumann/1571-exhaustive-command-dispatchfrom
chhoumann/1571-remove-infinite-ai-assistant

Conversation

@chhoumann

@chhoumann chhoumann commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Stacked on #1623. Merge #1623 first - this branch contains its two commits, and the base flips to master once it lands.

What this removes, and why

CommandType.InfiniteAIAssistant shipped in ae90edeb on 2023-06-20, six minutes before the 1.2.0 tag. Every release since has carried it. It was never creatable in any released version: across all 202 tags, git log --all -S"InfiniteAIAssistant" --name-only shows the identifier only ever touched CommandType.ts, IAIAssistantCommand.ts, the modal (+test), main.ts, packagePreview.ts, MacroDisclosure.svelte, modelRefPinning.ts, refreshStaleDefaultModelSeeds.ts and one test file. Never a builder, an engine, or an API file. No InfiniteAIAssistantCommand class ever existed; the only add-AI path is CommandSequenceEditor.ts -> new AIAssistantCommand(), which hardcodes CommandType.AIAssistant.

It was abandoned deliberately. Chunked prompting shipped as a user script (discussion #535: "I'm kind of on the fence about whether it should be a feature") and later as quickAddApi.ai.chunkedPrompt().

Rejecting "wire it up instead." It is not a missing if. IInfiniteAIAssistantCommand has no promptTemplate and no text source, and ChunkedPrompt throws without a chunk reference. Wiring it up means designing where the text comes from plus a template picker: a new feature with zero recorded demand, competing against quickAddApi.ai.chunkedPrompt, which is a strict superset (documented, 588-line test file, auto-split on provider rejection, 500-prompt cap). If chunking ever returns to the builder, the right shape is a "chunk long input" toggle on the existing AI Assistant command reusing its promptTemplate, not a second command type. Recording that so it does not get re-proposed.

Removed

Enum member · IInfiniteAIAssistantCommand · the 268-line modal + its 114-line test · the systemPromptFields MODALS row · the devMode testQuickAdd command (its entire body constructed that modal - and passed type: CommandType.AIAssistant for an IInfiniteAIAssistantCommand, so even the dev harness built a mistyped object) and its label · the packagePreview case · the MacroDisclosure label · the isAICommand clauses in modelRefPinning.ts and refreshStaleDefaultModelSeeds.ts · the orphaned getMaxChunkTokensUpperBound / getLargestModelMaxTokens with their test, plus FALLBACK_MODEL_MAX_TOKENS and the estimateModelInputBudget import they were the only local users of.

chunkSeparator / resultJoiner / maxChunkTokens / mergeChunks on the script API path (AIAssistant.ts, quickAddApi.ts) are untouched. Same names, different feature - the biggest trap in this removal.

No data migration

Deliberate, and the reasoning is worth keeping:

  • Converting to a plain AIAssistant is not inert. With promptTemplate.enable: false, executeAIAssistant -> runAIAssistant opens a prompt-template picker and fires a billable network request. It turns a no-op into an interactive, billable step the user never configured. Under disableOnlineFeatures (the default) it throws instead.
  • Dropping the command deletes user data to fix a hazard nobody demonstrably has.
  • A migration runs once and is flagged forever, but hand-editing and package import still work afterwards. fix: say so when a macro step cannot be run, instead of dropping it #1623 covers the hazard permanently and generically.
  • The setting could not be carried faithfully anyway: chunkSeparator is a string here and a RegExp in chunkedPrompt, so a stored "\n" is a literal backslash-n.

Verified in the live vault: a data.json holding one survives load, all migrations, a macro-builder open/reorder/close, and saveSettings() byte-identical (sha 22cc0612… before and after). Nothing in this PR writes to it.

Behaviour changes worth naming

1. pinAiCommandModelRefs stops classifying it as an AI command at import time (packageImportService.ts -> modelRefPinning.ts). Same for refreshStaleDefaultModelSeeds. Both migrations now skip such a command instead of pinning a modelRef / rewriting model / stripping baked params on it. This removes writes rather than adding them, and the command was never runnable, so nothing observable changes - but it is a real behaviour change, not "2 LOC".

2. Package import disclosure flips from a false promise to an honest warning. KNOWN_COMMAND_TYPES is Object.values(CommandType), so removal moves a legacy InfiniteAIAssistant step from the "AI assistant / Sends note content to your AI provider over the network" row to "Unknown capability. Review it manually." Pinned by a new test. It also means MacroDisclosure renders a CapabilityTag for the row, never the now-label-less raw type string.

3. The engine keeps telling the truth about the type after the enum member is gone. A naive removal would drop it into the generic branch and tell the user it "can come from a newer version of QuickAdd" - the exact opposite of what happened, and no help. RETIRED_COMMAND_TYPES carries the fact forward:

retired type notice

The out prompt behind it is the unchanged downstream symptom: the step still does not set out, so the capture still asks. What changed in #1623 is that the user is now told why. This PR adds what to do instead.

4. quickadd:run still answers ok: true for a macro with a skipped step (the envelope already carries verified: false). Enumerating skipped steps in the run envelope belongs with the #1606 result contract, not here.

Docs

AIAssistant.md had an anchor-pinned ### Max chunk tokens {#max-chunk-tokens} under Model settings and token budgets, sitting next to real settings - but the only "Max chunk tokens" control the plugin ever had was the slider inside the unreachable modal. A reader hunts for a setting that does not exist.

The substance moves to the chunkedPrompt API docs, reframed as the API option it actually is, and the redundant duplicate bullet is folded into a pointer. Anchors are frozen, so {#max-chunk-tokens} is preserved as a real heading on both pages: the old page keeps its ToC entry and the term the reader clicked, with one line pointing at the new home.

docs/scripts/check-links.py: 0 problems across 50 pages; both id="max-chunk-tokens" anchors present in the built site.

Also: AGENTS.md pointed agents at the deleted quickadd:testQuickAdd command.

Flagged, not folded in (sibling workers are active on #1607-#1615 in this area)

  • The macro builder gives no hint which row is dead. The notice says "delete the step from the macro"; CommandList.svelte's {:else} fallback renders the retired command as an ordinary row with Delete + Reorder and no marker. Since there is deliberately no migration, the builder is where these live forever. Worth a follow-up - but the population is "users with a hand-edited data.json", and the acquisition survey below found none.
  • A run-on-startup macro holding one now raises a notice at every launch. That is the intended trade of fix: say so when a macro step cannot be run, instead of dropping it #1623 (shout, don't drop), and the remedy is one edit, but it is the shape where "shout every time" has no dismissal.
  • getModelMaxTokens (aiHelpers.ts) has no production caller either - dead on master, not introduced or adjacent here.

Acquisition surface, for the record

Hand-edited data.json, a script mutating settings.choices, or a hand-authored package. Zero hits in issues, zero in discussions, zero public JSON on GitHub, zero of the 6 public packages. That is "no evidence anyone has one", not "impossible" - which is exactly why the fix is #1623's generic guard rather than a migration.

Verification

tsc -noEmit clean · eslint clean · svelte-check 0 errors · 4644 tests pass · docs build + link check clean · live-verified in this worktree's isolated vault (legacy data.json round-trip, run-path notice, quickadd:testQuickAdd gone from the command registry, remaining quickadd:* commands intact).

Closes #1571

Summary by CodeRabbit

  • New Features

    • Added clearer guidance for running and verifying Obsidian workflows.
    • Improved documentation for configuring chunk sizes in AI prompts.
  • Bug Fixes

    • Legacy Infinite AI Assistant commands now receive clearer retired-command messaging.
    • Legacy commands are correctly classified as unsupported rather than active AI capabilities.
  • Refactor

    • Removed the retired Infinite AI Assistant command and its configuration interface.
    • Removed the development-only test command and related settings UI.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR retires the unreachable InfiniteAIAssistant command type, removes its modal and obsolete chunk-budget helpers, updates legacy-command handling and previews, revises related tests and labels, and documents the current AI chunk-token API and E2E workflow.

Changes

Infinite AI Assistant retirement

Layer / File(s) Summary
Retired command contract and runtime handling
src/types/macros/CommandType.ts, src/engine/..., src/services/..., src/ai/modelRefPinning.ts, src/migrations/..., src/gui/PackageManager/...
Removes InfiniteAIAssistant as a valid enum member and classifies legacy values as retired or unknown instead of executable or AI-capable.
Dead UI and helper removal
src/gui/MacroGUIs/..., src/types/macros/QuickCommands/..., src/main.ts, src/ai/aiHelpers.ts, src/gui/ai/..., src/commandLabels.ts
Removes the unreachable settings modal, related interface, dev command registration, chunk-budget helpers, and associated test scaffolding.
Documentation and E2E workflow updates
docs/src/content/docs/docs/..., AGENTS.md
Documents maxChunkTokens as a chunkedPrompt() API option and updates Obsidian verification instructions to use runner and eval commands.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested labels: released

Poem

A bunny found a command asleep,
And tucked its old code in a heap.
The chunks now know where budgets belong,
E2E hops through a runner song.
Retired types rest, neat and deep.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Clear and specific summary of the main change.
Linked Issues check ✅ Passed Removes the unreachable command type and adds retired-command reporting, matching #1571's remove-and-notify approach.
Out of Scope Changes check ✅ Passed No clearly unrelated changes are evident; the docs, tests, and AGENTS updates all support the command-type removal.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chhoumann/1571-remove-infinite-ai-assistant

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

It shipped in 1.2.0 and was never creatable in any released version. Across
all 202 tags the identifier only ever touched CommandType, the interface, the
modal (+test), main.ts, packagePreview, MacroDisclosure, modelRefPinning,
refreshStaleDefaultModelSeeds and one test - never a builder, an engine or an
API file. The only add-AI path hardcodes CommandType.AIAssistant. Chunked
prompting shipped instead as quickAddApi.ai.chunkedPrompt(), which is a strict
superset: documented, tested, auto-splitting on provider rejection.

Wiring it up was the alternative, and it is not a missing `if`:
IInfiniteAIAssistantCommand has no promptTemplate and no text source, and
ChunkedPrompt throws without a chunk reference. It would mean designing where
the text comes from plus a template picker - a new feature with zero recorded
demand, competing with a superset. If chunking ever returns to the builder,
the right shape is a "chunk long input" toggle on the existing AI Assistant
command reusing its promptTemplate, not a second command type.

Removed: the enum member, IInfiniteAIAssistantCommand, the 268-line modal and
its test, the systemPromptFields entry, the devMode testQuickAdd command
(whose entire body constructed that modal) and its label, the packagePreview
case, the MacroDisclosure label, the isAICommand clauses in modelRefPinning
and refreshStaleDefaultModelSeeds, and the orphaned aiHelpers pair
getMaxChunkTokensUpperBound / getLargestModelMaxTokens with their test,
FALLBACK_MODEL_MAX_TOKENS and the estimateModelInputBudget import they were
the only local users of.

No data migration. Converting to a plain AIAssistant is not inert - with
promptTemplate.enable false it opens a template picker and fires a billable
request, or throws under disableOnlineFeatures (the default). Dropping the
command deletes user data to fix a hazard nobody demonstrably has. And
chunkSeparator is a string here but a RegExp in chunkedPrompt, so a stored
"\n" is a literal backslash-n that no conversion could carry faithfully. The
dispatch loop covers the hazard permanently and generically instead.

The engine keeps telling the truth about the type after the enum member is
gone: RETIRED_COMMAND_TYPES holds the message, so a data.json still carrying
one gets "never runnable, now removed, use chunkedPrompt" rather than the
generic "can come from a newer version of QuickAdd", which would be the exact
opposite of what happened.

Docs: the anchor-pinned "Max chunk tokens" section sat under AIAssistant's
"Model settings and token budgets" next to real settings, but the only control
that ever rendered it was the slider inside the unreachable modal. It moves to
the chunkedPrompt API docs, reframed as the API option it actually is. The
frozen anchor is preserved on both pages - the alias-anchor pattern this docs
tree already uses - so /docs/AIAssistant#max-chunk-tokens still lands on a
pointer to the new home.

AGENTS.md pointed agents at the deleted quickadd:testQuickAdd command; it now
points at quickadd:run and eval.
…r visible

Review follow-ups on the removal:

- The retired-type notice ran 438 characters, ~50% longer than any notice
  QuickAdd has ever shipped, in a 15-second toast. The provenance clause ("no
  macro-builder entry and no engine branch in any version") was commit-message
  material with no user-side referent; the two actions now come first.
- The docs pointer was a bare `<a id>` under the "Max tokens is the context
  window" section, so a reader arriving on the frozen anchor landed mid-way
  through a section about a different field, with the phrase they clicked
  nowhere on the page. It is a real heading again - same anchor, same ToC
  entry, one line of body pointing at the API docs.
- AGENTS.md claimed `eval` takes "an expression, not statements". Statements
  are fine and the completion value comes back; only top-level `await` fails.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 27, 2026

Copy link
Copy Markdown

Deploying quickadd with  Cloudflare Pages  Cloudflare Pages

Latest commit: 4a91cae
Status: ✅  Deploy successful!
Preview URL: https://f66e443c.quickadd.pages.dev
Branch Preview URL: https://chhoumann-1571-remove-infini.quickadd.pages.dev

View logs

@chhoumann
chhoumann force-pushed the chhoumann/1571-remove-infinite-ai-assistant branch from ba78f0c to 4a91cae Compare July 27, 2026 20:44
@chhoumann
chhoumann marked this pull request as ready for review July 27, 2026 20:53
@chhoumann

chhoumann commented Jul 27, 2026

Copy link
Copy Markdown
Owner Author

Note on CI and review bots: ci.yml triggers only on PRs targeting the default branch, and CodeRabbit auto-review is disabled off it too - so neither runs while this PR is stacked on #1623.

CI ran by workflow_dispatch against this branch instead, all green: https://github.com/chhoumann/quickadd/actions/runs/30304509379

Once #1623 merges, retarget this PR to master and both run natively.

@chhoumann

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@AGENTS.md`:
- Around line 51-55: Update the `quickadd:run` and `eval` command examples in
AGENTS.md to include the required `vault=<vault>` selector as the command
prefix, while preserving their existing arguments and guidance about readiness,
completion status, and wrapping asynchronous eval work in an IIFE.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b3781d8e-484a-4862-aae9-fc6b2921e5b2

📥 Commits

Reviewing files that changed from the base of the PR and between e0c022c and 4a91cae.

📒 Files selected for processing (22)
  • AGENTS.md
  • docs/src/content/docs/docs/AIAssistant.md
  • docs/src/content/docs/docs/QuickAddAPI.md
  • src/ai/AIAssistant.systemPromptLiteral.test.ts
  • src/ai/aiHelpers.maxChunkTokens.test.ts
  • src/ai/aiHelpers.ts
  • src/ai/modelRefPinning.ts
  • src/commandLabels.ts
  • src/engine/MacroChoiceEngine.ts
  • src/engine/MacroChoiceEngine.unknownCommand.test.ts
  • src/gui/MacroGUIs/AIAssistantInfiniteCommandSettingsModal.test.ts
  • src/gui/MacroGUIs/AIAssistantInfiniteCommandSettingsModal.ts
  • src/gui/PackageManager/MacroDisclosure.svelte
  • src/gui/ai/systemPromptFields.test.ts
  • src/gui/ai/systemPromptLiteralNote.ts
  • src/main.commandLabels.test.ts
  • src/main.ts
  • src/migrations/refreshStaleDefaultModelSeeds.ts
  • src/services/packagePreview.test.ts
  • src/services/packagePreview.ts
  • src/types/macros/CommandType.ts
  • src/types/macros/QuickCommands/IAIAssistantCommand.ts
💤 Files with no reviewable changes (10)
  • src/types/macros/CommandType.ts
  • src/ai/aiHelpers.maxChunkTokens.test.ts
  • src/main.commandLabels.test.ts
  • src/types/macros/QuickCommands/IAIAssistantCommand.ts
  • src/commandLabels.ts
  • src/gui/MacroGUIs/AIAssistantInfiniteCommandSettingsModal.ts
  • src/gui/PackageManager/MacroDisclosure.svelte
  • src/gui/MacroGUIs/AIAssistantInfiniteCommandSettingsModal.test.ts
  • src/ai/aiHelpers.ts
  • src/main.ts

Comment thread AGENTS.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant