Skip to content

feat(persona): add ambient Buddy stage one - #2817

Open
rmusser01 wants to merge 29 commits into
devfrom
codex/persona-ambient-stage1
Open

feat(persona): add ambient Buddy stage one#2817
rmusser01 wants to merge 29 commits into
devfrom
codex/persona-ambient-stage1

Conversation

@rmusser01

@rmusser01 rmusser01 commented Aug 24, 2026

Copy link
Copy Markdown
Owner

Change summary (human-written)

This PR delivers Stage 1 of the ambient Persona Buddy: a focused Persona can now appear as a calm, idle-only web companion with Off, Expressive, and Roaming modes, global and per-Persona preferences, grounded movement, accessible pointer/keyboard/touch controls, reduced-motion fallbacks, and no runtime model calls. It also adds secure visual-pack rendering and review/activation/fork workflows, hardens pack immutability and state transitions, and includes comprehensive API, engine, UI, and Playwright coverage. This establishes the shared companion engine needed for the later transparent-video creation and import stage.

Validation

  • Tests added/updated for behavior changes

  • Relevant unit/integration tests pass locally

  • Docs updated (if behavior, routes, or config changed)

  • Backend Persona/DB matrix: 358/358

  • Frontend Buddy/editor/services matrix: 255/255

  • Isolated Chromium workflow: 13/13

  • ESLint: 0 errors

  • TypeScript 5.9.3: 0 diagnostics in touched paths (47 unrelated baseline diagnostics)

  • Bandit: 0 findings and 0 errors

  • Final independent review: 0 Critical and 0 Important

UX Audit Checklist (v2 Stage 5)

Not applicable; this change does not target the v2 Stage 5 audit scope.

Watchlists Accessibility Checklist (Group 09 Stage 5)

Not applicable; Watchlists is unchanged.

Watchlists Scale Checklist (Group 10 Stage 5)

Not applicable; Watchlists is unchanged.

Risk & Rollback

  • Risk level: Medium
  • Rollback plan: Revert this PR. The feature remains controlled by the existing Persona Buddy shell and ambient-mode settings; no Stage 2 video runtime is introduced.

Summary by cubic

Adds Stage 1 of the ambient Persona Buddy. Previously the Buddy did nothing while idle; now a deterministic, idle‑only companion runs locally with Off, Expressive, and Roaming modes, per‑Persona/global preferences, secure asset loading, and accessible controls, without model calls or arbitrary network requests.

  • New Features

    • Adds a renderer‑neutral companion engine and usePersonaCompanion to schedule idle variants and bounded horizontal roaming on web.
    • Persists ambient mode globally and per Persona via persona-buddy; UI shows effective mode per surface and coerces sidepanel roaming to Expressive.
    • Secures visual assets with persona-visual-assets (authenticated Blob loader with SHA‑256 verification and caching).
    • Requires explicit visual‑pack review with expected_version, validates companion_behavior, and makes active/archived revisions immutable and fingerprinted.
    • Updates sprite rendering to honor deterministic generations, requested states, and reduced‑motion, and to report asset‑load failures.
    • Roaming is web‑only; unsupported surfaces suspend ambient behavior; reduced‑motion disables animation.
  • Migration

    • DB schema v62 adds companion preferences and review constraints; standard migrations apply, no manual steps.
    • No user migration required; ambient defaults remain safe. Packs must be reviewed and declare companion_behavior to schedule ambient states.

Written for commit 9327166. Summary will update on new commits.

Review in cubic

@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 56161bcf-acb9-498c-8bca-b89f4b2c4413

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add Stage 1 ambient Persona Buddy with preferences and pack review workflows

✨ Enhancement 🧪 Tests 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Introduce idle-only ambient Persona Buddy with Off/Expressive/Roaming modes and accessibility.
• Add global + per-Persona buddy preferences with optimistic concurrency.
• Harden visual-pack lifecycle with review→activate fingerprinting and sealed-pack forking.
• Expand Persona/visual-pack/Chatbooks/media-ingest test coverage and implementation docs.
Diagram

