fix(assistant): complete PR3 conversation history#57
Conversation
|
Warning Review limit reached
Next review available in: 28 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (3)
📒 Files selected for processing (11)
📝 WalkthroughWalkthroughAdds persisted assistant conversation history with JDBC-backed chat memory, conversation lifecycle APIs, actor-scoped web history and navigation, prompt user context and XML escaping, and direct asset feedback submission. ChangesAssistant conversations
Asset feedback submission
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant AssistantPage
participant AssistantController
participant AssistantConversationService
participant SpringAiChatModelAdapter
User->>AssistantPage: Send message
AssistantPage->>AssistantController: POST message with conversationId
AssistantController->>AssistantConversationService: Begin user turn
AssistantController->>SpringAiChatModelAdapter: Stream assistant response
SpringAiChatModelAdapter-->>AssistantPage: Response chunks and conversation ID
AssistantController->>AssistantConversationService: Complete assistant turn
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 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 `@apps/api/src/main/java/com/orgmemory/api/assistant/AssistantController.java`:
- Around line 139-151: Update AssistantController.delete so conversations.delete
executes before memory.clear, ensuring chat memory is cleared only after the
transcript deletion succeeds. Replace the redundant conversations.requireAccess
pre-check with the existing ownership enforcement in conversations.delete, while
preserving actor and conversationId handling.
In
`@core/src/main/java/com/orgmemory/core/assistant/AssistantConversationService.java`:
- Around line 69-81: Update AssistantConversationService.list to eliminate the
per-conversation messages.countByConversationId call by loading message counts
for all returned conversation IDs in one repository query, then map those counts
when constructing AssistantConversationSummary and default missing IDs to zero.
In `@core/src/main/resources/db/migration/V6__assistant_conversation_history.sql`:
- Around line 41-65: Update the assistant_conversation_messages definition and
its parent conversation key constraints to add a composite foreign key tying
conversation_id and organization_id to the corresponding assistant_conversations
columns, while preserving the existing conversation_id cascade behavior. Ensure
the referenced parent columns have a matching primary or unique constraint and
retain the actor-user tenant foreign key.
In `@web/src/features/assistant/components/assistant-conversation-list.tsx`:
- Around line 123-135: Update the empty-state condition in the conversation list
rendering near conversations.isError so the “Your recent conversations will
appear here” message is suppressed when an error exists. Preserve the
empty-state message for non-pending, non-error conversations with no visible
items.
In `@web/src/features/assistant/components/assistant-page.tsx`:
- Around line 350-372: Update the loading and error state containers in the
conversation history flow of the assistant page: add an appropriate live-region
status announcement to the loading block and an alert announcement to the error
block, matching the existing accessible turn-error banner pattern while
preserving their current content and behavior.
- Around line 350-372: Prevent stale messages from rendering during a
conversation switch by deriving a synchronous switching state from the current
conversationId and the conversation identity associated with messages, rather
than relying solely on the reset useEffect. Update the assistant-page render
guards around the existing history loading/error checks to show the loading
state while switching, while preserving normal rendering once messages belong to
the active conversation.
- Around line 221-244: The useChat onFinish callback should also invalidate the
actor-scoped conversation history query identified by
scopeActorQueryKey(historyOptions.queryKey, actorKey), not only
conversationListQueryKey. Update the completion flow in the component so the
current conversation history is invalidated or refetched after each completed
turn, preserving the existing list-cache invalidation.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: e4046aec-8f25-4e64-ab16-35381d5a85fd
⛔ Files ignored due to path filters (6)
contracts/openapi.jsonis excluded by!contracts/openapi.jsondocs/increments/active/2026-07-25-unified-asset-registry-definition/design.mdis excluded by!docs/**docs/increments/active/2026-07-25-unified-asset-registry-definition/plan.mdis excluded by!docs/**docs/increments/active/2026-07-25-unified-asset-registry-definition/ui-reference-audit.mdis excluded by!docs/**docs/specs/domains/assistant-and-mcp.mdis excluded by!docs/**docs/tests/domains/assistant-and-mcp.mdis excluded by!docs/**
📒 Files selected for processing (33)
apps/api/build.gradle.ktsapps/api/src/main/java/com/orgmemory/api/ApiExceptionHandler.javaapps/api/src/main/java/com/orgmemory/api/assistant/AssistantChatRequest.javaapps/api/src/main/java/com/orgmemory/api/assistant/AssistantConfiguration.javaapps/api/src/main/java/com/orgmemory/api/assistant/AssistantController.javaapps/api/src/main/java/com/orgmemory/api/security/OidcCurrentActorProvider.javaapps/api/src/main/resources/application.ymlapps/api/src/test/java/com/orgmemory/api/assistant/AssistantControllerStreamingTests.javacore/src/main/java/com/orgmemory/core/ai/ChatModelPort.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversation.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationMessage.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationMessageRepository.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationMessageView.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationNotFoundException.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationRepository.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationRole.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationService.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationSummary.javacore/src/main/java/com/orgmemory/core/assistant/AssistantPromptFactory.javacore/src/main/java/com/orgmemory/core/assistant/AssistantService.javacore/src/main/java/com/orgmemory/core/organization/CurrentActor.javacore/src/main/resources/db/migration/V6__assistant_conversation_history.sqlcore/src/test/java/com/orgmemory/core/assistant/AssistantConversationServiceTests.javacore/src/test/java/com/orgmemory/core/assistant/AssistantServiceTests.javaintegrations/ai-openai-compatible/src/main/java/com/orgmemory/integrations/ai/openai/SpringAiChatModelAdapter.javaweb/src/components/app-shell/app-sidebar.tsxweb/src/features/assets/actor-key.tsweb/src/features/assets/components/asset-detail-page.tsxweb/src/features/assistant/api/chat-transport.tsweb/src/features/assistant/components/assistant-conversation-list.tsxweb/src/features/assistant/components/assistant-page.tsxweb/src/features/session/actor-cache-key.tsweb/src/routes/_authenticated/index.tsx
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
- GitHub Check: Backend · Java 25
- GitHub Check: PostgreSQL GraphRAG
- GitHub Check: Web · Node 24
🧰 Additional context used
📓 Path-based instructions (7)
**/*
📄 CodeRabbit inference engine (CLAUDE.md)
**/*: Record current behavior in architecture/specification documentation only after it exists in code; keep intended behavior in vision, roadmap, or an active increment, and do not duplicate state.
Before using unfamiliar Spring Boot 4, Spring Modulith 2, Spring AI 2, Gradle, React, Vite, Tailwind, or TypeScript APIs, consult current official documentation via Context7 and the projectorgmemory-*verification skills.
Before retrieval, AI, MCP, permission, upload, graph, or export work, readdocs/guidelines/agent-safety.md.
Never commit.envfiles, provider keys, tokens, or customer data.
Run the relevant verification gates fromdocs/guidelines/testing-harness.md; use a terminating clean test as the context gate, and do not treatbootRunas verification.
Files:
core/src/main/java/com/orgmemory/core/assistant/AssistantConversationRole.javaapps/api/build.gradle.ktscore/src/main/java/com/orgmemory/core/assistant/AssistantConversationNotFoundException.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationSummary.javaapps/api/src/main/resources/application.ymlweb/src/features/session/actor-cache-key.tscore/src/main/java/com/orgmemory/core/assistant/AssistantConversationMessageView.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationMessageRepository.javaweb/src/features/assistant/api/chat-transport.tscore/src/main/java/com/orgmemory/core/ai/ChatModelPort.javaapps/api/src/test/java/com/orgmemory/api/assistant/AssistantControllerStreamingTests.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationRepository.javaweb/src/features/assets/components/asset-detail-page.tsxapps/api/src/main/java/com/orgmemory/api/assistant/AssistantConfiguration.javaweb/src/routes/_authenticated/index.tsxcore/src/test/java/com/orgmemory/core/assistant/AssistantConversationServiceTests.javaweb/src/components/app-shell/app-sidebar.tsxcore/src/main/java/com/orgmemory/core/assistant/AssistantConversation.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationMessage.javacore/src/main/resources/db/migration/V6__assistant_conversation_history.sqlapps/api/src/main/java/com/orgmemory/api/assistant/AssistantChatRequest.javacore/src/main/java/com/orgmemory/core/organization/CurrentActor.javaapps/api/src/main/java/com/orgmemory/api/security/OidcCurrentActorProvider.javacore/src/main/java/com/orgmemory/core/assistant/AssistantService.javaweb/src/features/assets/actor-key.tsintegrations/ai-openai-compatible/src/main/java/com/orgmemory/integrations/ai/openai/SpringAiChatModelAdapter.javaapps/api/src/main/java/com/orgmemory/api/ApiExceptionHandler.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationService.javaweb/src/features/assistant/components/assistant-page.tsxcore/src/test/java/com/orgmemory/core/assistant/AssistantServiceTests.javaapps/api/src/main/java/com/orgmemory/api/assistant/AssistantController.javaweb/src/features/assistant/components/assistant-conversation-list.tsxcore/src/main/java/com/orgmemory/core/assistant/AssistantPromptFactory.java
**/*.{java,kt}
📄 CodeRabbit inference engine (CLAUDE.md)
JetBrains IDE inspection is a verification gate for the Java backend.
Files:
core/src/main/java/com/orgmemory/core/assistant/AssistantConversationRole.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationNotFoundException.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationSummary.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationMessageView.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationMessageRepository.javacore/src/main/java/com/orgmemory/core/ai/ChatModelPort.javaapps/api/src/test/java/com/orgmemory/api/assistant/AssistantControllerStreamingTests.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationRepository.javaapps/api/src/main/java/com/orgmemory/api/assistant/AssistantConfiguration.javacore/src/test/java/com/orgmemory/core/assistant/AssistantConversationServiceTests.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversation.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationMessage.javaapps/api/src/main/java/com/orgmemory/api/assistant/AssistantChatRequest.javacore/src/main/java/com/orgmemory/core/organization/CurrentActor.javaapps/api/src/main/java/com/orgmemory/api/security/OidcCurrentActorProvider.javacore/src/main/java/com/orgmemory/core/assistant/AssistantService.javaintegrations/ai-openai-compatible/src/main/java/com/orgmemory/integrations/ai/openai/SpringAiChatModelAdapter.javaapps/api/src/main/java/com/orgmemory/api/ApiExceptionHandler.javacore/src/main/java/com/orgmemory/core/assistant/AssistantConversationService.javacore/src/test/java/com/orgmemory/core/assistant/AssistantServiceTests.javaapps/api/src/main/java/com/orgmemory/api/assistant/AssistantController.javacore/src/main/java/com/orgmemory/core/assistant/AssistantPromptFactory.java
**/application*.{yml,yaml,properties}
📄 CodeRabbit inference engine (CLAUDE.md)
Keep JPA
ddl-auto=validate; pair JPA schema or entity changes with a Flyway migration.
Files:
apps/api/src/main/resources/application.yml
**/*.{ts,tsx,js,jsx,css,scss,html}
📄 CodeRabbit inference engine (CLAUDE.md)
For frontend files, run Oxlint, TypeScript typecheck, the production build, and browser tests when the UI flow matters; do not run JetBrains IDE inspection on TypeScript, TSX, or web configuration.
Files:
web/src/features/session/actor-cache-key.tsweb/src/features/assistant/api/chat-transport.tsweb/src/features/assets/components/asset-detail-page.tsxweb/src/routes/_authenticated/index.tsxweb/src/components/app-shell/app-sidebar.tsxweb/src/features/assets/actor-key.tsweb/src/features/assistant/components/assistant-page.tsxweb/src/features/assistant/components/assistant-conversation-list.tsx
web/src/**/*.{ts,tsx}
⚙️ CodeRabbit configuration file
web/src/**/*.{ts,tsx}: OAuth access and refresh tokens must never enter browser JavaScript or
browser storage. Use the HttpOnly BFF session, CSRF-protected mutations,
generated Hey API data clients, accessible states, and both light and
dark themes. Handwritten transport is reserved for documented protocol
flows such as navigation redirects and streaming.
Files:
web/src/features/session/actor-cache-key.tsweb/src/features/assistant/api/chat-transport.tsweb/src/features/assets/components/asset-detail-page.tsxweb/src/routes/_authenticated/index.tsxweb/src/components/app-shell/app-sidebar.tsxweb/src/features/assets/actor-key.tsweb/src/features/assistant/components/assistant-page.tsxweb/src/features/assistant/components/assistant-conversation-list.tsx
apps/api/src/main/java/**/*.java
⚙️ CodeRabbit configuration file
apps/api/src/main/java/**/*.java: Enforce the browser-BFF and resource-server boundaries. Authentication
must resolve an active internal actor through the explicit issuer and
subject binding. Reject identity, tenant, roles, or permissions supplied
by request payloads, JWT email, or untrusted JWT role claims.
Files:
apps/api/src/main/java/com/orgmemory/api/assistant/AssistantConfiguration.javaapps/api/src/main/java/com/orgmemory/api/assistant/AssistantChatRequest.javaapps/api/src/main/java/com/orgmemory/api/security/OidcCurrentActorProvider.javaapps/api/src/main/java/com/orgmemory/api/ApiExceptionHandler.javaapps/api/src/main/java/com/orgmemory/api/assistant/AssistantController.java
core/src/main/resources/db/migration/*.sql
⚙️ CodeRabbit configuration file
core/src/main/resources/db/migration/*.sql: The repository is pre-release: V1 is the intentionally resettable clean
baseline and development data carries no migration cost. Once a release
baseline is frozen, later Flyway migrations are immutable. Check tenant
isolation, foreign keys, uniqueness, indexes, append-only evidence
semantics, safe defaults, and PostgreSQL 18 plus pgvector compatibility.
Files:
core/src/main/resources/db/migration/V6__assistant_conversation_history.sql
🧠 Learnings (1)
📚 Learning: 2026-07-23T23:30:44.585Z
Learnt from: kl3inIT
Repo: kl3inIT/OrgMemory PR: 30
File: core/src/main/resources/db/migration/V32__evidence_scoped_graph_semantics.sql:0-0
Timestamp: 2026-07-23T23:30:44.585Z
Learning: For OrgMemory PostgreSQL Flyway migrations under core/src/main/resources/db/migration, do not recommend using `CREATE INDEX CONCURRENTLY` or `DROP INDEX CONCURRENTLY` inside application-owned Flyway migration SQL. Flyway’s schema-history connection may hold a transaction that can cause concurrent index operations to wait indefinitely (e.g., on a `virtualxid`), and docs/conventions.md forbids this pattern. If you need large production-table index replacement, pre-stage online index operations via the deployment pipeline (outside Flyway) rather than inside the migration; “ordinary” index replacement is acceptable for unreleased projections before production traffic.
Applied to files:
core/src/main/resources/db/migration/V6__assistant_conversation_history.sql
🪛 ast-grep (0.44.1)
core/src/main/java/com/orgmemory/core/assistant/AssistantService.java
[warning] 34-34: Avoid LDAP injections
Context: retrieval.search(actor, question, requestedLimit, requestId)
Note: [CWE-90] Improper Neutralization of Special Elements used in an LDAP Query ('LDAP Injection'). Security best practice.
(ldap-injection-java)
🪛 SQLFluff (4.2.2)
core/src/main/resources/db/migration/V6__assistant_conversation_history.sql
[error] 13-14: CREATE INDEX should use CONCURRENTLY to avoid locking the table during the build.
(PG01)
[error] 16-17: CREATE INDEX should use CONCURRENTLY to avoid locking the table during the build.
(PG01)
[error] 36-39: CREATE INDEX should use CONCURRENTLY to avoid locking the table during the build.
(PG01)
[error] 70-73: CREATE INDEX should use CONCURRENTLY to avoid locking the table during the build.
(PG01)
🪛 Squawk (2.59.0)
core/src/main/resources/db/migration/V6__assistant_conversation_history.sql
[warning] 4-4: Changing the size of a varchar field requires an ACCESS EXCLUSIVE lock, that will prevent all reads and writes to the table. Use a TEXT field with a CHECK constraint.
(prefer-text-field)
[warning] 6-6: Changing the size of a varchar field requires an ACCESS EXCLUSIVE lock, that will prevent all reads and writes to the table. Use a TEXT field with a CHECK constraint.
(prefer-text-field)
[warning] 7-7: When Postgres stores a datetime in a timestamp field, Postgres drops the UTC offset. This means 2019-10-11 21:11:24+02 and 2019-10-11 21:11:24-06 will both be stored as 2019-10-11 21:11:24 in the database, even though they are eight hours apart in time. Use timestamptz instead of timestamp for your column type.
(prefer-timestamp-tz)
[warning] 23-23: Changing the size of a varchar field requires an ACCESS EXCLUSIVE lock, that will prevent all reads and writes to the table. Use a TEXT field with a CHECK constraint.
(prefer-text-field)
[warning] 46-46: Changing the size of a varchar field requires an ACCESS EXCLUSIVE lock, that will prevent all reads and writes to the table. Use a TEXT field with a CHECK constraint.
(prefer-text-field)
🔇 Additional comments (34)
core/src/main/java/com/orgmemory/core/assistant/AssistantConversationSummary.java (1)
1-11: LGTM!web/src/features/assets/components/asset-detail-page.tsx (1)
702-715: 🎯 Functional CorrectnessRun the required frontend verification gates.
This changes a user-facing mutation flow. Confirm Oxlint, TypeScript typecheck, production build, and browser coverage for submit, pending, and disabled states. As per coding guidelines, “For frontend files, run Oxlint, TypeScript typecheck, the production build, and browser tests when the UI flow matters.”
Source: Coding guidelines
web/src/features/session/actor-cache-key.ts (1)
1-20: LGTM!web/src/features/assets/actor-key.ts (1)
1-13: LGTM!web/src/features/assistant/api/chat-transport.ts (1)
5-20: LGTM!Also applies to: 32-32
web/src/features/assistant/components/assistant-page.tsx (2)
2-5: LGTM!Also applies to: 39-47, 156-212, 255-268, 303-304
144-154: 🎯 Functional CorrectnessNo change needed for persisted message role mapping.
AssistantConversationRoleonly definesUSERandASSISTANT, so the"ASSISTANT"->"assistant"default maps the persisted history roles cleanly.web/src/features/assistant/components/assistant-conversation-list.tsx (1)
1-122: LGTM!Also applies to: 136-236
web/src/routes/_authenticated/index.tsx (1)
4-19: LGTM!Also applies to: 21-37
web/src/components/app-shell/app-sidebar.tsx (1)
5-6: LGTM!Also applies to: 33-38, 79-84
core/src/main/java/com/orgmemory/core/assistant/AssistantConversation.java (1)
1-74: LGTM!core/src/main/java/com/orgmemory/core/assistant/AssistantConversationMessage.java (1)
1-74: LGTM!core/src/main/java/com/orgmemory/core/assistant/AssistantConversationMessageView.java (1)
6-12: LGTM!core/src/main/java/com/orgmemory/core/assistant/AssistantConversationRole.java (1)
3-6: LGTM!core/src/main/java/com/orgmemory/core/assistant/AssistantConversationNotFoundException.java (1)
5-10: LGTM!core/src/main/java/com/orgmemory/core/assistant/AssistantConversationMessageRepository.java (1)
1-15: LGTM!core/src/main/java/com/orgmemory/core/assistant/AssistantConversationService.java (1)
27-67: LGTM!Also applies to: 83-113
core/src/main/resources/db/migration/V6__assistant_conversation_history.sql (1)
1-40: LGTM!Also applies to: 66-74
core/src/main/java/com/orgmemory/core/assistant/AssistantPromptFactory.java (1)
5-118: LGTM!core/src/main/java/com/orgmemory/core/assistant/AssistantService.java (1)
29-77: LGTM!apps/api/src/main/java/com/orgmemory/api/assistant/AssistantChatRequest.java (1)
5-10: LGTM!apps/api/src/main/java/com/orgmemory/api/assistant/AssistantController.java (1)
44-101: LGTM!Also applies to: 103-137
core/src/main/java/com/orgmemory/core/assistant/AssistantConversationRepository.java (1)
1-15: LGTM!core/src/test/java/com/orgmemory/core/assistant/AssistantConversationServiceTests.java (1)
1-143: LGTM!apps/api/build.gradle.kts (1)
27-27: LGTM!apps/api/src/main/java/com/orgmemory/api/assistant/AssistantConfiguration.java (1)
31-42: LGTM!apps/api/src/main/resources/application.yml (1)
6-10: LGTM!apps/api/src/main/java/com/orgmemory/api/security/OidcCurrentActorProvider.java (1)
49-56: LGTM! Role is sourced from the internally-resolvedAppUser, not from JWT claims, consistent with the resource-server boundary requirement.core/src/main/java/com/orgmemory/core/ai/ChatModelPort.java (1)
9-15: LGTM!core/src/test/java/com/orgmemory/core/assistant/AssistantServiceTests.java (1)
34-297: LGTM!apps/api/src/main/java/com/orgmemory/api/ApiExceptionHandler.java (1)
59-69: 🎯 Functional Correctness | ⚡ Quick winMisleading error message for conversation-not-found.
AssistantConversationNotFoundExceptionis grouped intoknowledgeResourceNotFound, which always returns "The requested knowledge resource is not available" — inaccurate for a missing/inaccessible conversation (history/rename/delete endpoints).🐛 Proposed fix: dedicated handler with accurate message
`@ExceptionHandler`({ - AssistantConversationNotFoundException.class, AssetNotFoundException.class, KnowledgeAssetNotFoundException.class, KnowledgeResourceNotFoundException.class }) ProblemDetail knowledgeResourceNotFound(RuntimeException e) { return ProblemDetail.forStatusAndDetail( HttpStatus.NOT_FOUND, "The requested knowledge resource is not available"); } + + `@ExceptionHandler`(AssistantConversationNotFoundException.class) + ProblemDetail assistantConversationNotFound(AssistantConversationNotFoundException e) { + return ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, e.getMessage()); + }apps/api/src/test/java/com/orgmemory/api/assistant/AssistantControllerStreamingTests.java (1)
68-76: LGTM!core/src/main/java/com/orgmemory/core/organization/CurrentActor.java (1)
14-21: 🎯 Functional CorrectnessNo change needed for null-role prompt rendering.
AssistantPromptFactoryalready maps a nullCurrentActorrole toUNSPECIFIEDbefore emitting the<role>tag.integrations/ai-openai-compatible/src/main/java/com/orgmemory/integrations/ai/openai/SpringAiChatModelAdapter.java (1)
66-109: 🩺 Stability & AvailabilityValidate multi-turn assistant memory before relying on fresh evidence per turn.
MessageChatMemoryAdvisorrewrites the prompt when history is present, andAssistantControllerStreamingTestsdoes not exercise this path with an existingchatMemory. Add a second-turn integration test, includingspring-ai-openai, to cover an existing conversation plus a new per-turn system message before using this in production.
What changed
V6; mergedV5remains unchangedWhy
PR #56 shipped the assistant Asset workspace, but its original memory conclusion was too strict and the history experience was incomplete. This follow-up finishes PR3 without adding a rare-case purge/re-authorization pipeline or expanding into PR4 MCP work.
Validation
./gradlew.bat --no-daemon clean test— passed, 97 taskscorepack pnpm -C web build— passed (Oxlint, TypeScript, Vite production build)git diff --check— passedImpact
The Assistant now supports practical, URL-addressable conversation history and normal bounded multi-turn context. Existing tenant, actor, retrieval, citation, and permission checks remain authoritative.
Summary by CodeRabbit
New Features
Bug Fixes