Commit Graph

741 Commits

Author SHA1 Message Date
wizardchen 9ae17be43c fix(chat): persist attachment content and fix fallback multi-turn context
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.
2026-07-16 17:41:27 +08:00
wizardchen 92ceb3bd7d refactor(chat): enhance follow-up handling for previous image/document context
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.
2026-07-16 17:41:27 +08:00
wizardchen ceb4d1a310 feat(chat): add session-scoped temporary attachments with async parsing
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.
2026-07-16 17:41:27 +08:00
wizardchen 7b2c9e73bf fix(agent): ground follow-up suggestions and preserve KB scope on click
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.
2026-07-15 19:16:53 +08:00
wizardchen fbc9db85d1 fix(chat): enforce retrieved image output in answers
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.
2026-07-15 18:10:31 +08:00
wizardchen a729bc1271 feat(agent): enrich follow-up suggestion generation context
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.
2026-07-15 17:05:24 +08:00
wizardchen 0f4500b98f fix(tests): update resource alias syntax from 'res:' to 'res://' in tests and registry
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.
2026-07-15 17:02:43 +08:00
wizardchen 38c594aec3 feat(chat): implement orphan alias detection and logging in chat completion and streaming
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.
2026-07-15 17:02:43 +08:00
wizardchen 6d14cc3536 feat(resource): add stable resource registry with LLM-context alias compaction
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.
2026-07-15 17:02:43 +08:00
wizardchen a8dea5f9a3 feat(storage): improve storage connectivity error handling and multi-instance support
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.
2026-07-15 14:54:39 +08:00
wizardchen f8b3e5f148 feat(storage): add multi-instance storage backends per workspace
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.
2026-07-15 14:54:39 +08:00
wizardchen 139ec1e6b8 fix(storage): align default provider fallback with STORAGE_ALLOW_LIST
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.
2026-07-15 11:05:00 +08:00
wizardchen ace84bc757 fix(knowledge): recover tasks safely after server restart
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.
2026-07-14 17:55:26 +08:00
wizardchen 41975abcc5 refactor(terminology): rename user-facing tenant labels to workspace
Align product copy, API docs, Swagger descriptions, and i18n strings
with workspace terminology while keeping internal tenant identifiers
and headers unchanged for API compatibility.
2026-07-14 16:14:43 +08:00
wizardchen e1572b71b9 feat(models): let system admins edit builtin model config
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.
2026-07-14 15:56:02 +08:00
wizardchen f409bd756b feat(tests): enhance image multimodal service tests and runtime task handling
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.
2026-07-14 15:38:06 +08:00
wizardchen 4ae48d6acf feat(system): expand runtime queue task inspection and safe actions
Replace failed-only task views with state-aware runtime task listing,
operator-safe cancel/run-now/delete actions, orphan detection, and
multimodal queue cleanup for deleted knowledge rows.
2026-07-14 15:38:06 +08:00
darcy f7ec759cc6 fix(knowledge): propagate chunking strategy to parent-child splitter configs
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.
2026-07-14 11:56:29 +08:00
wizardchen 087fcc9fe7 feat(agent): add question suggestions with after-answer follow-ups
Enable agents to configure starter prompts and async follow-up questions after completed answers, with durable caching, analytics events, and chat/embed UI integration.
2026-07-14 11:17:25 +08:00
wizardchen 8ec65941a5 feat(system): add admin password reset with session revocation
Let system administrators reset another user's local password from the settings UI, revoke all active sessions, and record the action in the audit log.
2026-07-13 20:11:00 +08:00
wizardchen 87ba3fc2de refactor(auth): unify OIDC provisioning under shared default_tenant_mode policy
Drop the standalone OIDC_AUTH_DEFAULT_TENANT_MODE / oidc_auth.default_tenant_mode
knob so OIDC auto-provisioning and local password registration share the single
auth.default_tenant_mode policy (resolved by the callback handler). Repair
tenantless sessions by falling back to the first active membership on the login
happy path and stale-preference paths, allow tenantless PUT /auth/me/preferences,
clear the tenant snapshot on /auth/me responses without a tenant, and default the
frontend canCreateTenant capability to fail-closed until /auth/me confirms it.
2026-07-13 19:14:49 +08:00
wizardchen ecf2c1fb9b feat(auth): support tenantless provisioning and gated self-service workspace creation
Allow deployments to register users without auto-creating a personal tenant, expose creation policy via /auth/me, and guide tenantless accounts through a workspace onboarding flow.
2026-07-13 18:13:51 +08:00
wizardchen 50b8c0a72e fix(security): harden agent share listing and align full-access API key routes
Enforce tenant ownership in ListSharesByAgent so full-access API keys cannot enumerate cross-tenant shares, and allow full-access keys to create KBs and manage share routes consistently with other tenant-wide operations.
2026-07-13 17:09:58 +08:00
wizardchen eacc278b9a fix(wiki): strip internal chunk aliases from page content
Wiki ingest prompts previously encouraged inline [cNNN] citations that
leak internal chunk metadata into reader-facing Markdown. Strip legacy
aliases on read/write paths and update the modify prompt to keep prose
clean while source links remain in ChunkRefs.
2026-07-13 15:59:09 +08:00
wizardchen 07ba01ec93 feat(worker): replace aggregate asynq concurrency with per-pool governance
Split the monolithic upstream worker budget into explicit core, post-process,
enrichment, maintenance, and shared elastic pools, expose live cluster capacity
on the runtime dashboard, and retire the legacy asynq.concurrency setting.
2026-07-13 15:51:06 +08:00
wizardchen 5eefa70e6f Enhance knowledge base configuration by normalizing and validating custom instruction fields. Implemented length checks for prompt instructions and added tests for validation logic. Updated GraphSettings to retain custom instructions when extraction is disabled. 2026-07-13 12:16:19 +08:00
wizardchen c1cddb4d4d Add instruction fields to knowledge base configuration 2026-07-13 12:16:19 +08:00
wizardchen c8793b001d fix(spans): make fitSpanName rune-aware and normalize lookups
Follow-up to the knowledge span name column expansion: truncate span
names by rune count to match PostgreSQL VARCHAR(255), apply the same
normalization in LookupSpanByName, and add regression tests for mid-length
wiki slugs and CJK truncation boundaries.
2026-07-13 10:38:50 +08:00
wizardchen 26f8afa3db fix(spans): expand knowledge span name column and truncate long wiki names
Wiki ingest builds postprocess.wiki.page[<slug>] subspan names that can exceed
varchar(64); widen the column to 255 and hash-suffix truncation so long slugs
still persist distinctly.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-13 10:35:44 +08:00
wizardchen d496d0fc73 feat(task-queue): split upstream workers into isolated core/enrichment/maintenance pools
Route summary/sync/maintenance tasks to dedicated queues and servers so parsing, enrichment, and batch work no longer share one concurrency budget, while extending the runtime dashboard and settings validation to reflect the new topology.
2026-07-10 23:51:29 +08:00
wizardchen fe47ac1f96 feat(system): add runtime task queue observability dashboard for system admins
Expose live asynq queue depths and worker-pool concurrency via a new SystemAdmin API and settings UI, so operators can monitor parsing/wiki backlog without Redis CLI access.
2026-07-10 23:51:29 +08:00
wizardchen b4b63a0c1f feat(tenant): optional legacy auto-create API key on tenant creation
Add a tenant.auto_create_api_key setting (env
WEKNORA_TENANT_AUTO_CREATE_API_KEY, default false) that restores the
pre-break-change behaviour of minting a full_access API key when a
tenant is created and returning its plaintext token in the create
response (data.api_key).

