Skip to content

feat(ocr): integrate Light-OCR#2005

Merged
yyhhyyyyyy merged 34 commits into
devfrom
feat/light-ocr-integration
Jul 23, 2026
Merged

feat(ocr): integrate Light-OCR#2005
yyhhyyyyyy merged 34 commits into
devfrom
feat/light-ocr-integration

Conversation

@yyhhyyyyyy

@yyhhyyyyyy yyhhyyyyyy commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

Integrate @arcships/light-ocr into DeepChat to provide fully offline OCR for image attachments, especially when the selected model does not support vision.

What changed

  • Add main-owned attachment capability routing for vision and non-vision models.
  • Add Auto, Send image and Use OCR text attachment preferences.
  • Persist the exact attachment representation sent to the model.
  • Reuse OCR snapshots for history, retry, edit and compaction.
  • Add submission-scoped OCR preparation cancellation.
  • Preserve Composer drafts across cancellation, failure and session switching.
  • Add encrypted derived OCR caching with TTL, LRU GC and singleflight.
  • Add OCR runtime status, backend selection and cache controls.
  • Localize OCR flows across all 20 shipped locales.

Runtime and packaging

  • Pin @arcships/light-ocr@0.3.4.
  • Pin model bundle ppocrv6-small-native-20260719.1.
  • Run OCR in bundled Node 24.14.1.
  • Verify the Node executable version and SHA-256 during install, afterPack and packaged smoke.
  • Bundle all OCR assets for completely offline use.
  • Support macOS arm64/x64, Windows x64 and Linux x64.
  • Keep Windows arm64 and Linux arm64 explicitly unavailable until compatible upstream assets pass packaged smoke.

Safety and reliability

  • Treat OCR text as untrusted user attachment data.
  • Bound and truncate OCR text before persistence and provider input.
  • Never log OCR text, source paths or content hashes.
  • Launch the helper with a minimal environment allowlist.
  • Run packaged smoke under OS-level network isolation.
  • Ensure preparation cancellation never stops unrelated generation.
  • Safely degrade malformed or legacy attachment metadata.

Scope

Included:

  • Chat user image attachments.
  • Direct send, new thread, queue, steer, remote, retry and compaction.
  • Offline packaged OCR runtime.
  • Runtime observability and cache management.

Not included:

  • Scanned PDF OCR.
  • Knowledge-base image ingestion.
  • MCP, tool or generated images.
  • Automatic model switching.
  • Runtime model downloads.
  • OCR language selection.

Validation

  • Main: 4,477 tests passed, 230 skipped.
  • Renderer: 1,400 tests passed.
  • The remaining 15 renderer failures are pre-existing App.startup.test.ts mock failures outside this diff.
  • Typecheck, i18n, lint, format check and production build passed.
  • macOS arm64 packaged OCR passed with network access denied.
  • Cold recognition: approximately 1.67 seconds.
  • Warm recognition: approximately 27 milliseconds.
  • Peak helper RSS: 509.94 MiB.
  • macOS arm64 zip increase: 65.12 MiB, below the 90 MiB budget.
  • Cross-platform packaged workflows are configured for macOS x64, Windows x64 and Linux x64.

Summary by CodeRabbit

  • New Features
    • Added offline OCR for image attachments, including auto-extraction for non-vision models and send-mode selection (image / OCR text / send without image content).
    • Added an OCR settings page with runtime availability, engine details, and derived OCR cache management (including clearing).
    • Added OCR previews plus blocked/unavailable attachment UI with retry, fallback, and optional model switching.
    • Added submission and attachment-preparation cancellation support.
  • Bug Fixes
    • Improved search, tape recall, and exports to include OCR-derived text.
    • Strengthened packaged OCR integrity verification and introduced installer size regression enforcement for more reliable releases.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds an offline Light OCR attachment pipeline: a helper process/protocol, extraction service, encrypted cache, and capability router, integrated into session/turn coordination, attachment preflight/blocking UI, OCR settings, CI packaging/size gates, shared contracts, and full localization. It also refreshes the ACP registry and model catalog (unrelated).

Changes

Offline Light OCR Attachment Integration