graph TD
  UI["Buddy shell UI"] --> FE(["FE persona services"]) --> API{{"Persona API"}} --> DB[("Persona DB")]
  API --> VIS(["Visual service"]) --> BEH["Behavior validator"]
  UI --> RENDER["Sprite renderer"] --> ASSET(["Asset handle fetch"]) --> API
  subgraph Legend
    direction LR
    _ui["UI"] ~~~ _svc(["Service"]) ~~~ _api{{"API"}} ~~~ _db[("Database")]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use HTTP ETag/If-Match for optimistic concurrency
  • ➕ Standard pattern; removes custom expected_version fields
  • ➕ Potentially reusable across other write endpoints
  • ➖ Still needs a payload fingerprint for review correctness
  • ➖ Requires careful ETag semantics/caching across endpoints
2. Client-only buddy preferences (localStorage only)
  • ➕ Simpler backend; no DB/state store changes
  • ➕ Offline-friendly and instant UI changes
  • ➖ Preferences won’t roam across devices
  • ➖ Harder to keep multiple clients consistent; per-Persona overlays become fragmented
3. Single endpoint for effective mode resolution
  • ➕ Moves effective-mode policy to server, simplifying UI logic
  • ➕ One authoritative decision point for surface limitations (e.g., sidepanel roaming)
  • ➖ Adds extra API round trips or coupling to rendering context
  • ➖ Still requires client-side UX state handling (focus/drag/visibility)

Recommendation: The PR’s approach (explicit version checks for writes + review-bound fingerprint for activation) is the right trade-off for correctness: it prevents stale writes and guarantees that an activated pack exactly matches what was reviewed. Consider ETag/If-Match later as a standardization layer, but keep the fingerprint as the security/integrity primitive.

Files changed (24) +6165 / -490

Enhancement (17) +4363 / -481
BuddyShellDock.tsxRedesign dock as draggable buddy button with hint and controls affordance +122/-46

Redesign dock as draggable buddy button with hint and controls affordance

• Refactors the dock UI into a compact draggable button with visual facing/nudge states, adds a first-use hint, and routes control opening/closing through explicit handlers. Plumbs ambient mode state into the popover and adds richer debug data attributes for companion state.

apps/packages/ui/src/components/Common/PersonaBuddy/BuddyShellDock.tsx

BuddyShellHost.tsxImplement Stage 1 ambient buddy interactions and preference syncing +538/-149

Implement Stage 1 ambient buddy interactions and preference syncing

• Overhauls pointer/keyboard interaction handling (drag, click vs. double-click controls, focus/visibility/viewport tracking, reduced-motion handling). Adds global and per-Persona ambient preference loading and conflict-aware update flows, and integrates companion policy/engine hooks for idle-only behavior.

apps/packages/ui/src/components/Common/PersonaBuddy/BuddyShellHost.tsx

BuddyShellPopover.tsxAdd ambient mode controls (global + per-Persona) and close button +78/-3

Add ambient mode controls (global + per-Persona) and close button

• Adds radio controls for Off/Expressive/Roaming globally and per Persona (including “Use global”), shows the effective mode, and surfaces sidepanel roaming limitation messaging. Adds an explicit close action to improve keyboard/mouse accessibility.

apps/packages/ui/src/components/Common/PersonaBuddy/BuddyShellPopover.tsx

SpriteFrameRenderer.tsxSecure sprite rendering via asset handles with reduced-motion support +135/-22

Secure sprite rendering via asset handles with reduced-motion support

• Switches sprite rendering from direct asset URLs to acquired/released asset handles. Adds generation-aware lifecycle callbacks (ready/failure/complete) and reduced-motion constraints/fallback behavior.

apps/packages/ui/src/components/Common/PersonaBuddy/SpriteFrameRenderer.tsx

persona-buddy.tsAdd typed client for buddy preference APIs +0/-0

Add typed client for buddy preference APIs

• Implements get/patch for global buddy preferences and get/patch for per-Persona override preferences using the shared persona visual JSON fetch helper.

apps/packages/ui/src/services/persona-buddy.ts

persona-buddy-shell.tsPersist first-use hint dismissal state +0/-0

Persist first-use hint dismissal state

• Adds a persisted boolean to track whether the buddy first-use hint has been dismissed, and includes it in the persisted slice alongside positions.

apps/packages/ui/src/store/persona-buddy-shell.ts

persona.pyAdd buddy preference endpoints and visual-pack review/fork lifecycle APIs +333/-5