- system_setting: register tenant.auto_create_api_key bool spec
- handler: gate auto key creation behind the setting; embed the token
  via tenantWithAPIKey without re-adding a persisted api_key column;
  key-creation failures log a warning and do not fail tenant creation
- client: add optional Tenant.APIKey field populated only on create
- docs/env: document the switch (.env.example, docker-compose,
  tenant.md, regenerated swagger)
2026-07-10 15:50:15 +08:00
wizardchen 38aacc3113 chore(env): update WEKNORA_MODEL_MAX_CONCURRENCY to 32 in configuration files
Increase the default value of WEKNORA_MODEL_MAX_CONCURRENCY from 8 to 32 in .env.example, docker-compose.yml, and related application code. This change enhances the concurrency limit for background tasks, ensuring better performance and resource management across the system.
2026-07-10 14:51:01 +08:00
wizardchen 4404ea74e3 feat(models): implement model.max_concurrency for background tasks
Add a new `max_concurrency` setting to the model configuration, allowing for fine-tuned control over the maximum number of concurrent background tasks (ingestion/enrichment) per model. This update includes localization support across multiple languages and integrates the setting into the system's concurrency governor, enabling immediate application of changes without requiring a service restart.
2026-07-09 20:40:51 +08:00
wizardchen 76a8092483 refactor(task_queue): enhance claim handling and test coverage
- Renamed TestTaskPendingOps_ClaimBatch_NewSiblingRowNotDoubleClaimed to TestTaskPendingOps_ClaimBatch_LateSiblingBlockedByFreshClaim for clarity on behavior.
- Added new test TestTaskPendingOps_ClaimBatch_LateSiblingClaimableAfterStale to verify claim behavior when a holder crashes.
- Updated ClaimBatch logic to ensure that fresh claims block late siblings entirely, maintaining serialization of same-document operations.
- Improved comments in task_queue.go to clarify the handling of concurrent claims and the implications of the claimed_at field.
- Added crash safety mechanism in ProcessWikiIngest to release claims on abnormal exits, ensuring timely re-claims of pending operations.
2026-07-09 17:41:07 +08:00
wizardchen 60f7f35e40 fix(wiki): recover stranded claims and prevent finalize double-run
- claim/peekPendingList now surface DB errors so a transient load
  failure retries via asynq instead of acking as a false "no pending
  ops" success that strands the queue.
