Persist category and hierarchy metadata on wiki pages (new migration), expose
category-path retrieval and related repository/service/handler/router APIs, and
update wiki ingestion (batch, cite, taxonomy) plus agent wiki prompts to build
and consume the taxonomy. Regenerate swagger docs for the new endpoints.
ParseLLMJsonResponse recompiled its ```json fence-extraction regexp on
every call that fell through the direct-unmarshal fast path — i.e. every
fenced LLM response on the graph-extraction path. Hoist it to a
package-level var.
Adds a test (none existed) covering direct, fenced, no-lang and
prose-wrapped inputs, plus a benchmark.
Benchmark, fenced payload (-benchmem):
before: 3205 ns/op, 5712 B/op, 54 allocs/op
after: 1315 ns/op, 693 B/op, 15 allocs/op
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
hasCommandSubstitution recompiled its three regexps with regexp.MustCompile
on every call, and ValidateArgs calls it once per argument — so validating
an N-arg command compiled 3N patterns. Hoist them to a package-level slice
compiled once at init.
Behavior is unchanged (same patterns); covered by the existing
TestScriptValidator_ValidateArgs / ValidateAll tests.
Benchmark, ValidateArgs with 8 args (-benchmem):
before: 16374 ns/op, 40142 B/op, 505 allocs/op
after: 2092 ns/op, 32 B/op, 1 allocs/op
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
WikiChunkCitationPrompt placed the per-batch <chunks> block before the
static rules, output schema and the per-document-stable <candidate_slugs>.
Within one document only ChunksXML changes between batches, so the stable
content trailing the chunks could not form a long common prefix and
providers re-billed the static rules on every citation batch (issue #1687
measured ~6.4% prefix-cache hit rate on wiki synthesis).
Reorder to [rules | output schema | candidate_slugs | chunks] so every
batch after the first shares the long [rules | candidate_slugs] prefix.
No instruction text was dropped; only block order and the inline
above/below directional references changed. Verified the cacheable prefix
grows from 281 to 2366 bytes and is byte-identical across batches.
Addresses #1687
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
When the dominant heading level repeats and becomes the split backbone,
a long section is sub-split via SplitText and every sub-chunk inherited
the section-level breadcrumb. Deep `###`/`####` headings that define a
sub-chunk's meaning were dropped from Chunk.ContextHeader, so queries
about content nested far below a shallow heading failed to retrieve it.
Track the heading hierarchy across the section and assign each sub-chunk
the breadcrumb in effect at its start offset, so the deepest active
heading reaches the breadcrumb. Adds a regression test.
Fixes#1674
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The "add to knowledge base" action on the chat page opens the manual
editor, whose target picker was populated only from listKnowledgeBases()
— the caller's own KBs. A user who was granted editor access to a shared
KB therefore could not select it, even though the backend
(CreateManualKnowledge) accepts editor/admin permission.
Also fetch shared knowledge bases and merge those the user can write to
(editor/admin) into the picker, de-duplicated against owned KBs and
limited to document-type KBs. Viewer-only shares stay excluded.
Fixes#1689
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a `quick` flag to `opendataloader_available` so registry listing can use
a single short-timeout health check instead of the patient retry/backoff loop.
Parsing keeps the original tolerant probe to handle a hybrid service that is
still starting up.
Wiki summary/entity/concept/page-modify prompts instructed the LLM to
reproduce  verbatim, so high-entropy image URLs passed
through generation and got corrupted (dropped UUID segments, duplicated
or mangled path prefixes, even CJK chars inserted into the bucket name),
producing object keys that don't exist -> 404.
Mask all image URLs to opaque placeholders at the generateWithTemplate
chokepoint and deterministically rehydrate after generation; drop
corrupted/hallucinated placeholders so broken links never reach storage.
Group embed sessions in the sidebar by channel, replace session source filter
with grouping buckets, and align shared chat components with embed theme colors.
Introduce embed_channels storage, publish-token and session-token auth,
origin allowlist enforcement, shared Redis rate limiter, public embed API
routes, webhooks with SSRF validation, and session listing by embed source.
Three related improvements to the IM-session experience:
- Auto-generated titles: a new IM session starts untitled and gets a
content-based title from its first message via the same GenerateTitleAsync
flow web sessions use, instead of an identity title like "user · dm". Falls
back to the identity title when the first message has no text. All platforms.
- In-flight reply recovery (web chat): opening a session whose reply is still
being generated on an IM channel made the web client attach via
continue-stream and fail (the IM answer never streams through this server),
flashing a "stream failed" toast and forcing a manual refresh. Treat a failed
attach to an IM reply (channel === 'im') as recoverable — poll until it
completes, then reload the thread; on timeout surface the standard error.
Web/api replies keep the original behaviour, untouched.
- Source-filter classification: the sidebar filter treats "web" as sessions
with no IM mapping, but the list join excluded soft-deleted mappings, so
/clear'd IM sessions leaked into the user's own web chats. Include soft-deleted
mappings so a session ever bound to an IM channel stays under its platform.
Adds a repository regression test.
IM-channel sessions were mixed in with the user's own chats. The sidebar
now defaults to web sessions; tenants with a configured IM channel get a
source switcher in the "对话" header to reach a specific platform.
- getSessionsList: optional `source` query param
- getMessageList: token-guarded loads (racing source switches / route
changes can't append stale rows) + per-source pagination reset
- SourceSwitcherDropdown: scope dropdown mirroring KBSwitcherDropdown,
scales to many platforms, reuses platform logos, closes on select
- empty state when a source has no sessions
- pure logic in sessionSourceFilter.ts with unit tests; zh/en/ko/ru i18n
- Updated McpSettings.vue, ModelSettings.vue, VectorStoreSettings.vue, and WebSearchSettings.vue to streamline the empty state display for services and models.
- Removed admin-specific add buttons from empty states, enhancing clarity for non-admin users.
- Improved consistency in the presentation of empty states across different settings components.
- Updated the menu component to include a new chat option, improving user navigation.
- Refactored the menu layout to allow for sticky behavior during scrolling, enhancing usability.
- Added localization support for the new chat feature in English, Korean, Russian, and Chinese.
- Adjusted the menu store to reflect the new chat option and maintain consistent menu structure.
- Updated the menu component to include a search button alongside the sidebar toggle in the expanded view, improving accessibility to search functionality.
- Refactored the layout to maintain a consistent design for the logo actions, ensuring a seamless user experience.
- Adjusted CSS styles for the sidebar toggle and search button for better alignment and responsiveness.
- Improved tooltip handling for the search feature to provide clear user guidance.
- Replaced toolbar layouts with a more streamlined header design in McpSettings.vue, VectorStoreSettings.vue, and WebSearchSettings.vue for improved consistency.
- Introduced new button styles for adding services and stores, enhancing visual clarity and user interaction.
- Updated empty state handling to utilize a unified design approach across settings views.
- Adjusted CSS styles for better alignment and responsiveness in service and store cards.
- Added a new section for model type selection in ModelEditorDialog.vue, allowing users to choose between different model types with visual indicators.
- Updated the source selection logic to reflect changes in model type and ensure proper state management.
- Refactored related computed properties to utilize the active model type for better clarity and maintainability.
- Enhanced localization files (English, Korean, Russian, Chinese) to include new translations for model type and type label.
- Improved the layout and structure of ModelSettings.vue for better user experience and accessibility.
- Revised usage steps in English, Korean, Russian, and Chinese localization files for clarity on saving credentials and adding cloud models.
- Introduced a new section in WeKnoraCloudSettings.vue to display the status of cloud model integration based on credential configuration.
- Added utility functions for managing WeKnoraCloud models, including model configuration and existing model checks.
- Enhanced ModelSettings.vue to improve model management actions and confirm deletion prompts.
- Implemented logic to handle adding cloud models with success and failure notifications.
- Updated the openCreateKB method to accept an optional initialSection parameter, allowing for targeted navigation during knowledge base creation.
- Removed the TenantModelsGuide component from KnowledgeBaseList.vue to streamline the UI.
- Adjusted logic in handleCreateKnowledgeBase to conditionally set the initial section based on model readiness, improving user experience.
- Removed unnecessary margins and adjusted padding in AgentList.vue, Chat.vue, and KnowledgeBaseList.vue to enhance the visual layout.
- Updated scrollbar styles to utilize system defaults for a more consistent user experience across components.
- Ensured that sticky headers align properly with the container edges by modifying padding settings.
- Added a new script `build_frontend_dist.sh` to handle the building of frontend static assets.
- Updated `docker-compose.yml` to include a note about running the build script before building the frontend service.
- Modified the GitHub Actions workflow to integrate the new build script for frontend assets.
- Adjusted the Dockerfile to copy built assets directly from the `dist` directory.
- Refined the `.dockerignore` to exclude unnecessary files while keeping the `dist` directory.
- Updated the CreateKnowledgeFromFile function to accept an optional processConfig parameter, enhancing flexibility in knowledge file uploads.
- Modified related service and test files to accommodate the new parameter, ensuring consistent handling across the upload process.
- Removed dependency on utils for schema generation, replacing it with a hardcoded JSON schema for GetDocumentInfoInput.
- Updated the input struct to use omitempty for JSON fields, clarifying that either knowledge_ids or faq_ids may be provided, but both are optional.
- Enhanced documentation for GetDocumentInfoInput to specify the usage of knowledge_ids and faq_ids.