Add buddy preference endpoints and visual-pack review/fork lifecycle APIs

• Adds global and per-Persona buddy preference endpoints with versioned updates. Extends visual pack endpoints to include companion_behavior and review metadata, adds pack review and sealed-pack forking, and strengthens activation via expected_version + reviewed_fingerprint requirements.

tldw_Server_API/app/api/v1/endpoints/persona.py

persona.pyIntroduce ambient mode, preference, and pack review/fork/activate schemas +56/-2

Introduce ambient mode, preference, and pack review/fork/activate schemas

• Adds PersonaAmbientMode plus strict version typing, request/response models for global/per-Persona buddy preferences, and models for visual pack review, fork, and activation (including reviewed_fingerprint validation).

tldw_Server_API/app/api/v1/schemas/persona.py

companion_behavior.pyAdd strict validator for optional pack companion behavior metadata +191/-0

Add strict validator for optional pack companion behavior metadata

• Introduces schema validation and normalization for pack-level behavior entries, including trigger/category enums, unique trigger/state pairs, bounded weights/cooldowns, and movement constraints for move entries.

tldw_Server_API/app/core/Persona/companion_behavior.py

persona_state_store.pyPersist global buddy preferences and merge overlay patches safely +461/-73

Persist global buddy preferences and merge overlay patches safely

• Adds storage and optimistic-concurrency updates for global buddy preferences. Changes buddy upsert to validate and merge overlay preferences (instead of overwriting), and decodes stored companion_behavior for visual packs.

tldw_Server_API/app/core/DB_Management/chacha/persona_state_store.py

visual_service.pyBind review→activate to fingerprints and support sealed-pack fork +342/-26

Bind review→activate to fingerprints and support sealed-pack fork

• Adds pack fingerprinting across manifest/behavior and immutable asset fields, requires reviewed_fingerprint to match during activation, and adds a fork path that copies assets and remaps manifests into a new editable revision.

tldw_Server_API/app/core/Persona/visual_service.py

fingerprints.pyAdd visual pack fingerprint builder including immutable assets +41/-2

Add visual pack fingerprint builder including immutable assets

• Adds build_persona_visual_pack_fingerprint() to compute a canonical sha256 over pack payload fields and a stable projection of asset metadata.

tldw_Server_API/app/core/Persona/visual_portability/fingerprints.py

importer.pyValidate/import companion_behavior alongside manifest payload +22/-9

Validate/import companion_behavior alongside manifest payload

• Extends import preview to normalize/validate companion_behavior against resolvable manifest state IDs and store it via a unified pack payload update.

tldw_Server_API/app/core/Persona/visual_portability/importer.py

chatbooks.pyUpdate Chatbooks API endpoints for export/import workflows +84/-57

Update Chatbooks API endpoints for export/import workflows

• Adjusts Chatbooks endpoints to support expanded backup/export/import flows and associated operational behaviors.

tldw_Server_API/app/api/v1/endpoints/chatbooks.py

chatbook_schemas.pyExtend Chatbooks schemas for full-account contract +89/-8

Extend Chatbooks schemas for full-account contract

• Updates Chatbooks API schema models to support the full-account export/import contract and related metadata.

tldw_Server_API/app/api/v1/schemas/chatbook_schemas.py

chatbook_account_inventory.pyAdd Chatbooks account export inventory core module +243/-0

Add Chatbooks account export inventory core module

• Introduces an inventory module used to enumerate/export Chatbooks account content for full-account backup workflows.

tldw_Server_API/app/core/Chatbooks/chatbook_account_inventory.py

chatbook_service.pyHarden Chatbooks export/import service logic +1628/-79

Harden Chatbooks export/import service logic

• Extends and hardens Chatbooks service behavior to meet the full-account export/import contract, including worker coordination and state correctness improvements.

tldw_Server_API/app/core/Chatbooks/chatbook_service.py

Bug fix (1) +8 / -9
buddy.pyValidate ambient_mode while preserving overlay preference keys +8/-9

Validate ambient_mode while preserving overlay preference keys

• Updates overlay preference normalization to keep unknown keys intact while enforcing a strict ambient_mode enum contract.

tldw_Server_API/app/core/Persona/buddy.py