Layer / File(s) Summary
Docs & specs
docs/features/light-ocr-integration/*, docs/issues/light-ocr-follow-up-hardening/spec.md
Adds plan, spec, tasks, and deferred-hardening documentation for the OCR feature.
CI/CD & packaging config
.github/actions/light-ocr-package-size/action.yml, .github/workflows/build.yml, .github/workflows/release.yml, electron-builder.yml, electron.vite.config.ts, package.json, resources/light-ocr-size-budgets.json, resources/runtime-versions.json, tsconfig.node.json, scripts/apple-notarization.js, scripts/notarize-dmg.js, scripts/notarize.js
Adds size-budget enforcement action, network-isolated smoke verification steps, token/permission hardening, packaging config for the OCR helper/native module, DMG notarization hardening, and pinned runtime manifests.
Runtime install & packaging scripts
scripts/install-runtime.mjs, scripts/afterPack.js, scripts/compare-light-ocr-package-size.mjs, scripts/smoke-light-ocr.js, src/main/ocr/lightOcrNativePayload.ts, test/fixtures/light-ocr/*, test/main/scripts/*, test/main/ocr/lightOcrNativePayload.test.ts
Implements runtime installation, OCR asset packaging/verification and native payload materialization, size comparison, and packaged smoke-testing plus fixtures/tests.
Shared attachment types & contracts
src/shared/types/attachment.ts, src/shared/contracts/*, src/shared/utils/attachmentRepresentation.ts, src/shared/settingsNavigation.ts, test/main/shared/*
Defines attachment representation/preparation types, Zod route/settings contracts, and normalization helpers.
OCR core engine & capability router
src/main/ocr/*, test/main/ocr/*
Implements the protocol, helper/process host, image preprocessing, extraction service, artifact cache, scheduler, asset resolver/service, settings, routes, and attachment capability router.
Session/turn coordinator & pending-input integration
src/main/agent/*, src/main/session/*, src/main/app/*, test/main/agent/*, test/main/session/*, test/main/routes/*
Wires attachment preflight into turn coordination, chat service, session lifecycle/routes, blocked pending-input persistence, and submission cancellation.
Context builder, exporter, transcript & tape integration
src/main/agent/deepchat/runtime/contextBuilder.ts, src/main/exporter/*, src/main/session/data/transcript.ts, src/main/tape/*, src/main/remote/*, src/main/lightOcrHelperEntry.ts
Materializes resolved OCR/image representations into model context, exports, search text, and tape recall.
Renderer API clients
src/renderer/api/*
Adds OCR client and submission cancellation/blocked-resolution support to chat/session clients.
Renderer OCR settings UI
src/renderer/settings/components/OcrSettings.vue, src/renderer/settings/settingsRouteComponents.ts
Adds the OCR automation/backend/cache management settings page.
Renderer composer/attachment UI components
src/renderer/src/components/chat/*, src/shadcn/components/ui/dropdown-menu/DropdownMenuContent.vue, src/renderer/src/lib/errors.ts
Adds attachment-preparation dialog, OCR badges/preview, editable input states, and blocked-lane actions.
Composer submit & session store logic
src/renderer/src/features/chat-page/*, src/renderer/src/pages/NewThreadPage.vue, src/renderer/src/stores/ui/*
Reworks submission dispatch/draft state, retry fallback, and pending-input/session store behavior.
i18n translations
src/renderer/src/i18n/*/chat.json, .../routes.json, .../settings.json
Adds localized strings for attachment representation and OCR settings across all locales.

Unrelated ACP Registry & Model Catalog Refresh

Layer / File(s) Summary
Registry & model catalog updates
resources/acp-registry/registry.json, resources/model-db/providers.json
Bumps ACP agent versions/artifacts and refreshes model catalog entries.

Estimated code review effort: 5 (Critical) | ~180 minutes

Possibly related PRs

Suggested reviewers: zhangmo8, zerob13

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: integrating Light-OCR into the product.
✨ 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 feat/light-ocr-integration

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 13

🧹 Nitpick comments (5)
src/renderer/src/components/chat/nodes/fileAttachment.ts (1)

41-46: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Validate parsed requestedRepresentation with the shared normalizer.

parseHTML only defaults to 'auto' when the attribute is missing, not when it holds an invalid value. normalizeAttachmentRepresentationPreference (src/shared/utils/attachmentRepresentation.ts) already exists to validate/coerce this exact preference and is presumably relied on elsewhere in the attachment contract chain; using it here keeps deserialized HTML consistent with the rest of the pipeline.

♻️ Proposed fix
+import { normalizeAttachmentRepresentationPreference } from '`@shared/utils/attachmentRepresentation`'
...
       requestedRepresentation: {
         default: 'auto',
-        parseHTML: (el) => el.getAttribute('data-requested-representation') || 'auto',
+        parseHTML: (el) =>
+          normalizeAttachmentRepresentationPreference(
+            el.getAttribute('data-requested-representation')
+          ) ?? 'auto',
         renderHTML: (attrs) => ({
           'data-requested-representation': attrs.requestedRepresentation
         })
       }
