Skip to content

refactor: remove the InfiniteAIAssistant command type - #1633

Open
chhoumann wants to merge 3 commits into
masterfrom
chhoumann/1571-remove-infinite-ai-assistant
Open

refactor: remove the InfiniteAIAssistant command type#1633
chhoumann wants to merge 3 commits into
masterfrom
chhoumann/1571-remove-infinite-ai-assistant

Conversation

@chhoumann

@chhoumann chhoumann commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Follow-up to #1623, which is now merged. This is the second half of #1571: #1623 stopped the engine dropping steps it cannot run; this removes the type that motivated it.

(Replaces #1624, which GitHub auto-closed when #1623's branch was deleted - same change, rebased onto master.)

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.

(Screenshot taken on this branch rebased onto merged master, in this worktree's isolated vault.)

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

Re-run after rebasing onto merged master (1a864faa, i.e. after #1623, #1629 and #1632 landed):

tsc -noEmit clean · eslint clean · svelte-check 1171 files / 0 errors · 4799 tests pass · docs build + check-links.py 0 problems across 50 pages, both #max-chunk-tokens anchors present.

Live in this worktree's isolated vault, on the rebased build:

  • a legacy data.json command survives load + all migrations, and saveSettings() preserves every field (model, modelParameters, outputVariableName, systemPrompt, resultJoiner, chunkSeparator, maxChunkTokens, mergeChunks) - nothing here rewrites user data;
  • the run path emits the notice above and carries on into the capture;
  • quickadd:testQuickAdd is gone from the command registry, with runQuickAdd, runTemplateFromFolder, applyTemplateToActiveFile, reloadQuickAdd and openQuickAddSettings intact.

Closes #1571

Summary by CodeRabbit

  • Changes

    • Retired the legacy “Infinite AI Assistant” command and removed its settings interface.
    • Legacy configurations referencing the retired command type now receive clearer, more actionable guidance.
    • Stopped treating the legacy command type as AI-capable in macro/package previews, so it’s surfaced appropriately as unknown/unsupported.
    • Removed the dev-only test command from available quick-add command labels.
  • Documentation

    • Updated Obsidian runtime workflow instructions to use pnpm run obsidian:e2e, including choice execution/result interpretation and safe JS evaluation guidance.
    • Clarified that chunk sizing is governed by chunkedPrompt()’s maxChunkTokens, with details on token budgeting and prompt overhead.

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.
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR removes the unreachable InfiniteAIAssistant command type and configuration surface, reports legacy values as retired or unknown, removes related runtime integrations and tests, and updates AI documentation and Obsidian workflow instructions.

Changes

Infinite AI Assistant retirement

Layer / File(s) Summary
Remove command contract and configuration surface
src/types/macros/..., src/gui/ai/..., src/ai/aiHelpers.ts
Removes the InfiniteAIAssistant type, interface, settings modal coverage, token-bound helpers, and related system-prompt test fixtures.
Handle legacy commands as retired
src/engine/..., src/services/packagePreview.*, src/gui/PackageManager/..., src/ai/modelRefPinning.ts, src/migrations/...
Legacy InfiniteAIAssistant values are no longer treated as active AI commands and are reported as retired or unknown.
Remove obsolete development command
src/main.ts, src/commandLabels.ts, src/main.commandLabels.test.ts
Removes the dev-only test command and its label.
Update AI documentation and runtime workflow
AGENTS.md, docs/src/content/docs/docs/*.md
Documents pnpm run obsidian:e2e usage and clarifies maxChunkTokens behavior for chunkedPrompt().

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

Sequence Diagram(s)

sequenceDiagram
  participant Macro
  participant MacroChoiceEngine
  participant RetiredTypeLookup
  participant PackagePreview
  Macro->>MacroChoiceEngine: execute legacy InfiniteAIAssistant
  MacroChoiceEngine->>RetiredTypeLookup: describeUnknownType
  RetiredTypeLookup-->>MacroChoiceEngine: retired command message
  PackagePreview->>PackagePreview: classify legacy type as unknown-command
Loading

Possibly related PRs

Poem

A rabbit watched the old type fade,
Its modal packed and neatly laid.
“Retired,” said QuickAdd, clear and bright,
While chunks found their documented light.
Hop, hop—the workflow’s right!

🚥 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 The title accurately summarizes the main change: removing the unreachable InfiniteAIAssistant command type.
Linked Issues check ✅ Passed The PR removes the dead command type and handles legacy data honestly at runtime, matching #1571's requested direction.
Out of Scope Changes check ✅ Passed The changes stay focused on removing InfiniteAIAssistant and related docs, tests, and runtime handling, with no clear unrelated additions.
✨ Finishing Touches 💡 1
📝 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

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.

@cloudflare-workers-and-pages

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

Copy link
Copy Markdown

Deploying quickadd with  Cloudflare Pages  Cloudflare Pages

Latest commit: 186f97d
Status: ✅  Deploy successful!
Preview URL: https://ddc71bb2.quickadd.pages.dev
Branch Preview URL: https://chhoumann-1571-remove-infini.quickadd.pages.dev

View logs

@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 `@src/ai/modelRefPinning.ts`:
- Line 13: The model-mutation paths need regression coverage for legacy
"InfiniteAIAssistant" commands. Add tests for pinAiCommandModelRefs in
src/ai/modelRefPinning.ts and refreshStaleDefaultModelSeeds in
src/migrations/refreshStaleDefaultModelSeeds.ts confirming legacy records remain
unchanged, then run pnpm run test.
🪄 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: 97466738-b081-44eb-a93c-2d67008f381f

📥 Commits

Reviewing files that changed from the base of the PR and between 1a864fa and 40b3ed5.

📒 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/gui/MacroGUIs/AIAssistantInfiniteCommandSettingsModal.test.ts
  • src/commandLabels.ts
  • src/ai/aiHelpers.maxChunkTokens.test.ts
  • src/types/macros/QuickCommands/IAIAssistantCommand.ts
  • src/gui/PackageManager/MacroDisclosure.svelte
  • src/main.commandLabels.test.ts
  • src/gui/MacroGUIs/AIAssistantInfiniteCommandSettingsModal.ts
  • src/ai/aiHelpers.ts
  • src/main.ts

Comment thread src/ai/modelRefPinning.ts
… alone

Removing the type deliberately ships no migration, so `pinAiCommandModelRefs`
and `refreshStaleDefaultModelSeeds` have to leave an "InfiniteAIAssistant"
step exactly as the user's data.json has it. Both lost their clause for it
with no test failing; re-adding either clause now fails these two.

It matters beyond the migration run: pinAiCommandModelRefs also runs on
package import, so it meets this shape long after the one-time migration is
flagged done.

@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.

🧹 Nitpick comments (1)
src/migrations/refreshStaleDefaultModelSeeds.test.ts (1)

278-301: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Assert that the legacy discriminator is preserved.

This test claims the command is unchanged, but storedAICommand() exposes only model and modelParameters. A migration that rewrites type would still pass. Include type in the helper result and assert it remains "InfiniteAIAssistant".

🤖 Prompt for 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.

In `@src/migrations/refreshStaleDefaultModelSeeds.test.ts` around lines 278 - 301,
Update storedAICommand() to expose the command’s type discriminator, then extend
the “does not touch a legacy InfiniteAIAssistant command” test to assert it
remains "InfiniteAIAssistant" after
refreshStaleDefaultModelSeeds.migrate(mockPlugin).
🤖 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.

Nitpick comments:
In `@src/migrations/refreshStaleDefaultModelSeeds.test.ts`:
- Around line 278-301: Update storedAICommand() to expose the command’s type
discriminator, then extend the “does not touch a legacy InfiniteAIAssistant
command” test to assert it remains "InfiniteAIAssistant" after
refreshStaleDefaultModelSeeds.migrate(mockPlugin).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 071ae883-b753-48e4-8cd2-fb4b83875f7f

📥 Commits

Reviewing files that changed from the base of the PR and between 40b3ed5 and 186f97d.

📒 Files selected for processing (2)
  • src/migrations/pinAiModelRefs.test.ts
  • src/migrations/refreshStaleDefaultModelSeeds.test.ts

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.

[BUG] The InfiniteAIAssistant command type is unreachable, unconfigurable, and silently skipped at run time

1 participant