Tests (4) +1593 / -0
test_persona_buddy_api.pyAdd API tests for buddy global and per-Persona preferences +308/-0

Add API tests for buddy global and per-Persona preferences

• Adds coverage for default global preference behavior, versioned preference updates, validation error handling, and per-Persona override semantics (including preserving unknown overlay keys and conflict handling).

tldw_Server_API/tests/Persona/test_persona_buddy_api.py

test_persona_companion_behavior.pyAdd unit tests for companion behavior schema validation +205/-0

Add unit tests for companion behavior schema validation

• Adds comprehensive unit coverage for schema versioning, enum validation, bounds checks, uniqueness constraints, and movement validation without clamping.

tldw_Server_API/tests/Persona/test_persona_companion_behavior.py

test_chatbooks_full_account_export_contract.pyAdd contract tests for Chatbooks full-account export +531/-0

Add contract tests for Chatbooks full-account export

• Adds comprehensive tests validating the full-account export contract end-to-end at the service/API boundary.

tldw_Server_API/tests/Chatbooks/test_chatbooks_full_account_export_contract.py

test_chatbooks_full_account_import_restore.pyAdd contract tests for Chatbooks full-account import/restore +549/-0

Add contract tests for Chatbooks full-account import/restore

• Adds comprehensive tests validating full-account import/restore behavior against the defined manifest/contract expectations.

tldw_Server_API/tests/Chatbooks/test_chatbooks_full_account_import_restore.py

Documentation (2) +201 / -0
Persona_Ambient_Companion.mdDocument ambient Persona Buddy Stage 1 behavior and constraints +158/-0

Document ambient Persona Buddy Stage 1 behavior and constraints

• Adds technical documentation describing Stage 1 ambient buddy behavior, modes, input/accessibility expectations, and the “no runtime model calls” constraint.

Docs/Code_Documentation/Persona_Ambient_Companion.md

Persona_Visual_Packs.mdDocument Persona visual packs and lifecycle workflows +43/-0

Document Persona visual packs and lifecycle workflows

• Adds technical documentation for visual pack structure and lifecycle behaviors, including review/activation/fork expectations and safety constraints.

Docs/Code_Documentation/Persona_Visual_Packs.md

@qodo-code-review

qodo-code-review Bot commented Aug 24, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Local CompanionBehaviorValidationError defined ✓ Resolved 📘 Rule violation ⌂ Architecture
Description
A new custom exception class is defined in tldw_Server_API/app/core/Persona/companion_behavior.py
instead of being centralized in the core exceptions module. This fragments the exception taxonomy
and makes consistent handling harder.
Code

tldw_Server_API/app/core/Persona/companion_behavior.py[R31-33]

+class CompanionBehaviorValidationError(ValueError):
+    """Raised when pack-level companion behavior is invalid."""
+
Evidence
PR Compliance ID 224217 requires custom exceptions to be defined in the centralized core exceptions
module rather than locally in feature modules. This PR introduces CompanionBehaviorValidationError
in a feature module file.

Rule 224217: Centralize custom exceptions in core module
tldw_Server_API/app/core/Persona/companion_behavior.py[31-33]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`CompanionBehaviorValidationError` is a new custom exception defined outside the centralized core exceptions module.

## Issue Context
The checklist requires new custom exceptions to live in the central exceptions location so callers can import consistently.

## Fix Focus Areas
- tldw_Server_API/app/core/Persona/companion_behavior.py[31-33]
- tldw_Server_API/app/core/exceptions.py[55-70]
- tldw_Server_API/app/core/Persona/visual_service.py[20-30]
- tldw_Server_API/app/core/Persona/visual_portability/preview.py[10-20]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Raw SQL in ChatbookService ✗ Dismissed 📘 Rule violation ⌂ Architecture
Description
New SQL query strings are executed from tldw_Server_API/app/core/Chatbooks/chatbook_service.py
rather than via /app/core/DB_Management/ abstractions. This bypasses the required DB access layer
and can lead to inconsistent data-access patterns and review gaps.
Code

tldw_Server_API/app/core/Chatbooks/chatbook_service.py[R7898-7900]