- no_pending_ops now arms a coalesced stale-claim recheck (TaskID
  keyed, delayed past wikiClaimStaleAfter) so rows held by a crashed
  batch's fresh claim are reclaimed automatically instead of sitting
  unclaimable and never re-triggered.
- ProcessWikiFinalize fails CLOSED on a SetNX error (returns an error
  to retry) instead of running unlocked, avoiding two finalize runs
  double-rebuilding the index page.
2026-07-09 17:41:07 +08:00
wizardchen c8a4fd5ba3 fix(wiki): prevent silent work loss and cross-batch doc races
Two correctness fixes on the Phase 3 concurrent claim-based ingest path:

- Slug-lock timeout / reduce failure no longer silently drops work. When a
  per-slug lock can't be acquired within wikiSlugLockWait, or reduce returns
  an error, the page's read-modify-write never lands. Previously the owning
  document was still counted as successful and its pending row was deleted at
  trim time, permanently losing the contribution (finalize only rebuilds the
  index / cross-links, it does not re-run reduce). Such documents are now
  folded into failedOps: their rows stay queued, their finalizing slot is
  held, and requeueFailedOps' fail_count budget retries them (dead-lettering
  a permanently hot/broken slug).

- ClaimBatch now claims by dedup_key affinity so a document is never split
  across concurrent batches. limit counts distinct dedup_keys (documents),
  and ALL eligible rows sharing a key are claimed together. On Postgres the
  per-key anchor row is locked with FOR UPDATE SKIP LOCKED, handing
  concurrent claimers disjoint key sets. This restores in-document ordering
  (e.g. ingest-then-retract collapses correctly) that the per-batch dedup
  could not guarantee once the exclusive per-KB lock was removed, preventing
  a stale ingest from resurrecting a retracted document.

Adds repository tests for same-key affinity and in-flight sibling rows.
2026-07-09 17:41:07 +08:00
wizardchen 70e2e85fa6 feat(wiki): dedicated worker pool with concurrent claim-based batching
Isolate the wiki generation pipeline from the document parse pipeline so
the two can no longer starve each other during concurrent uploads.

- Dedicated asynq worker pool for QueueWiki (NewWikiAsynqServer) with its
  own concurrency budget (WEKNORA_WIKI_ASYNQ_CONCURRENCY / asynq.wiki_
  concurrency, default 16), split from the parse pool (NewParseAsynqServer).
  Both run the same mux over disjoint queue sets. Replaces the old
  weighted-lottery approach where wiki sat on the low queue (weight 1).
- Task queue: add ClaimBatch (SELECT ... FOR UPDATE SKIP LOCKED + claimed_at)
  and ReleaseByIDs so multiple concurrent consumers pull disjoint rows
  without an external per-KB lock; PeekBatch retained for Lite mode.
- New TypeWikiFinalize debounced KB-global finalize task (index rebuild /
  dead-link cleanup / cross-linking), registered on both Redis and Lite paths.
- Two-level wiki ingest concurrency: IngestMaxInflight caps concurrent
  batches per KB; Map/Reduce fan-out sized within a batch. New config knob
  + system setting + swagger docs.
2026-07-09 17:41:07 +08:00
wizardchen b6d3420a5d fix: harden document pipeline concurrency and diagnostics
- docreader: serialize all pdfium access behind a global lock. pypdfium2
  is process-global and not thread-safe, so concurrent PDF uploads could
  corrupt its shared state and deadlock the whole process (requests stuck
  in "Parsing document" forever). Non-PDF parsers still run concurrently.
- logger: strip ANSI color escapes from file logs so on-disk logs stay
  plain text while stdout keeps terminal colors.
- storage: log baseDir/resolvedPath on file-open failure and when the
  multimodal service resolves a file service, so a LOCAL_STORAGE_BASE_DIR
  mismatch between writer and reader is immediately visible.