🤖 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/renderer/src/components/chat/nodes/fileAttachment.ts` around lines 41 -
46, Update the requestedRepresentation parseHTML handler in the attachment node
to pass the retrieved data-requested-representation value through
normalizeAttachmentRepresentationPreference, preserving 'auto' as the fallback
for missing or invalid values. Keep renderHTML unchanged.
test/main/session/chatService.test.ts (1)

178-281: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Submission-scoped abort is tested for sendMessage but not for steerActiveTurn.

L208-247 only covers stopStream-triggered abort for steerActiveTurn; L249-281 covers submission-scoped AbortController abort, but only for sendMessage. Consider adding an analogous submission-scoped-abort test for steerActiveTurn to confirm it doesn't inadvertently cancel generation/session permissions either.

🤖 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 `@test/main/session/chatService.test.ts` around lines 178 - 281, Add a
submission-scoped AbortController test for steerActiveTurn, analogous to the
existing sendMessage test. Keep the steer operation pending until the supplied
signal aborts, then assert it rejects with AbortError without calling
turn.cancelGeneration or sessionPermissionPort.clearSessionPermissions.
test/main/routes/dispatcher.test.ts (2)

4255-4323: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Renderer-ownership cancellation coverage exists only for chat.sendMessage.

This is a strong regression test for a real authorization boundary (blocking cross-renderer cancellation), but there's no analogous test exercising chat.cancelSubmission against an in-flight chat.steerActiveTurn or sessions.retryMessage attachment preflight, even though both now surface attachmentPreparation/blocking behavior in this same file. Consider extending this pattern to those two paths.

🤖 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 `@test/main/routes/dispatcher.test.ts` around lines 4255 - 4323, Extend the
renderer-ownership cancellation coverage from the existing chat.sendMessage test
to both in-flight chat.steerActiveTurn and sessions.retryMessage
attachment-preflight flows. For each path, await the preflight becoming blocked,
verify chat.cancelSubmission from a different renderer returns { cancelled:
false } without aborting it, then verify cancellation from the owning renderer
succeeds and the operation rejects with AbortError; preserve the existing
post-cancellation false result.

1-1: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Submission-scoped cancellation is only fully tested for chat.sendMessage, not steerActiveTurn. Both files establish a solid pattern for verifying the new abort/attachment-preflight semantics, but the pattern isn't extended to the steer path at either layer.

  • test/main/routes/dispatcher.test.ts#L4255-4323: add an analogous renderer-ownership chat.cancelSubmission test for an in-flight chat.steerActiveTurn (and ideally sessions.retryMessage, pending the separate signal-wiring verification) attachment preflight.
  • test/main/session/chatService.test.ts#L178-281: add a submission-scoped AbortController abort test for steerActiveTurn (mirroring the existing sendMessage test at L249-281), distinct from the already-covered stopStream-triggered abort at L208-247.
🤖 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 `@test/main/routes/dispatcher.test.ts` at line 1, Extend the existing
cancellation coverage to steerActiveTurn: in the dispatcher tests, add a
renderer-ownership chat.cancelSubmission case for an in-flight steerActiveTurn
attachment preflight, preserving the established sendMessage pattern; in
chatService tests, add a submission-scoped AbortController abort test for
steerActiveTurn, separate from the stopStream-triggered abort coverage. Also
apply the analogous renderer test to sessions.retryMessage if its signal wiring
is available.
test/main/session/data/tables/deepchatPendingInputsTable.test.ts (1)

157-183: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add a negative-case test for invalid/forged resolvedRepresentation.

This test only verifies the happy path where a valid resolvedRepresentation is preserved. Given attachment data is treated as untrusted (per PR objectives) and this is the boundary where renderer-supplied payloads enter persisted pending-input state, add a companion case asserting that a forged/invalid resolvedRepresentation (e.g., unexpected kind, extra fields, or a fake kind: 'image' used to bypass OCR) is rejected or stripped, mirroring how test 6 (lines 134-155) verifies blocking metadata is sanitized.

🤖 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 `@test/main/session/data/tables/deepchatPendingInputsTable.test.ts` around
lines 157 - 183, Add a companion negative-case test near the existing valid
snapshot test for createQueueInput, supplying a forged or invalid
resolvedRepresentation such as an unsupported kind or fake image representation
with extra fields. Assert that the persisted pending payload rejects or strips
the invalid representation, matching the sanitization expectations established
by test 6.
🤖 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 `@resources/model-db/providers.json`:
- Line 260229: Update the context value for the Meituan: LongCat 2.0 provider
entry from 1048756 to 1048576 in providers.json, leaving all other provider
configuration unchanged.
- Around line 236569-236573: The gemini-3.6-flash pricing entry has an incorrect
cache_read value. In its cost object, update cache_read from 1.5 to 0.15 while
preserving the input and output values.
- Around line 259585-259661: Update the `type` field in both OpenRouter entries,
`google/gemini-3.5-flash-lite` and `google/gemini-3.6-flash`, from
`imageGeneration` to `chat`; leave their existing modalities, reasoning, limits,
and other capabilities unchanged.

In `@src/main/agent/deepchat/runtime/contextBuilder.ts`:
- Around line 407-428: Update buildResolvedImageRepresentationContext to inspect
the ocr_text representation’s truncated flag and append a clear truncation note
to the generated OCR context when it is true. Preserve the existing unavailable,
empty-text, escaping, metadata, and non-truncated output behavior.
- Around line 430-432: Update escapeUntrustedOcrBlockDelimiters to escape every
angle bracket in the input, rather than pattern-matching only untrusted_ocr_data
tags. Ensure both “<” and “>” are encoded so any OCR text resembling an
HTML-like delimiter cannot bypass the trust boundary.

In `@src/main/ocr/ocrRuntimeAssetResolver.ts`:
- Around line 256-262: Update the escape guard in the runtime asset path
validation to also reject the exact parent-relative value (`relative === '..'`),
while preserving the existing checks for empty, nested-parent, and absolute
paths. Keep the change scoped to the validation logic surrounding `resolvedRoot`
and `resolvedPath`.

In `@src/main/session/data/pendingInputStore.ts`:
- Around line 145-154: Update updateQueueInput to validate the current row.state
before writing payload_json, matching the state-guard behavior of the sibling
mutators. Reject claimed or otherwise non-editable states before mutation, while
preserving the existing blocked-to-pending reset and normal update behavior for
allowed states.

In `@src/main/session/turn.ts`:
- Around line 281-287: In the ACP branch of the turn handling flow, move
commitRetryMessage so it runs only after runtime.send completes successfully.
Preserve the existing sessionId and prepared.sourceOrderSeq arguments, and
ensure send errors propagate without committing or deleting the prior
transcript.

In `@src/renderer/settings/components/OcrSettings.vue`:
- Line 256: Update the status polling error handling around statusErrorNotified
and the logic near status.value so failures after a prior successful poll are
surfaced instead of remaining silent; preserve deduplication by notifying only
on the first failure in each failure period, and reset that failure state when a
subsequent poll succeeds. Ensure the status card no longer presents stale
available data without an indication of polling failure.

In `@src/renderer/src/components/chat/ChatInputBox.vue`:
- Around line 558-563: Update handleKeydown so the non-editable guard does not
prevent Tab navigation or standard copy/select-all shortcuts (Ctrl/Cmd+Tab,
Ctrl/Cmd+C, and Ctrl/Cmd+A as applicable); allow those key-specific paths to
execute before returning for other editing commands. Preserve the existing
prevention behavior for actions that modify the draft while props.editable is
false.

In `@src/renderer/src/components/message/MessageItemUser.vue`:
- Around line 256-263: Update messageFileByKey and its fallback lookup in
MessageItemUser so exact file paths remain uniquely mapped, while basename
matching is only used when exactly one attachment has that name. Do not
overwrite basename candidates when duplicates exist; treat ambiguous names as
unmatched so inline blocks cannot receive incorrect file metadata or OCR
content.

In `@src/renderer/src/i18n/he-IL/chat.json`:
- Line 431: Update the Hebrew translations for image_limit_exceeded and the
corresponding message at line 440 to replace התור with a term clearly meaning
the current turn or round, while preserving the existing message meaning and
formatting.

In `@test/main/ocr/ocrArtifactStore.test.ts`:
- Around line 15-26: Ensure encrypted persistence tests cannot be silently
skipped in required CI: update the OCR artifact store test setup around
sqliteAvailable and persistentIt to honor DEEPCHAT_REQUIRE_NATIVE_SQLITE,
failing when the flag is set but better-sqlite3-multiple-ciphers is unavailable;
also configure that environment variable for the CI command running these tests
if needed.

---

Nitpick comments:
In `@src/renderer/src/components/chat/nodes/fileAttachment.ts`:
- Around line 41-46: Update the requestedRepresentation parseHTML handler in the
attachment node to pass the retrieved data-requested-representation value
through normalizeAttachmentRepresentationPreference, preserving 'auto' as the
fallback for missing or invalid values. Keep renderHTML unchanged.

In `@test/main/routes/dispatcher.test.ts`:
- Around line 4255-4323: Extend the renderer-ownership cancellation coverage
from the existing chat.sendMessage test to both in-flight chat.steerActiveTurn
and sessions.retryMessage attachment-preflight flows. For each path, await the
preflight becoming blocked, verify chat.cancelSubmission from a different
renderer returns { cancelled: false } without aborting it, then verify
cancellation from the owning renderer succeeds and the operation rejects with
AbortError; preserve the existing post-cancellation false result.
- Line 1: Extend the existing cancellation coverage to steerActiveTurn: in the
dispatcher tests, add a renderer-ownership chat.cancelSubmission case for an
in-flight steerActiveTurn attachment preflight, preserving the established
sendMessage pattern; in chatService tests, add a submission-scoped
AbortController abort test for steerActiveTurn, separate from the
stopStream-triggered abort coverage. Also apply the analogous renderer test to
sessions.retryMessage if its signal wiring is available.

In `@test/main/session/chatService.test.ts`:
- Around line 178-281: Add a submission-scoped AbortController test for
steerActiveTurn, analogous to the existing sendMessage test. Keep the steer
operation pending until the supplied signal aborts, then assert it rejects with
AbortError without calling turn.cancelGeneration or
sessionPermissionPort.clearSessionPermissions.

In `@test/main/session/data/tables/deepchatPendingInputsTable.test.ts`:
- Around line 157-183: Add a companion negative-case test near the existing
valid snapshot test for createQueueInput, supplying a forged or invalid
resolvedRepresentation such as an unsupported kind or fake image representation
with extra fields. Assert that the persisted pending payload rejects or strips
the invalid representation, matching the sanitization expectations established
by test 6.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: ee0267a3-1fb3-4f16-b76a-a4ee94389d34

📥 Commits

Reviewing files that changed from the base of the PR and between 2f6852b and 420027e.

⛔ Files ignored due to path filters (2)
  • src/renderer/src/lib/icons/icon-collections.generated.ts is excluded by !**/*.generated.*
  • src/renderer/src/lib/icons/icon-whitelist.generated.ts is excluded by !**/*.generated.*
📒 Files selected for processing (234)
  • .github/actions/light-ocr-package-size/action.yml
  • .github/workflows/build.yml
  • .github/workflows/release.yml
  • docs/features/light-ocr-integration/plan.md
  • docs/features/light-ocr-integration/spec.md
  • docs/features/light-ocr-integration/tasks.md
  • docs/issues/light-ocr-follow-up-hardening/spec.md
  • electron-builder.yml
  • electron.vite.config.ts
  • package.json
  • resources/acp-registry/registry.json
  • resources/light-ocr-size-budgets.json
  • resources/model-db/providers.json
  • resources/runtime-versions.json
  • scripts/afterPack.js
  • scripts/compare-light-ocr-package-size.mjs
  • scripts/install-runtime.mjs
  • scripts/smoke-light-ocr.js
  • src/main/agent/deepchat/runtime/contextBuilder.ts
  • src/main/agent/deepchat/runtime/deepChatRuntimeCoordinator.ts
  • src/main/agent/deepchat/runtime/turnCoordinator.ts
  • src/main/agent/manager/deepChatAgentBackend.ts
  • src/main/agent/manager/directAcpAgentBackend.ts
  • src/main/agent/manager/sessionHandles.ts
  • src/main/agent/shared/agentSessionHandle.ts
  • src/main/agent/shared/agentSessionNormalization.ts
  • src/main/app/composition.ts
  • src/main/app/settingsRoutes.ts
  • src/main/data/databaseConnection.ts
  • src/main/data/schemaCatalog.ts
  • src/main/exporter/agentSessionExporter.ts
  • src/main/exporter/formats/conversationExporter.ts
  • src/main/exporter/formats/nowledgeMemExporter.ts
  • src/main/exporter/formats/userMessageText.ts
  • src/main/lightOcrHelperEntry.ts
  • src/main/ocr/attachmentCapabilityRouter.ts
  • src/main/ocr/imagePreprocessor.ts
  • src/main/ocr/imageTextExtractionService.ts
  • src/main/ocr/lightOcrHelper.ts
  • src/main/ocr/lightOcrProcessHost.ts
  • src/main/ocr/lightOcrProtocol.ts
  • src/main/ocr/ocrArtifactStore.ts
  • src/main/ocr/ocrCacheKeyProvider.ts
  • src/main/ocr/ocrExtractionScheduler.ts
  • src/main/ocr/ocrRuntimeAssetResolver.ts
  • src/main/ocr/ocrRuntimeService.ts
  • src/main/ocr/ocrSettings.ts
  • src/main/ocr/routes.ts
  • src/main/remote/conversation/runner.ts
  • src/main/session/chatService.ts
  • src/main/session/contracts.ts
  • src/main/session/data/contracts.ts
  • src/main/session/data/pendingInputStore.ts
  • src/main/session/data/pendingInputs.ts
  • src/main/session/data/tables/deepchatPendingInputs.ts
  • src/main/session/data/transcript.ts
  • src/main/session/data/userMessageContent.ts
  • src/main/session/lifecycle.ts
  • src/main/session/routes.ts
  • src/main/session/sessionService.ts
  • src/main/session/submissionCancellationRegistry.ts
  • src/main/session/transcriptMutations.ts
  • src/main/session/turn.ts
  • src/main/tape/application/recallProjection.ts
  • src/main/tape/application/recallService.ts
  • src/main/tape/infrastructure/sqlite/tapeSearchProjectionStore.ts
  • src/renderer/api/ChatClient.ts
  • src/renderer/api/OcrClient.ts
  • src/renderer/api/SessionClient.ts
  • src/renderer/settings/components/OcrSettings.vue
  • src/renderer/settings/settingsRouteComponents.ts
  • src/renderer/src/components/chat/AttachmentPreparationDialog.vue
  • src/renderer/src/components/chat/ChatAttachmentItem.vue
  • src/renderer/src/components/chat/ChatInputBox.vue
  • src/renderer/src/components/chat/ChatInputToolbar.vue
  • src/renderer/src/components/chat/ChatStatusBar.vue
  • src/renderer/src/components/chat/PendingInputLane.vue
  • src/renderer/src/components/chat/composables/useChatInputFiles.ts
  • src/renderer/src/components/chat/nodes/FileAttachmentView.vue
  • src/renderer/src/components/chat/nodes/fileAttachment.ts
  • src/renderer/src/components/chat/nodes/symbols.ts
  • src/renderer/src/components/message/MessageContent.vue
  • src/renderer/src/components/message/MessageItemUser.vue
  • src/renderer/src/features/chat-page/ChatPage.vue
  • src/renderer/src/features/chat-page/composables/useComposerSubmit.ts
  • src/renderer/src/features/chat-page/composables/useMessageActions.ts
  • src/renderer/src/features/chat-page/composables/usePendingInputActions.ts
  • src/renderer/src/features/chat-page/model/composerDraftState.ts
  • src/renderer/src/features/chat-page/model/displayMessage.ts
  • src/renderer/src/i18n/da-DK/chat.json
  • src/renderer/src/i18n/da-DK/routes.json
  • src/renderer/src/i18n/da-DK/settings.json
  • src/renderer/src/i18n/de-DE/chat.json
  • src/renderer/src/i18n/de-DE/routes.json
  • src/renderer/src/i18n/de-DE/settings.json
  • src/renderer/src/i18n/en-US/chat.json
  • src/renderer/src/i18n/en-US/routes.json
  • src/renderer/src/i18n/en-US/settings.json
  • src/renderer/src/i18n/es-ES/chat.json
  • src/renderer/src/i18n/es-ES/routes.json
  • src/renderer/src/i18n/es-ES/settings.json
  • src/renderer/src/i18n/fa-IR/chat.json
  • src/renderer/src/i18n/fa-IR/routes.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/fr-FR/chat.json
  • src/renderer/src/i18n/fr-FR/routes.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/i18n/he-IL/chat.json
  • src/renderer/src/i18n/he-IL/routes.json
  • src/renderer/src/i18n/he-IL/settings.json
  • src/renderer/src/i18n/id-ID/chat.json
  • src/renderer/src/i18n/id-ID/routes.json
  • src/renderer/src/i18n/id-ID/settings.json
  • src/renderer/src/i18n/it-IT/chat.json
  • src/renderer/src/i18n/it-IT/routes.json
  • src/renderer/src/i18n/it-IT/settings.json
  • src/renderer/src/i18n/ja-JP/chat.json
  • src/renderer/src/i18n/ja-JP/routes.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/ko-KR/chat.json
  • src/renderer/src/i18n/ko-KR/routes.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/ms-MY/chat.json
  • src/renderer/src/i18n/ms-MY/routes.json
  • src/renderer/src/i18n/ms-MY/settings.json
  • src/renderer/src/i18n/pl-PL/chat.json
  • src/renderer/src/i18n/pl-PL/routes.json
  • src/renderer/src/i18n/pl-PL/settings.json
  • src/renderer/src/i18n/pt-BR/chat.json
  • src/renderer/src/i18n/pt-BR/routes.json
  • src/renderer/src/i18n/pt-BR/settings.json
  • src/renderer/src/i18n/ru-RU/chat.json
  • src/renderer/src/i18n/ru-RU/routes.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/tr-TR/chat.json
  • src/renderer/src/i18n/tr-TR/routes.json
  • src/renderer/src/i18n/tr-TR/settings.json
  • src/renderer/src/i18n/vi-VN/chat.json
  • src/renderer/src/i18n/vi-VN/routes.json
  • src/renderer/src/i18n/vi-VN/settings.json
  • src/renderer/src/i18n/zh-CN/chat.json
  • src/renderer/src/i18n/zh-CN/routes.json
  • src/renderer/src/i18n/zh-CN/settings.json
  • src/renderer/src/i18n/zh-HK/chat.json
  • src/renderer/src/i18n/zh-HK/routes.json
  • src/renderer/src/i18n/zh-HK/settings.json
  • src/renderer/src/i18n/zh-TW/chat.json
  • src/renderer/src/i18n/zh-TW/routes.json
  • src/renderer/src/i18n/zh-TW/settings.json
  • src/renderer/src/lib/errors.ts
  • src/renderer/src/pages/NewThreadPage.vue
  • src/renderer/src/stores/ui/attachmentPreparation.ts
  • src/renderer/src/stores/ui/pendingInput.ts
  • src/renderer/src/stores/ui/session.ts
  • src/shadcn/components/ui/dropdown-menu/DropdownMenuContent.vue
  • src/shared/chat.d.ts
  • src/shared/contracts/common.ts
  • src/shared/contracts/domainSchemas.ts
  • src/shared/contracts/events/settings.events.ts
  • src/shared/contracts/routes.ts
  • src/shared/contracts/routes/chat.routes.ts
  • src/shared/contracts/routes/ocr.routes.ts
  • src/shared/contracts/routes/sessions.routes.ts
  • src/shared/contracts/routes/settings.routes.ts
  • src/shared/contracts/routes/system.routes.ts
  • src/shared/settingsNavigation.ts
  • src/shared/types/agent-interface.d.ts
  • src/shared/types/attachment.ts
  • src/shared/types/core/chat.ts
  • src/shared/utils/attachmentRepresentation.ts
  • test/fixtures/light-ocr/fake-helper.mjs
  • test/main/agent/deepchat/runtime/contextBuilder.test.ts
  • test/main/agent/deepchat/runtime/deepChatRuntimeCoordinator.test.ts
  • test/main/agent/manager/deepChatAgentBackend.test.ts
  • test/main/agent/manager/directAcpAgentBackend.test.ts
  • test/main/data/databaseConnection.test.ts
  • test/main/exporter/agentSessionExporter.test.ts
  • test/main/memory/memoryNativeMigration.test.ts
  • test/main/ocr/attachmentCapabilityRouter.test.ts
  • test/main/ocr/imagePreprocessor.test.ts
  • test/main/ocr/imageTextExtractionService.test.ts
  • test/main/ocr/lightOcrHelper.test.ts
  • test/main/ocr/lightOcrProcessHost.test.ts
  • test/main/ocr/ocrArtifactStore.test.ts
  • test/main/ocr/ocrCacheKeyProvider.test.ts
  • test/main/ocr/ocrExtractionScheduler.test.ts
  • test/main/ocr/ocrRuntimeAssetResolver.test.ts
  • test/main/ocr/ocrRuntimeService.test.ts
  • test/main/ocr/ocrSettings.test.ts
  • test/main/ocr/routes.test.ts
  • test/main/remote/remoteConversationRunner.test.ts
  • test/main/routes/contracts.test.ts
  • test/main/routes/dispatcher.test.ts
  • test/main/scripts/afterPack.test.ts
  • test/main/scripts/installRuntime.test.ts
  • test/main/scripts/lightOcrPackageSize.test.ts
  • test/main/scripts/smokeLightOcr.test.ts
  • test/main/session/assignmentPolicy.test.ts
  • test/main/session/chatService.test.ts
  • test/main/session/data/pendingInputStore.test.ts
  • test/main/session/data/pendingInputs.test.ts
  • test/main/session/data/tables/deepchatPendingInputsTable.test.ts
  • test/main/session/data/tapeRecall.test.ts
  • test/main/session/data/transcript.test.ts
  • test/main/session/lifecycle.test.ts
  • test/main/session/runtimeIntegration.test.ts
  • test/main/session/session.integration.test.ts
  • test/main/session/sessionFixture.ts
  • test/main/session/submissionCancellationRegistry.test.ts
  • test/main/session/transcriptMutations.test.ts
  • test/main/session/turn.test.ts
  • test/main/shared/attachmentRepresentation.test.ts
  • test/main/shared/settingsNavigation.test.ts
  • test/renderer/api/clients.test.ts
  • test/renderer/components/AttachmentPreparationDialog.test.ts
  • test/renderer/components/ChatAttachmentItem.test.ts
  • test/renderer/components/ChatInputBox.test.ts
  • test/renderer/components/ChatInputToolbar.test.ts
  • test/renderer/components/ChatPage.test.ts
  • test/renderer/components/DropdownMenuContent.test.ts
  • test/renderer/components/NewThreadPage.onboarding.test.ts
  • test/renderer/components/NewThreadPage.test.ts
  • test/renderer/components/OcrSettings.test.ts
  • test/renderer/components/PendingInputLane.test.ts
  • test/renderer/components/useChatInputFiles.test.ts
  • test/renderer/features/chat-page/composables/useComposerSubmit.test.ts
  • test/renderer/features/chat-page/composables/useMessageActions.test.ts
  • test/renderer/features/chat-page/composables/usePendingInputActions.test.ts
  • test/renderer/features/chat-page/model/composerDraftState.test.ts
  • test/renderer/lib/errors.test.ts
  • test/renderer/pages/NewThreadPage.test.ts
  • test/renderer/stores/attachmentPreparationStore.test.ts
  • test/renderer/stores/sessionStore.test.ts
  • tsconfig.node.json

Comment thread resources/model-db/providers.json
Comment thread resources/model-db/providers.json
Comment thread resources/model-db/providers.json
Comment thread src/main/agent/deepchat/runtime/contextBuilder.ts
Comment thread src/main/agent/deepchat/runtime/contextBuilder.ts Outdated
Comment thread src/renderer/settings/components/OcrSettings.vue
Comment thread src/renderer/src/components/chat/ChatInputBox.vue
Comment thread src/renderer/src/components/message/MessageItemUser.vue Outdated
Comment thread src/renderer/src/i18n/he-IL/chat.json Outdated
Comment thread test/main/ocr/ocrArtifactStore.test.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
resources/model-db/providers.json (1)

236574-236580: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Clamp Gemini 3.6 Flash output to 65536
resources/model-db/providers.json:236576-236578 advertises "output": 1048576, but this model’s published max output is 65,536 tokens. That value should be lowered to match the actual limit.

🤖 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 `@resources/model-db/providers.json` around lines 236574 - 236580, Update the
Gemini 3.6 Flash model entry’s limit.output value from 1048576 to 65536, while
leaving its context and tool_call settings unchanged.
🤖 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.

Outside diff comments:
In `@resources/model-db/providers.json`:
- Around line 236574-236580: Update the Gemini 3.6 Flash model entry’s
limit.output value from 1048576 to 65536, while leaving its context and
tool_call settings unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 19abf7c0-bc5f-4a74-8284-a134be85d1f8

📥 Commits

Reviewing files that changed from the base of the PR and between c626f06 and 104d718.

📒 Files selected for processing (15)
  • resources/acp-registry/registry.json
  • resources/model-db/providers.json
  • scripts/afterPack.js
  • scripts/smoke-light-ocr.js
  • src/main/ocr/lightOcrNativePayload.ts
  • src/main/ocr/lightOcrProcessHost.ts
  • src/main/ocr/ocrRuntimeAssetResolver.ts
  • src/main/ocr/ocrRuntimeService.ts
  • test/main/ocr/attachmentCapabilityRouter.test.ts
  • test/main/ocr/lightOcrNativePayload.test.ts
  • test/main/ocr/lightOcrProcessHost.test.ts
  • test/main/ocr/ocrRuntimeAssetResolver.test.ts
  • test/main/ocr/routes.test.ts
  • test/main/scripts/afterPack.test.ts
  • test/main/scripts/smokeLightOcr.test.ts
🚧 Files skipped from review as they are similar to previous changes (8)
  • test/main/ocr/routes.test.ts
  • test/main/ocr/ocrRuntimeAssetResolver.test.ts
  • src/main/ocr/ocrRuntimeService.ts
  • src/main/ocr/ocrRuntimeAssetResolver.ts
  • src/main/ocr/lightOcrProcessHost.ts
  • test/main/scripts/afterPack.test.ts
  • resources/acp-registry/registry.json
  • test/main/ocr/attachmentCapabilityRouter.test.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 `@test/main/scripts/lightOcrPackageSize.test.ts`:
- Around line 94-107: Extend the assertions in the test covering applicationStep
and feishuStep so both unsigned steps are verified not to contain CSC_LINK or
CSC_KEY_PASSWORD. Keep the existing signed cuaStep assertions unchanged.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 83b44083-fcc9-4fdc-818c-9c660367df64

📥 Commits

Reviewing files that changed from the base of the PR and between 104d718 and b4ec8d3.

📒 Files selected for processing (2)
  • .github/actions/light-ocr-package-size/action.yml
  • test/main/scripts/lightOcrPackageSize.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/actions/light-ocr-package-size/action.yml

Comment thread test/main/scripts/lightOcrPackageSize.test.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
resources/model-db/providers.json (1)

260548-260614: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Fix the Gemma model types in resources/model-db/providers.json google/gemma-4-26b-a4b-it, google/gemma-4-26b-a4b-it:free, google/gemma-4-31b-it, and google/gemma-4-31b-it:free are text-only, so type: "imageGeneration" is incorrect here.

🤖 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 `@resources/model-db/providers.json` around lines 260548 - 260614, Update the
provider entries for google/gemma-4-26b-a4b-it, google/gemma-4-26b-a4b-it:free,
google/gemma-4-31b-it, and google/gemma-4-31b-it:free to use the appropriate
text-model type instead of type: "imageGeneration"; preserve their existing text
output and capability metadata.
🤖 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.

Outside diff comments:
In `@resources/model-db/providers.json`:
- Around line 260548-260614: Update the provider entries for
google/gemma-4-26b-a4b-it, google/gemma-4-26b-a4b-it:free,
google/gemma-4-31b-it, and google/gemma-4-31b-it:free to use the appropriate
text-model type instead of type: "imageGeneration"; preserve their existing text
output and capability metadata.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f2f92920-45c6-4610-81cd-5e0feb466c71

📥 Commits

Reviewing files that changed from the base of the PR and between b4ec8d3 and 08f372f.

📒 Files selected for processing (10)
  • docs/features/light-ocr-integration/plan.md
  • docs/features/light-ocr-integration/spec.md
  • docs/features/light-ocr-integration/tasks.md
  • electron-builder.yml
  • resources/acp-registry/registry.json
  • resources/model-db/providers.json
  • scripts/apple-notarization.js
  • scripts/notarize-dmg.js
  • scripts/notarize.js
  • test/main/scripts/notarizeDmg.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • docs/features/light-ocr-integration/spec.md
  • docs/features/light-ocr-integration/plan.md
  • resources/acp-registry/registry.json

@yyhhyyyyyy
yyhhyyyyyy merged commit 87c1bfc into dev Jul 23, 2026
10 checks passed
@zhangmo8
zhangmo8 deleted the feat/light-ocr-integration branch July 23, 2026 07:21
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