+        return self._query_ids(
+            "SELECT id FROM Media WHERE deleted = 0 AND is_trash = 0 ORDER BY id ASC",
+            db=media_db,
Evidence
PR Compliance ID 224231 requires database access to go through /app/core/DB_Management/ only. The
added code in chatbook_service.py executes raw SQL (SELECT ...) directly from a
/app/core/Chatbooks/ module.

Rule 224231: Enforce database access through /app/core/DB_Management/ only
tldw_Server_API/app/core/Chatbooks/chatbook_service.py[7892-7901]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`tldw_Server_API/app/core/Chatbooks/chatbook_service.py` now contains raw SQL strings (e.g., `SELECT ...`) executed via `execute_query`, but DB access must be centralized under `/app/core/DB_Management/`.

## Issue Context
This PR introduced new scope/list/count helpers for chatbook full-account export that embed SQL directly in a non-DB_Management module.

## Fix Focus Areas
- tldw_Server_API/app/core/Chatbooks/chatbook_service.py[7892-8019]
- tldw_Server_API/app/core/DB_Management/[1-200]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. normalize_persona_buddy_overlay_preferences raises ValueError ✓ Resolved 📘 Rule violation ✧ Quality
Description
The new validation path raises a generic built-in ValueError instead of using a project-specific
custom exception (e.g., BadRequestError). This makes error handling less consistent across the
application.
Code

tldw_Server_API/app/core/Persona/buddy.py[R88-90]

+    ambient_mode = normalized.get("ambient_mode")
+    if ambient_mode is not None and ambient_mode not in {"off", "expressive", "roaming"}:
+        raise ValueError("ambient_mode must be off, expressive, or roaming")
Evidence
PR Compliance ID 380621 requires project-specific custom exceptions for domain/application errors
instead of generic built-ins like ValueError. The changed code raises ValueError for invalid
ambient_mode.

Rule 380621: Use project-specific custom exceptions instead of generic built-ins
tldw_Server_API/app/core/Persona/buddy.py[83-91]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`normalize_persona_buddy_overlay_preferences` raises a built-in `ValueError` for an application/domain validation failure.

## Issue Context
The project defines custom request/validation exceptions (e.g., `BadRequestError`) for consistent handling across layers.

## Fix Focus Areas
- tldw_Server_API/app/core/Persona/buddy.py[83-91]
- tldw_Server_API/app/core/exceptions.py[55-66]
- tldw_Server_API/app/core/DB_Management/chacha/persona_state_store.py[2116-2120]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View medium (3)
4. New helpers lack docstrings ✓ Resolved 📘 Rule violation ✧ Quality
Description
Several newly added helper functions have no docstring as their first statement. This reduces
maintainability and violates the docstring requirement for new/modified functions.
Code

tldw_Server_API/app/core/Persona/companion_behavior.py[R59-63]

+def _normalize_entries(
+    entries: list[Any],
+    resolvable_state_ids: set[str],
+) -> list[dict[str, Any]]:
+    normalized: list[dict[str, Any]] = []
Evidence
PR Compliance ID 224214 requires all functions to have docstrings. The cited helper functions begin
immediately with executable code (no leading string literal docstring).

Rule 224214: Require docstrings for all modules, classes, and functions
tldw_Server_API/app/core/Persona/companion_behavior.py[59-63]
tldw_Server_API/app/core/Persona/companion_behavior.py[135-137]
tldw_Server_API/app/core/Persona/companion_behavior.py[167-174]
tldw_Server_API/app/core/Persona/visual_portability/fingerprints.py[103-105]
tldw_Server_API/app/core/Persona/visuals.py[126-129]
tldw_Server_API/app/services/worker_startup_policy.py[27-31]
tldw_Server_API/app/core/Chatbooks/chatbook_format_v1_1.py[513-520]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Multiple newly added helper functions do not include docstrings.

## Issue Context
The compliance rule requires a docstring for every function/method definition added or modified in this PR.

## Fix Focus Areas
- tldw_Server_API/app/core/Persona/companion_behavior.py[59-63]
- tldw_Server_API/app/core/Persona/companion_behavior.py[135-139]
- tldw_Server_API/app/core/Persona/companion_behavior.py[167-174]
- tldw_Server_API/app/core/Persona/visual_portability/fingerprints.py[103-105]
- tldw_Server_API/app/core/Persona/visuals.py[126-129]
- tldw_Server_API/app/services/worker_startup_policy.py[27-31]
- tldw_Server_API/app/core/Chatbooks/chatbook_format_v1_1.py[513-520]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Stale frame on error ✓ Resolved 🐞 Bug ≡ Correctness
Description
SpriteFrameRenderer can keep rendering the previously-presented frame when the newly requested state
has a structural error (missing animation/asset), because it only clears presented/asset handles
inside the reducedMotion branch. This can display the wrong Persona/animation indefinitely instead
of falling back, while also keeping the old asset handle alive unnecessarily.
Code

apps/packages/ui/src/components/Common/PersonaBuddy/SpriteFrameRenderer.tsx[R238-241]

+    if (structuralError || !frame || !asset) {
+      if (reducedMotion) {
+        requestRef.current += 1
+        handleRef.current?.release()
Evidence
On structural errors, the effect does not clear presented unless reducedMotion is true, but the
render path uses presented as the sole gate for showing fallback UI; therefore a previously
successful frame can remain visible even after switching to an invalid/missing state/asset.

apps/packages/ui/src/components/Common/PersonaBuddy/SpriteFrameRenderer.tsx[237-245]
apps/packages/ui/src/components/Common/PersonaBuddy/SpriteFrameRenderer.tsx[328-339]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`SpriteFrameRenderer` only clears `presented` (and releases the current `PersonaVisualAssetHandle`) when `reducedMotion` is true. When `structuralError || !frame || !asset` occurs in normal mode, `presented` remains set, so the component continues rendering the *previous* frame/asset instead of falling back.

## Issue Context
The render path returns fallback only when `!presented`, so leaving `presented` intact preserves stale visuals across state/pack/persona changes.

## Fix Focus Areas
- apps/packages/ui/src/components/Common/PersonaBuddy/SpriteFrameRenderer.tsx[238-244]

### Suggested change
In the `structuralError || !frame || !asset` branch, clear any outstanding/previous presentation regardless of `reducedMotion`:
- increment `requestRef.current`
- `handleRef.current?.release()` and null it
- `setPresented(null)`

Optionally, you can keep the “preserve last frame while loading” behavior by only clearing when the new request can never succeed (i.e., structuralError is non-null), but the current code clears too narrowly (reduced-motion only).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. _import_job_response() missing param type ✓ Resolved 📘 Rule violation ✧ Quality
Description
The new helper _import_job_response(job) omits a type annotation for job. This reduces static
checking and violates the project requirement for full parameter annotations.
Code

tldw_Server_API/app/api/v1/endpoints/chatbooks.py[111]

+def _import_job_response(job) -> ImportJobResponse:
Evidence
PR Compliance ID 224215 requires explicit type hints on all function parameters and return values.
The new _import_job_response(job) function leaves job unannotated.

Rule 224215: Require type hints on all function parameters and return values
tldw_Server_API/app/api/v1/endpoints/chatbooks.py[111-114]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The function `_import_job_response(job) -> ImportJobResponse` has an untyped parameter (`job`). The codebase requires type hints for all parameters and return values.

## Issue Context
`job` appears to be a `Chatbooks` model object (likely `ImportJob`). Adding an explicit type makes this helper safer and easier to refactor.

## Fix Focus Areas
- tldw_Server_API/app/api/v1/endpoints/chatbooks.py[111-134]
- tldw_Server_API/app/core/Chatbooks/chatbook_models.py[505-525]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 74 rules
Review mode: ⚖️ Balanced

Grey Divider

Tip of the day
💡 Did you know, you can hide the parts of a finding you never read, like the evidence or the agent prompt

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread tldw_Server_API/app/core/Chatbooks/chatbook_service.py Outdated
Comment thread tldw_Server_API/app/api/v1/endpoints/chatbooks.py Outdated
Comment thread tldw_Server_API/app/core/Persona/companion_behavior.py Outdated
Comment thread tldw_Server_API/app/core/Persona/companion_behavior.py
Comment thread tldw_Server_API/app/core/Persona/buddy.py Outdated
Comment thread apps/packages/ui/src/components/Common/PersonaBuddy/SpriteFrameRenderer.tsx Outdated
@rmusser01
rmusser01 force-pushed the codex/persona-ambient-stage1 branch from e4368ff to 3b61260 Compare August 25, 2026 07:13
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