- docker: set TZ (default Asia/Shanghai) for the docreader container.
2026-07-09 13:26:40 +08:00
wizardchen 6ac1703198 Simplify KB duplicate API and improve naming/docs coverage.
Drop client-supplied target_id, generate IDs server-side, localize duplicate
names from request language, document the endpoint, and expand handler/client tests.
2026-07-08 20:55:54 +08:00
wizardchen 58b79876ae Add knowledge base duplicate flow 2026-07-08 20:55:54 +08:00
wizardchen a1b49e2664 fix(faq): guard against division by zero in import timing logs
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 15:27:51 +08:00
wizardchen d9bb7aa8f2 fix(search): harden tag scope resolution after #1907
Default missing KB metadata to document tag relation lookup, propagate tag resolution failures instead of returning empty results, and reject ambiguous bare tag_ids when multiple knowledge bases are in scope.
2026-07-08 10:55:42 +08:00
wizardchen 45eab4a95f fix(quick-qa): distinguish web and knowledge base retrieval in pipeline UI
Emit search_source metadata from RAG progress events so quick-answer steps,
summaries, and IM labels no longer mislabel web-only results as knowledge base search.
2026-07-08 00:26:34 +08:00
Ilya Bogin 8cf9f1c882 feat: add Keenable as a configurable web search provider
Add Keenable Search alongside the existing DuckDuckGo / Bing / Google /
Tavily / Ollama / Baidu / SearXNG providers.

- internal/infrastructure/web_search/keenable.go: KeenableProvider
  implementing the WebSearchProvider interface, following the Tavily
  provider pattern. Keyless by default: with no API key it calls the
  public endpoint (/v1/search/public, rate-limited); a key switches to
  /v1/search and lifts the cap. Base URL is hardcoded (SSRF-safe), proxy
  is honored.
- Registered "keenable" in the container registry.
- Added the keenable provider type + type metadata (RequiresAPIKey=false)
  and service validation (no required key, like DuckDuckGo).
- Provider-specific empty-results diagnostic (keyless rate-limit hint).
- Frontend: extend the provider union type with 'keenable'.
- Unit tests: keyless vs keyed endpoint, attribution header, maxResults
  trim, result mapping, error status, name.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 16:58:26 +08:00
wizardchen 2c6f082062 Refine scoped API key capabilities 2026-07-07 12:00:13 +08:00
wizardchen b5cc7d2a28 feat(api-keys): implement throttled last_used_at updates for API key authentication
Enhance the tenant API key service by introducing asynchronous throttling for the last_used_at updates during API key authentication. This change reduces database write frequency under high request rates, improving performance. Additionally, update tests to validate the throttling behavior, ensuring that last_used_at is only updated once per key within the defined interval. This implementation aligns with the goal of optimizing API key management and maintaining system efficiency.
2026-07-07 12:00:13 +08:00
wizardchen 97c36f634a refactor(api-keys): remove API key reset endpoint and update documentation
Eliminate the POST /tenants/{id}/api-key endpoint for resetting tenant API keys, transitioning to a more granular API key management approach. Update related documentation and API specifications to reflect the new structure, including changes to the tenant API key management paths. Adjust frontend code and internationalization files to remove references to the deprecated API key reset functionality, enhancing clarity and consistency across the application.
2026-07-07 12:00:13 +08:00
wizardchen d2ffc1b973 refactor(api-keys): simplify authorization to a single-role gate
Redesign tenant API key authorization around one dimension (role) plus a
central default-deny gate, replacing the previous role + KB-scoped flag model.

- Add APIKeyGate as the single authority for API-key authorization: routes
  declare one policy (MinRole) via apiKeyGroup/apiKeyRoute helpers; undeclared
  routes are denied by default. JWT principals short-circuit the gate and the
  JWT-centric RBAC guards short-circuit for API-key principals.
- Roles: viewer/contributor/admin are knowledge-base data-plane only (KB scope
  is a pure downstream data filter); owner is a full-access tenant tier that
  unlocks tenant-level infrastructure routes and is required for every method.
- Drop the KBScoped policy flag and the KB-restricted-vs-tenant branching.
- Security hardening: never disclose HMAC secret (return presence only), abort
  writes on API-key encryption failure, deny KB-restricted keys on /files, and
  backfill legacy key hashes at startup instead of O(N) plaintext scans.
- Frontend: two-level create dialog (access type -> permission level), rename
  role labels to reflect actual scope, sync en/zh/ko/ru locales.
- Fix startup self-check false-positive on trailing-slash routes and normalize
  gin paths before comparison; add regression tests.
2026-07-07 12:00:13 +08:00
wizardchen 9a76a24ce6 refactor(api-keys): use role field and route-level API key guards
Replace scopes JSON with a viewer/contributor/admin role column, move
unsafe-method authorization from path-prefix middleware to declarative
APIKey* guards on routes, and close remaining KB-scope gaps in handlers.
2026-07-07 12:00:13 +08:00