Publish scoped API keys, worker-pool governance, multi-instance storage,
and the rest of the v0.7.0 feature set across CHANGELOG, READMEs, QA,
Swagger, and version pins.
Chat attachment parser rules belong on agents; drop the duplicate workspace settings section while preserving legacy tenant rules when engine config is updated without that field.
Decouple the references SSE event from the per-agent citation output toggle
so the retrieval-results drawer still works, and align follow-up suggestion
card layout with the chat column.
Lark and Feishu are the same product deployed on two isolated clouds
(open.larksuite.com and open.feishu.cn). WeKnora touches both from two
places — the IM bot and the Wiki data-source connector — and this brings
Lark to parity across both. Neither API surface differs, so rather than
duplicate either implementation, each is parametrized by a Region and
registered twice.
IM (internal/im/feishu):
Every API call routes through a.api(), which prefixes the region's
host, and the WebSocket client passes larkws.WithDomain — the SDK
defaults to open.feishu.cn, so Lark long connections would otherwise
fail to authenticate.
Data source (internal/datasource/connector/feishu):
Lark was half-supported: the client honoured a base_url override and a
LarkBaseURL constant existed, but the connector registered only as
"feishu" and the UI never exposed base_url, so Lark wikis could not be
configured at all. Lark is now its own connector type. base_url is kept
as an explicit override so data sources that pointed a "feishu"
connector at open.larksuite.com keep working.
Bugs found and fixed along the way:
- Wiki resource links were hardcoded to https://feishu.cn/wiki/{token} in
four places, so a Lark wiki linked into the wrong cloud entirely.
- Bot identity is now platform-prefixed (feishu:cli_x vs lark:cli_x).
BotIdentity carries a unique index, so without this a Lark channel
would be rejected as a duplicate of an unrelated Feishu bot sharing an
app_id.
- The card image cache is now keyed by app_id. image_keys are issued per
app on one cloud; a Feishu key handed to a Lark app fails the card
update with code=200570.
- The datasource doc claimed Lark "adapts automatically" — it could not,
since the UI had no way to reach base_url.
Permissions are where the clouds genuinely diverge. Identical APIs do not
mean identical permission catalogues: aily:file:read, aily:file:write and
corehr:file:download exist on Feishu but not on Lark, so pasting Feishu's
scope JSON into Lark fails to import. That JSON is also over-broad (it
covers products WeKnora never calls) and simultaneously incomplete (it
omits the drive:*/docx:* scopes the connector needs). Lark therefore gets
its own list, derived from the 17 endpoints the code actually calls and
checked identifier-by-identifier against Lark's own API reference, plus a
full Feishu→Lark mapping table marking each scope verified, unverified,
or absent. Both features use tenant_access_token only — no user_access_
token exists anywhere in the repo — so the user dimension stays empty.
Known limitation: Region.ThinkingText makes Lark's initial card
placeholder English, but once streaming starts the think-block headers
come from the shared MarkdownThinkStyle and are Chinese on every platform
(Lark, Slack, Telegram, Mattermost alike). Fixing that means threading a
locale through FormatIMDisplayContent, which has no platform context — a
cross-platform change, not a Lark one. Documented as such.
The channel-creation 400 message is now derived from validIMPlatforms so
the list cannot drift as platforms are added.
Tests: region invariants and per-region URL construction on both sides,
the Feishu/Lark bot-identity split, platform-to-channel mapping, base_url
override precedence, an end-to-end SendReply against a fake Open Platform
(token fetch, reply, thread-unsupported fallback, hard-error surfacing),
and a ListResources drive asserting wiki links never leak the other
cloud's host.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Improve reference list readability by resolving URL-like titles to domains,
stripping markdown noise from snippets, and aligning suggestion chip hover
styles across chat and embed surfaces.
Update the SuggestedQuestionsRequest to include TagScopes for better filtering of knowledge items based on their parent knowledge bases. Modify related API documentation and frontend interfaces to accommodate the new structure. Ensure backend services handle the new tag scope logic correctly, including tests for the updated functionality.
Add a test to verify that selecting an agent defaults web search to off until the user enables it. Update the agent selection logic to ensure that the web search capability is controlled by user action rather than agent configuration. Modify comments in the Input-field component to reflect this change in behavior.
Implement improvements to the chat references drawer, including a new event for handling panel entry to ensure smooth scrolling to highlighted citations. Update the logic for retrieving references from agent events, allowing for better integration of citation data. Additionally, enhance tests to cover new functionality and ensure correct behavior of the references drawer during interactions.
Implement a mechanism to ensure follow-up suggestions are only displayed after the answer is fully rendered. Introduce an event for rendering completion and update related components to handle this new logic. Update tests to verify the correct behavior of follow-up suggestions based on rendering state.
Move citation protocol injection to the system layer so custom prompts no
longer own citation syntax. Agents can disable inline citations while source
aliases still encode and decode tool arguments correctly.
Replace raw chunk/document/KB IDs in LLM context with short cN/dN/bN/wN
aliases, decode tool arguments on the way in, and expand compact <ref/>
citations to the public <kb>/<web> format before user-facing output.
Preserve selected MCP IDs in the agent editor when services are disabled or
missing, display them as disabled options with clear labels, and tighten
setting-row layout so long multi-select tags do not overflow.
Shorten follow-up and refresh labels across locales, and replace flashy
suggestion card hovers with the same border, neutral background, and
shadow treatment used elsewhere in the chat page.
Keep the agent timeline placeholder visible between tool rounds when
nothing is pending, remove redundant thinking dot loaders, and replace
embed bouncing dots with a lightweight native spinner.
Remove redundant bounce-dot indicators from agent/RAG timelines and non-agent
answers; use existing pending step cards before activity and a compact spinner
for global wait states so streaming feedback stays aligned with the timeline.
Implement a maximum limit of 5 for the total number of images and attachments that can be uploaded in a chat session. Introduce a warning message for users when the limit is exceeded. Additionally, add functionality to clear pending uploads when switching sessions to prevent errors related to stale document IDs. Update localization files to include new warning messages in English, Korean, Russian, and Chinese.
Add functionality to normalize temporary attachment IDs, ensuring deduplication and enforcing a maximum limit of 5 attachments per message. Update related handlers and tests to support this new behavior, enhancing the robustness of attachment management in chat sessions.
Persist resolved temporary-attachment content onto the stored user message
so later turns can replay it in history. Close the retrieval progress spinner
on early pipeline exits, and reshape model-fallback messages with a proper
system role plus trailing user question.
Update the classification logic for follow-up questions to include reasoning about previously described images or documents. Ensure that follow-up queries referencing earlier attachments are correctly identified and processed without triggering unnecessary knowledge base searches. This change improves the model's ability to maintain context and respond accurately to user inquiries related to past interactions.
Let users upload documents in chat without ingesting them into a knowledge base: files are parsed in the background, referenced by ID on send, and expire after a configurable TTL.
Tighten model prompt so retrieval questions stay topic-bound and self-contained,
reserve knowledge slots in hybrid mode, and carry suggestion KB IDs into the next send.
When retrieved context or tool results contain Markdown images, dynamically
append output requirements to system prompts and final-answer instructions.
Also normalize fullwidth image parentheses in the frontend renderer so
localized model output still renders correctly.
Chat and agent tool context now emits answer-ready Markdown images instead
of internal <image> XML so copied content renders safely. The frontend also
normalizes legacy XML blocks in persisted conversations during streaming.
Improve follow-up question quality by feeding the model structured context
(evidence, capabilities, complete turns) instead of raw RAG content, and
rank knowledge candidates by current-topic relevance.
Refactor tests and registry to use the new 'res://' syntax for resource aliases, ensuring consistency across the codebase. This change addresses alias handling in various test cases, including stream processing and registry encoding, to prevent data loss and improve resource reference management.
Add functionality to detect unresolvable resource aliases emitted by the model during chat completion and streaming. Introduce logging for these orphan aliases to aid in debugging and improve the handling of resource references. Update the stream processing to ensure held aliases are flushed upon cancellation, preventing data loss. Include tests to verify the correct reporting of orphan aliases.
Introduce resource://<handle> as the stable application identity for stored
objects, decoupling API responses, persisted rich text, and LLM prompts from
physical storage paths. Adds a resource catalog service (register/resolve/bind,
revocable expiring access grants), a request-local alias registry that compacts
resource references while in the LLM context and restores them (including across
streaming chunks), plus router, IM, chat-pipeline, and multimodal integration.
Includes schema migrations (resources, resource_bindings, resource_access_grants)
for sqlite, and hardens URL/output security handling.
Implement a comprehensive API for managing storage backends, including endpoints for listing, creating, updating, and deleting storage instances. Enhance the UI to support multi-instance configurations, allowing users to manage multiple storage types effectively. Update localization files for new storage backend features and improve error handling for connectivity tests. This update also includes detailed documentation for the storage backend API.
Enhance error messaging for storage connectivity issues by sanitizing raw errors to prevent leaking sensitive information. Introduce a new utility function for consistent error handling across storage backend operations. Additionally, implement logic to support multi-instance storage backends, allowing for more flexible workspace configurations and improved reporting of active storage providers.
Update the image source protection logic to include support for storage backend images. Introduce new regex patterns for identifying storage URLs and refactor the image tag building process to ensure proper handling of both provider and storage backend images. Add corresponding tests to validate the new functionality.
Introduce tenant-scoped storage backend registry so workspaces can register
multiple storage instances and bind each knowledge base to a specific backend,
with migration from legacy tenant-level storage config and new settings UI.
Extract storage allowlist into internal/storageallowlist so KB creation
uses FirstAllowed when tenant default_provider is empty or disallowed.
Share pickUsableStorageProvider via editorResources for consistent UI
selection, and add regression tests for OBS status and allow-list defaults.
Update the manage_kbs capability to cover the full lifecycle of knowledge bases, including create, copy, duplicate, update, and delete operations. Adjust related API routes and tests to ensure proper access control and policy requirements for knowledge base management.
Prevent in-chat navigation from replacing the active conversation by
opening knowledge-base and citation links in a new tab with
noopener/noreferrer, and apply the same policy to sanitized markdown links.
Stop failing distributed-mode knowledge rows on startup; let housekeeping
decide using span activity and Asynq queue state. In Lite mode, resume
wiki work from durable task_pending_ops and surface SERVER_RESTART errors
in the processing timeline with i18n support.
Move follow-up loading into the answer toolbar so the card only appears when suggestions are ready, and delay toolbar actions until the typewriter finishes revealing the answer.
Replace offset-based page numbers with opaque Redis-backed cursors so
scheduled/retry tasks sort by next run time and live lists stay stable
when queue state changes between requests.
Refactor the error handling logic in the GetKnowledgeSpans function to utilize a new helper function, knowledgeSpansLastError, which consolidates the logic for determining the last error from span failures and knowledge row failures. This improves clarity and maintainability of the code. Additionally, update test cases to cover new scenarios for last error handling.
Latest attempt tabs and header now trust parse_status over a closed root span, surface recovery failures via last_error, and keep attempt hover styles from washing out the active tab.
Align product copy, API docs, Swagger descriptions, and i18n strings
with workspace terminology while keeping internal tenant identifiers
and headers unchanged for API compatibility.
Allow platform system administrators to update builtin model parameters
and credentials from the management UI while keeping secrets masked in API
responses. UI edits clear YAML ownership so startup reconciliation no
longer overwrites runtime overrides.
Added new tests for the ImageMultimodalService to verify the handling of orphan tasks and the finalization of pending counters. Improved runtime task inspection with better error handling and task cancellation logic, ensuring robust management of orphan tasks in the system.
Added new translations and improved existing ones for English, Korean, Russian, and Chinese. Introduced short weight labels, refined failed task notices, and updated queue names and descriptions for better clarity and consistency across languages.
buildParentChildConfigs only copied ChunkSize/ChunkOverlap/Separators into
the parent and child SplitterConfigs, dropping base.Strategy. Since an empty
Strategy resolves to the legacy tier (resolveChainWithProfile treats "" as
legacy for backwards compatibility), parent-child chunking always ran the
legacy recursive splitter regardless of the configured strategy: no heading
alignment and no ContextHeader breadcrumbs in child embeddings, silently.
The flat path (buildSplitterConfigFromChunking) already propagates Strategy;
parent-child predates the strategy system (b3334990, 2026-03) and was not
updated when the 3-tier strategy landed (ae6fde23, 2026-05). SplitParentChild's
docstring ("Child splitting honours childCfg.Strategy") and mergeBreadcrumbs
both assume the strategy reaches the parent-child path.
Copy base.Strategy into both configs and add a regression test.