Commit Graph
1622 Commits
Author SHA1 Message Date
wizardchen f58139a945 fix(frontend): persist graph extract toggle state on KB save (#1297)
The "启用实体关系提取" switch in GraphSettings was silently dropped on
save: buildSubmitData only attached extract_config to the request when
both indexingStrategy.graphEnabled AND nodeExtractConfig.enabled were
true. When the graph indexing strategy was off (the default), the
toggle change never reached the backend and reloading the KB always
showed the switch as off.

Always emit extract_config based on the user's actual toggle state so
the value round-trips correctly through updateKBConfig regardless of
the indexing strategy selection.
2026-05-13 00:40:58 +08:00
wizardchen 9e08ab7302 fix(chat): map MaxTokens to MaxCompletionTokens for GPT-5/o-series
OpenAI's GPT-5 series and o-series reasoning models (o1/o3/o4-mini) no
longer accept `max_tokens` and reject non-default sampling params
(`temperature`, `top_p`, `frequency_penalty`, `presence_penalty`).
Azure OpenAI propagates the same constraint, returning HTTP 400 with
"this model is not supported MaxTokens, please use MaxCompletionTokens".

Lower the compatibility shim into `RemoteAPIChat.BuildChatCompletionRequest`
(the single OpenAI-protocol egress) so every internal caller keeps using
`MaxTokens` uniformly:

- Add `provider.IsOpenAIReasoningOrGPT5Model` with precise prefix matching
  (covers `gpt-5*`, `o1`/`o1-*`, `o3`/`o3-*`, `o4`/`o4-*`; rejects
  `olympus-1`, `openai-*`, `o3xtra`, etc.).
- When the provider is `openai`/`azure_openai` and the model matches, map
  `MaxTokens` to `MaxCompletionTokens` (explicit `MaxCompletionTokens`
  wins) and skip the unsupported sampling fields; `omitempty` keeps them
  off the wire.
- Behavior is unchanged for gpt-4o, gpt-4, and all other providers.

Add unit tests for the matcher and for the request-building path
(Azure gpt-5.2, OpenAI gpt-5/o1-mini/o3/o4-mini, plus negative cases).

Fixes #1283
2026-05-13 00:40:35 +08:00
langcaiye 4d2b8707ff fix: support Anthropic gateway streaming 2026-05-13 00:14:23 +08:00
wizardchen 55caeefc3d feat(observability): log end-to-end TTFB on both ends of chat stream
To diagnose where latency lives between "user hits send" and "first
token appears" we need a single number that can be matched across
the browser console and the server log. Add correlated TTFB markers
keyed by X-Request-ID:

Frontend (streame.ts)

* Generate the X-Request-ID once and reuse it for logging.
* Log request:start when fetchEventSource is invoked, response:headers
  when onopen fires, and response:first_answer the first time an SSE
  payload with response_type === 'answer' arrives. Filtering by event
  type avoids treating session_title / references / tool_call as the
  "first token".

Backend (session handler)

* parseQARequest records the wall-clock entry time and logs TTFB:start
  with the same X-Request-ID.
* qaRequestContext carries receivedAt through to the stream handler.
* AgentStreamHandler emits a one-shot TTFB:first_answer_chunk log the
  first time it observes an AgentFinalAnswerData chunk, so the delta
  against TTFB:start is the server's request-in → first-token-out
  budget.

The frontend delta minus the backend delta is then attributable to
network + gin middleware, which were previously invisible.
2026-05-12 21:16:37 +08:00
wizardchen f740e7cecf feat(observability): expand Langfuse spans across chat pipeline
Previously the Langfuse timeline for a knowledge-chat request only
showed generations (chat.completion, embedding.embed, rerank), so the
work happening between them — query setup, vector/keyword search,
result merging, prompt assembly — appeared as unexplained gaps.

Add spans around the pieces that fill those gaps:

* qa.setup wraps request-time KB / model / search-target resolution
  before the pipeline event loop starts, accounting for the visible
  delay before the first chat.completion.
* pipeline.<event> wraps each pipeline stage's eventManager.Trigger
  call so generations inside a stage nest under it. CHAT_COMPLETION_
  STREAM is intentionally skipped because its OnEvent returns as soon
  as the streaming goroutine starts; a stage span would always finish
  before the chat.completion.stream generation it nominally parents.
* retrieve wraps the actual vector + keyword retrieve call inside
  HybridSearch, exposing the DB round-trip that previously sat invisibly
  between embedding generations and rerank.
* web_search wraps the external web-search HTTP call when enabled.
2026-05-12 21:16:37 +08:00
wizardchen 64b20a2d87 feat(agent): support dedicated model for query understanding step
Quick-answer (RAG) agents can now configure a separate chat model for
the query-understanding stage (rewrite + intent classification),
decoupling it from the main conversation model so users can route the
lightweight rewrite call to a cheaper / faster model.

- Add CustomAgentConfig.QueryUnderstandModelID and plumb it through
  PipelineRequest and ChatManage.Clone.
- query_understand plugin prefers QueryUnderstandModelID on the
  text-only path; falls back to ChatModelID if the configured model
  cannot be resolved (with a warn log). Multimodal path is unchanged
  to keep vision-capable model selection intact.
- AgentEditorModal exposes a ModelSelector under the existing Query
  Rewrite block; empty means reuse the main chat model.
- Add i18n strings (queryUnderstandModel / placeholder / desc) for
  zh-CN, en-US, ko-KR, ru-RU.
- Extend Go SDK AgentConfig with the new field.
2026-05-12 20:27:20 +08:00
wizardchen 1f60d19f1b fix(agent-editor): move data-analysis toggle to retrieval section
The data-analysis pipeline stage is a retrieval-strategy concern (it only
runs after chunk search/rerank), so the toggle belongs alongside the other
retrieval knobs rather than under knowledge base settings.

Refs: https://github.com/Tencent/WeKnora/issues/1244
2026-05-12 19:46:31 +08:00
wizardchen 3f9b09e306 fix(pipeline): make data-analysis stage opt-in per agent (#1244)
The legacy in-pipeline DuckDB SQL data-analysis stage used to run on every
quick-answer RAG request whose retrieved chunks included a CSV/Excel file,
adding one extra LLM round-trip (~3s) to generate a SQL query that most
plain Q&A users never wanted. There was no way to disable it.

Introduce a per-agent DataAnalysisEnabled flag (default off), wire it
through PipelineRequest, and gate the DATA_ANALYSIS stage on it. Surface
the toggle in the agent editor for quick-answer agents with at least one
knowledge base attached.

Refs: https://github.com/Tencent/WeKnora/issues/1244
2026-05-12 19:39:35 +08:00
wizardchen 86b05d923e fix(middleware): mask camelCase secret fields in request logs
The request logger's sanitizeBody only matched lowercase / snake_case
field names (api_key, apikey, access_token, ...), so values for the
camelCase JSON fields actually used by the API (apiKey, secretKey,
refreshToken, accessToken, ...) were written to logs in clear text.

Replace the per-field patterns with a single case-insensitive regex
that tolerates optional `_`/`-` separators, covering snake_case,
camelCase and PascalCase variants, and extend coverage to id_token,
client_secret, private_key, auth_token, api_secret and passwd. The
field name is preserved; only its value is replaced with "***".

Add unit tests for sanitizeBody covering the previously-leaking
camelCase fields and common variants.

Fixes #1287
2026-05-12 19:27:29 +08:00
wizardchen cacca049d9 feat(knowledge-base): document list filters and explicit batch-management UX
Add three new optional filters to the document list under a knowledge base
detail page — parse status, source/channel, and updated time range — and
rework multi-select to no longer cause the card title to jitter on hover.

Backend
- Introduce types.KnowledgeListFilter to aggregate optional filter dimensions
  (tag, keyword, file_type, parse_status, source, updated_from/to) and switch
  ListPagedKnowledgeByKnowledgeBaseID (repository/service/interface) to accept
  it instead of a growing positional parameter list.
- The ListKnowledge HTTP handler accepts new parse_status, source, start_time
  and end_time query params; time params accept RFC3339, "YYYY-MM-DD HH:MM:SS"
  and "YYYY-MM-DD". The repository routes source="manual"/"url" onto the type
  column to stay consistent with file_type semantics; other source values match
  the channel column.
- Update the four other callers (agent_service, initialization) to pass an
  empty filter struct, preserving prior behavior.

Frontend
- Add three controls in the doc-filter-bar (status select, source select,
  date-range picker with future-date disabled) wired through getKnowled /
  listKnowledgeFiles into the new backend params.
- Replace the hover-triggered card checkbox with an explicit "批量管理" mode
  (mirrors the session list UX): in card view the checkbox only renders while
  batch mode is on, entered via the per-card "..." menu; the list view keeps
  its leading checkbox column. Switching from list to grid auto-enables batch
  mode when something is already selected, so the selection stays visible.
- DocumentBatchBar now stays open whenever batch mode or selection > 0, and
  its "取消选择" button both clears the selection and exits batch mode.

API surface sync
- Regenerate Swagger artifacts (docs/docs.go / swagger.json / swagger.yaml).
- Update docs/api/knowledge.md with the new query parameters.
- Add backward-compatible ListKnowledgeWithFilter + KnowledgeListFilter to the
  Go SDK; the existing ListKnowledge keeps its signature.

i18n
- New filter labels in zh-CN / en-US / ko-KR / ru-RU; reuse existing
  menu.batchManage / batchManage.cancel for the multi-select strings.
2026-05-12 18:29:47 +08:00
wizardchen f635eaf466 chore(github): translate templates to English and improve content
- Convert issue and PR templates to English only for broader reach
- Bug report: add Steps to Reproduce, Actual Behavior, WeKnora Version,
  and Deployment Method as required fields; expand log guide to cover
  Lite / Desktop / source builds
- Feature request: replace user-selected Priority with Impact to reduce
  severity inflation
- PR template: slim down to 6 sections, add Conventional Commits hint
  in the title, and require `make fmt && make lint && make test` in the
  checklist
2026-05-12 18:28:08 +08:00
wolfkill b387f3637a fix(feishu): tolerate partial wiki node listing failures 2026-05-12 17:40:59 +08:00
wizardchen 8b2a36d759 fix(multimodal): unblock processing when provider:// image read fails
When image bytes for a multimodal task cannot be read via FileService
(e.g. tenant.StorageEngineConfig.MinIO is empty while the image was
saved using the global MINIO_* env vars), the previous code fell back
to the HTTP downloader, which rejected the provider:// URL with
"unsupported URL scheme". The asynq handler then returned an error,
asynq retried until exhaustion, and the per-knowledge "pending images"
counter was never decremented — leaving the document stuck in
"processing" indefinitely (issue #1282).

Changes:
- ImageMultimodalService now holds a default FileService and
  resolveFileServiceForPayload falls back to it when the tenant-scoped
  storage config cannot produce a usable service, mirroring the
  write-side fallback in knowledgeService.resolveFileService.
- Extract readImageBytes: provider:// URLs are read exclusively via
  FileService and never handed to the HTTP downloader.
- On unrecoverable read failure for a single image, log and skip that
  image but still call checkAndFinalizeAllImages so the parent
  knowledge can progress to post-processing.

Fixes #1282
2026-05-12 17:40:04 +08:00
langcaiye 42d98261e7 feat: support Anthropic chat provider 2026-05-12 17:33:16 +08:00
wizardchen 5949be739f fix(agent): relax rerank model requirement for custom agents
Previously the custom agent editor hid the rerank model field when no
RAG-type knowledge base existed in the configured scope, but the
not-ready check and runtime hard-failed whenever knowledge_search was
in allowed_tools. Users with wiki-only or empty scopes saw "Rerank
Model required" warnings they could not resolve, and "All knowledge
bases" agents broke later if a RAG-type KB was added.

- Backend: when knowledge_search is enabled, fall back to the tenant
  default rerank model (ConversationConfig.RerankModelID) before
  erroring out, matching the built-in agent behaviour.
- Editor: always show the rerank field once a KB scope is selected;
  only mark it required (red *) when the scope contains a RAG KB, with
  a hint explaining the tenant-default fallback.
- Editor: only render rerank top_k / threshold sliders when a rerank
  model is actually selected.
- Input field: drop the eager "missing rerank" not-ready reason; the
  backend is now the single source of truth for rerank availability.
- i18n: add agent.editor.rerankModelOptionalHint across all locales.
2026-05-12 16:57:24 +08:00
nullkey 4ed7b90eac fix(faq): correct PostgreSQL cast precedence in FAQ search
`metadata->'similar_questions'::text` parses as
`metadata -> ('similar_questions'::text)` because `::` binds tighter
than `->`, so the expression yields jsonb instead of text. ILIKE on
jsonb then fails with "operator does not exist: jsonb ~~* unknown",
returning 1007 Internal server error for `search_field=similar_questions`
and `search_field=answers`. The `standard_question` branch was unaffected
because it uses `->>` (text) directly.

Wrap the json access in parens so the cast applies to the extracted
value: `(metadata->'similar_questions')::text ILIKE ?`. The MySQL
branch uses JSON_EXTRACT and is unchanged.

Fixes #1264
2026-05-12 16:42:21 +08:00
wizardchen d199628701 fix(agent): exclude wiki-only KBs from quick-answer (RAG) mode
Quick-answer agent mode retrieves purely through vector/keyword chunk
search and ships with no `allowed_tools`, so the existing capability
filter (which only reads from `allowed_tools`) let wiki-only KBs through
in every entry point. End result: users could @-mention, select, and
receive suggested questions from wiki-only KBs in quick-answer mode,
but the underlying retrieval always returned empty.

Treat "RAG-only" as an implicit property of `agent_mode = quick-answer`
and union it with the tool-derived filter. The same predicate is now
used everywhere the user can pick or be steered toward a KB:

Backend
- `tools.DeriveKBFilterForAgent` / `KBSatisfiesAgentRequirements`
  layer the implicit quick-answer requirement on top of tool derivation.
- `ListKnowledgeBases`, `SearchKnowledge` (shared-agent `@file`),
  `resolveKnowledgeBasesFromAgent` (chat runtime), `/search` IM command,
  and `GetSuggestedQuestions` now all use the agent-mode-aware variant.
- `GetSuggestedQuestions` also skips the wiki-page fallback for
  quick-answer agents to cover the `selected` / explicit-kb-ids paths
  where a wiki-only KB could still slip through.

Frontend
- `deriveKbFilterForAgent` / `kbSatisfiesAgentRequirements` mirror the
  Go helpers.
- `@` mention dropdown (`Input-field.vue`) uses the new helper.
- Agent editor's "specified KB" picker (`AgentEditorModal.vue`) grays
  out wiki-only KBs for quick-answer agents with a tooltip, and the
  pre-save warning fires for quick-answer mode too.
- i18n: add `agentEditor.agentType.kbMismatch.quickAnswer` across all
  four locales.
2026-05-12 16:27:28 +08:00
wizardchen a082c04d28 chore(deps): update dependencies in /docreader and adjust dependabot configuration
- Updated `pydantic` from 2.12.3 to 2.13.4 and `pypdfium2` from 5.0.0 to 5.8.0 in the `docreader` requirements.
- Modified the dependabot configuration to set `open-pull-requests-limit` to 0 and added an `ignore` rule for version updates across all ecosystems, allowing only security updates.
- Adjusted settings for `server-security`, `client-security`, `frontend-security`, and `miniprogram-security` groups to streamline security update handling.

This change aims to enhance dependency management and maintain security while reducing noise from version update PRs.
2026-05-12 14:58:52 +08:00
wizardchen 9ad8e7ca78 fix(agent): replay attachments in multi-turn history
Agent mode does not persist `rendered_content` for user messages, so
when the next turn's history was rebuilt from DB, attachments uploaded
in prior turns disappeared — the model only saw the raw query plus the
prior assistant reply, breaking follow-up questions that referenced
the file (e.g. "what is in there?").

Reconstruct the attachment prompt from the stored `Attachments` column
when `RenderedContent` is empty, mirroring how image captions are
already replayed. KnowledgeQA turns (which do persist
`RenderedContent`) are unaffected and won't get attachments injected
twice.

Refs #1237
2026-05-12 14:46:57 +08:00
dependabot[bot] d2fb51b809 chore(deps-dev): bump typescript from 5.8.3 to 6.0.3 in /frontend
Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.8.3 to 6.0.3.
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.8.3...v6.0.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-version: 6.0.3
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 14:29:51 +08:00
dependabot[bot] b1ea90490f chore(deps): update pypdfium2 requirement in /docreader
Updates the requirements on [pypdfium2](https://github.com/pypdfium2-team/pypdfium2) to permit the latest version.
- [Release notes](https://github.com/pypdfium2-team/pypdfium2/releases)
- [Commits](https://github.com/pypdfium2-team/pypdfium2/compare/5.0.0...5.8.0)

---
updated-dependencies:
- dependency-name: pypdfium2
  dependency-version: 5.8.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 14:29:29 +08:00
dependabot[bot] 7ef37c8502 chore(deps): update pydantic requirement in /docreader
Updates the requirements on [pydantic](https://github.com/pydantic/pydantic) to permit the latest version.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/v2.13.4/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.12.3...v2.13.4)

---
updated-dependencies:
- dependency-name: pydantic
  dependency-version: 2.13.4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 14:29:13 +08:00
dependabot[bot] 3675c0f656 chore(deps): bump github.com/spf13/pflag in /cli in the cli-deps group
Bumps the cli-deps group in /cli with 1 update: [github.com/spf13/pflag](https://github.com/spf13/pflag).


Updates `github.com/spf13/pflag` from 1.0.9 to 1.0.10
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.9...v1.0.10)

---
updated-dependencies:
- dependency-name: github.com/spf13/pflag
  dependency-version: 1.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cli-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 13:33:18 +08:00
dependabot[bot] 6b72ea9254 chore(deps): bump the server-deps group with 25 updates
Bumps the server-deps group with 25 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/JohannesKaufmann/html-to-markdown/v2](https://github.com/JohannesKaufmann/html-to-markdown) | `2.5.0` | `2.5.1` |
| [github.com/PuerkitoBio/goquery](https://github.com/PuerkitoBio/goquery) | `1.10.3` | `1.12.0` |
| [github.com/elastic/go-elasticsearch/v8](https://github.com/elastic/go-elasticsearch) | `8.18.0` | `8.19.6` |
| [github.com/gin-contrib/cors](https://github.com/gin-contrib/cors) | `1.7.5` | `1.7.7` |
| [github.com/gin-gonic/gin](https://github.com/gin-gonic/gin) | `1.11.0` | `1.12.0` |
| [github.com/golang-jwt/jwt/v5](https://github.com/golang-jwt/jwt) | `5.3.0` | `5.3.1` |
| [github.com/hibiken/asynq](https://github.com/hibiken/asynq) | `0.25.1` | `0.26.0` |
| [github.com/larksuite/oapi-sdk-go/v3](https://github.com/larksuite/oapi-sdk-go) | `3.5.3` | `3.6.1` |
| [github.com/mark3labs/mcp-go](https://github.com/mark3labs/mcp-go) | `0.43.0` | `0.52.0` |
| [github.com/panjf2000/ants/v2](https://github.com/panjf2000/ants) | `2.11.3` | `2.12.0` |
| [github.com/pganalyze/pg_query_go/v6](https://github.com/pganalyze/pg_query_go) | `6.1.0` | `6.2.2` |
| [github.com/qdrant/go-client](https://github.com/qdrant/go-client) | `1.16.1` | `1.18.1` |
| [github.com/redis/go-redis/v9](https://github.com/redis/go-redis) | `9.14.0` | `9.14.1` |
| [github.com/slack-go/slack](https://github.com/slack-go/slack) | `0.18.0-rc2` | `0.23.1` |
| [github.com/spf13/viper](https://github.com/spf13/viper) | `1.20.1` | `1.21.0` |
| [github.com/tencentyun/cos-go-sdk-v5](https://github.com/tencentyun/cos-go-sdk-v5) | `0.7.65` | `0.7.73` |
| [github.com/weaviate/weaviate](https://github.com/weaviate/weaviate) | `1.37.2` | `1.37.3` |
| [github.com/weaviate/weaviate-go-client/v5](https://github.com/weaviate/weaviate-go-client) | `5.5.0` | `5.7.3` |
| [github.com/yanyiwu/gojieba](https://github.com/yanyiwu/gojieba) | `1.4.5` | `1.4.7` |
| [go.opentelemetry.io/otel/exporters/stdout/stdouttrace](https://github.com/open-telemetry/opentelemetry-go) | `1.35.0` | `1.43.0` |
| [go.uber.org/dig](https://github.com/uber-go/dig) | `1.18.1` | `1.19.0` |
| [golang.org/x/mod](https://github.com/golang/mod) | `0.35.0` | `0.36.0` |
| [golang.org/x/net](https://github.com/golang/net) | `0.53.0` | `0.54.0` |
| [golang.org/x/time](https://github.com/golang/time) | `0.14.0` | `0.15.0` |
| [google.golang.org/api](https://github.com/googleapis/google-api-go-client) | `0.265.0` | `0.278.0` |


Updates `github.com/JohannesKaufmann/html-to-markdown/v2` from 2.5.0 to 2.5.1
- [Release notes](https://github.com/JohannesKaufmann/html-to-markdown/releases)
- [Commits](https://github.com/JohannesKaufmann/html-to-markdown/compare/v2.5.0...v2.5.1)

Updates `github.com/PuerkitoBio/goquery` from 1.10.3 to 1.12.0
- [Release notes](https://github.com/PuerkitoBio/goquery/releases)
- [Commits](https://github.com/PuerkitoBio/goquery/compare/v1.10.3...v1.12.0)

Updates `github.com/elastic/go-elasticsearch/v8` from 8.18.0 to 8.19.6
- [Release notes](https://github.com/elastic/go-elasticsearch/releases)
- [Changelog](https://github.com/elastic/go-elasticsearch/blob/v8.19.6/CHANGELOG.md)
- [Commits](https://github.com/elastic/go-elasticsearch/compare/v8.18.0...v8.19.6)

Updates `github.com/gin-contrib/cors` from 1.7.5 to 1.7.7
- [Release notes](https://github.com/gin-contrib/cors/releases)
- [Commits](https://github.com/gin-contrib/cors/compare/v1.7.5...v1.7.7)

Updates `github.com/gin-gonic/gin` from 1.11.0 to 1.12.0
- [Release notes](https://github.com/gin-gonic/gin/releases)
- [Changelog](https://github.com/gin-gonic/gin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gin-gonic/gin/compare/v1.11.0...v1.12.0)

Updates `github.com/golang-jwt/jwt/v5` from 5.3.0 to 5.3.1
- [Release notes](https://github.com/golang-jwt/jwt/releases)
- [Commits](https://github.com/golang-jwt/jwt/compare/v5.3.0...v5.3.1)

Updates `github.com/hibiken/asynq` from 0.25.1 to 0.26.0
- [Release notes](https://github.com/hibiken/asynq/releases)
- [Changelog](https://github.com/hibiken/asynq/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hibiken/asynq/compare/v0.25.1...v0.26.0)

Updates `github.com/larksuite/oapi-sdk-go/v3` from 3.5.3 to 3.6.1
- [Release notes](https://github.com/larksuite/oapi-sdk-go/releases)
- [Changelog](https://github.com/larksuite/oapi-sdk-go/blob/v3_main/changelog.md)
- [Commits](https://github.com/larksuite/oapi-sdk-go/compare/v3.5.3...v3.6.1)

Updates `github.com/mark3labs/mcp-go` from 0.43.0 to 0.52.0
- [Release notes](https://github.com/mark3labs/mcp-go/releases)
- [Commits](https://github.com/mark3labs/mcp-go/compare/v0.43.0...v0.52.0)

Updates `github.com/panjf2000/ants/v2` from 2.11.3 to 2.12.0
- [Release notes](https://github.com/panjf2000/ants/releases)
- [Commits](https://github.com/panjf2000/ants/compare/v2.11.3...v2.12.0)

Updates `github.com/pganalyze/pg_query_go/v6` from 6.1.0 to 6.2.2
- [Changelog](https://github.com/pganalyze/pg_query_go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pganalyze/pg_query_go/compare/v6.1.0...v6.2.2)

Updates `github.com/qdrant/go-client` from 1.16.1 to 1.18.1
- [Release notes](https://github.com/qdrant/go-client/releases)
- [Commits](https://github.com/qdrant/go-client/compare/v1.16.1...v1.18.1)

Updates `github.com/redis/go-redis/v9` from 9.14.0 to 9.14.1
- [Release notes](https://github.com/redis/go-redis/releases)
- [Changelog](https://github.com/redis/go-redis/blob/v9.14.1/RELEASE-NOTES.md)
- [Commits](https://github.com/redis/go-redis/compare/v9.14.0...v9.14.1)

Updates `github.com/slack-go/slack` from 0.18.0-rc2 to 0.23.1
- [Release notes](https://github.com/slack-go/slack/releases)
- [Changelog](https://github.com/slack-go/slack/blob/master/CHANGELOG.md)
- [Commits](https://github.com/slack-go/slack/compare/v0.18.0-rc2...v0.23.1)

Updates `github.com/spf13/viper` from 1.20.1 to 1.21.0
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.20.1...v1.21.0)

Updates `github.com/tencentyun/cos-go-sdk-v5` from 0.7.65 to 0.7.73
- [Release notes](https://github.com/tencentyun/cos-go-sdk-v5/releases)
- [Changelog](https://github.com/tencentyun/cos-go-sdk-v5/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tencentyun/cos-go-sdk-v5/compare/v0.7.65...v0.7.73)

Updates `github.com/weaviate/weaviate` from 1.37.2 to 1.37.3
- [Release notes](https://github.com/weaviate/weaviate/releases)
- [Commits](https://github.com/weaviate/weaviate/compare/v1.37.2...v1.37.3)

Updates `github.com/weaviate/weaviate-go-client/v5` from 5.5.0 to 5.7.3
- [Release notes](https://github.com/weaviate/weaviate-go-client/releases)
- [Commits](https://github.com/weaviate/weaviate-go-client/compare/v5.5.0...v5.7.3)

Updates `github.com/yanyiwu/gojieba` from 1.4.5 to 1.4.7
- [Release notes](https://github.com/yanyiwu/gojieba/releases)
- [Changelog](https://github.com/yanyiwu/gojieba/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yanyiwu/gojieba/compare/v1.4.5...v1.4.7)

Updates `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` from 1.35.0 to 1.43.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.35.0...v1.43.0)

Updates `go.uber.org/dig` from 1.18.1 to 1.19.0
- [Release notes](https://github.com/uber-go/dig/releases)
- [Changelog](https://github.com/uber-go/dig/blob/master/CHANGELOG.md)
- [Commits](https://github.com/uber-go/dig/compare/v1.18.1...v1.19.0)

Updates `golang.org/x/mod` from 0.35.0 to 0.36.0
- [Commits](https://github.com/golang/mod/compare/v0.35.0...v0.36.0)

Updates `golang.org/x/net` from 0.53.0 to 0.54.0
- [Commits](https://github.com/golang/net/compare/v0.53.0...v0.54.0)

Updates `golang.org/x/time` from 0.14.0 to 0.15.0
- [Commits](https://github.com/golang/time/compare/v0.14.0...v0.15.0)

Updates `google.golang.org/api` from 0.265.0 to 0.278.0
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.265.0...v0.278.0)

---
updated-dependencies:
- dependency-name: github.com/JohannesKaufmann/html-to-markdown/v2
  dependency-version: 2.5.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: server-deps
- dependency-name: github.com/PuerkitoBio/goquery
  dependency-version: 1.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: github.com/elastic/go-elasticsearch/v8
  dependency-version: 8.19.6
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: github.com/gin-contrib/cors
  dependency-version: 1.7.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: server-deps
- dependency-name: github.com/gin-gonic/gin
  dependency-version: 1.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: github.com/golang-jwt/jwt/v5
  dependency-version: 5.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: server-deps
- dependency-name: github.com/hibiken/asynq
  dependency-version: 0.26.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: github.com/larksuite/oapi-sdk-go/v3
  dependency-version: 3.6.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: github.com/mark3labs/mcp-go
  dependency-version: 0.52.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: github.com/panjf2000/ants/v2
  dependency-version: 2.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: github.com/pganalyze/pg_query_go/v6
  dependency-version: 6.2.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: github.com/qdrant/go-client
  dependency-version: 1.18.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: github.com/redis/go-redis/v9
  dependency-version: 9.14.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: server-deps
- dependency-name: github.com/slack-go/slack
  dependency-version: 0.23.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: github.com/spf13/viper
  dependency-version: 1.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: github.com/tencentyun/cos-go-sdk-v5
  dependency-version: 0.7.73
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: server-deps
- dependency-name: github.com/weaviate/weaviate
  dependency-version: 1.37.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: server-deps
- dependency-name: github.com/weaviate/weaviate-go-client/v5
  dependency-version: 5.7.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: github.com/yanyiwu/gojieba
  dependency-version: 1.4.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: server-deps
- dependency-name: go.opentelemetry.io/otel/exporters/stdout/stdouttrace
  dependency-version: 1.43.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: go.uber.org/dig
  dependency-version: 1.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: golang.org/x/mod
  dependency-version: 0.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: golang.org/x/net
  dependency-version: 0.54.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: golang.org/x/time
  dependency-version: 0.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
- dependency-name: google.golang.org/api
  dependency-version: 0.278.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: server-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 13:30:44 +08:00
dependabot[bot] ae1ea181f5 chore(deps): bump the frontend-deps group in /frontend with 15 updates
Bumps the frontend-deps group in /frontend with 15 updates:

| Package | From | To |
| --- | --- | --- |
| [axios](https://github.com/axios/axios) | `1.15.0` | `1.16.0` |
| [mermaid](https://github.com/mermaid-js/mermaid) | `11.14.0` | `11.15.0` |
| [pagefind](https://github.com/Pagefind/pagefind) | `1.3.0` | `1.5.2` |
| [pinia](https://github.com/vuejs/pinia) | `3.0.3` | `3.0.4` |
| [swiper](https://github.com/nolimits4web/Swiper) | `12.1.2` | `12.1.4` |
| [tdesign-icons-vue-next](https://github.com/Tencent/tdesign-icons/tree/HEAD/packages/vue-next) | `0.4.1` | `0.4.4` |
| [tdesign-vue-next](https://github.com/Tencent/tdesign-vue-next/tree/HEAD/packages/tdesign-vue-next) | `1.17.2` | `1.19.2` |
| [vue-demi](https://github.com/antfu/vue-demi) | `0.14.6` | `0.14.10` |
| [vue-i18n](https://github.com/intlify/vue-i18n/tree/HEAD/packages/vue-i18n) | `11.1.12` | `11.4.2` |
| [webpack](https://github.com/webpack/webpack) | `5.105.2` | `5.106.2` |
| [@tsconfig/node22](https://github.com/tsconfig/bases/tree/HEAD/bases) | `22.0.2` | `22.0.5` |
| [@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue/tree/HEAD/packages/plugin-vue) | `6.0.0` | `6.0.6` |
| [@vitejs/plugin-vue-jsx](https://github.com/vitejs/vite-plugin-vue/tree/HEAD/packages/plugin-vue-jsx) | `5.0.1` | `5.1.5` |
| [@vue/tsconfig](https://github.com/vuejs/tsconfig) | `0.7.0` | `0.9.1` |
| [vue-tsc](https://github.com/vuejs/language-tools/tree/HEAD/packages/tsc) | `3.2.5` | `3.2.8` |


Updates `axios` from 1.15.0 to 1.16.0
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.15.0...v1.16.0)

Updates `mermaid` from 11.14.0 to 11.15.0
- [Release notes](https://github.com/mermaid-js/mermaid/releases)
- [Commits](https://github.com/mermaid-js/mermaid/compare/mermaid@11.14.0...mermaid@11.15.0)

Updates `pagefind` from 1.3.0 to 1.5.2
- [Release notes](https://github.com/Pagefind/pagefind/releases)
- [Changelog](https://github.com/Pagefind/pagefind/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Pagefind/pagefind/compare/v1.3.0...v1.5.2)

Updates `pinia` from 3.0.3 to 3.0.4
- [Release notes](https://github.com/vuejs/pinia/releases)
- [Commits](https://github.com/vuejs/pinia/compare/v3.0.3...v3.0.4)

Updates `swiper` from 12.1.2 to 12.1.4
- [Release notes](https://github.com/nolimits4web/Swiper/releases)
- [Changelog](https://github.com/nolimits4web/swiper/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nolimits4web/Swiper/compare/v12.1.2...v12.1.4)

Updates `tdesign-icons-vue-next` from 0.4.1 to 0.4.4
- [Changelog](https://github.com/Tencent/tdesign-icons/blob/develop/packages/vue-next/CHANGELOG.md)
- [Commits](https://github.com/Tencent/tdesign-icons/commits/HEAD/packages/vue-next)

Updates `tdesign-vue-next` from 1.17.2 to 1.19.2
- [Release notes](https://github.com/Tencent/tdesign-vue-next/releases)
- [Changelog](https://github.com/Tencent/tdesign-vue-next/blob/develop/packages/tdesign-vue-next/CHANGELOG.en-US.md)
- [Commits](https://github.com/Tencent/tdesign-vue-next/commits/tdesign-vue-next@1.19.2/packages/tdesign-vue-next)

Updates `vue-demi` from 0.14.6 to 0.14.10
- [Release notes](https://github.com/antfu/vue-demi/releases)
- [Commits](https://github.com/antfu/vue-demi/compare/v0.14.6...v0.14.10)

Updates `vue-i18n` from 11.1.12 to 11.4.2
- [Release notes](https://github.com/intlify/vue-i18n/releases)
- [Changelog](https://github.com/intlify/vue-i18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/intlify/vue-i18n/commits/v11.4.2/packages/vue-i18n)

Updates `webpack` from 5.105.2 to 5.106.2
- [Release notes](https://github.com/webpack/webpack/releases)
- [Changelog](https://github.com/webpack/webpack/blob/main/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack/compare/v5.105.2...v5.106.2)

Updates `@tsconfig/node22` from 22.0.2 to 22.0.5
- [Commits](https://github.com/tsconfig/bases/commits/HEAD/bases)

Updates `@vitejs/plugin-vue` from 6.0.0 to 6.0.6
- [Release notes](https://github.com/vitejs/vite-plugin-vue/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-vue/blob/main/packages/plugin-vue/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-vue/commits/plugin-vue@6.0.6/packages/plugin-vue)

Updates `@vitejs/plugin-vue-jsx` from 5.0.1 to 5.1.5
- [Release notes](https://github.com/vitejs/vite-plugin-vue/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-vue/blob/main/packages/plugin-vue-jsx/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-vue/commits/plugin-vue@5.1.5/packages/plugin-vue-jsx)

Updates `@vue/tsconfig` from 0.7.0 to 0.9.1
- [Release notes](https://github.com/vuejs/tsconfig/releases)
- [Commits](https://github.com/vuejs/tsconfig/compare/v0.7.0...v0.9.1)

Updates `vue-tsc` from 3.2.5 to 3.2.8
- [Release notes](https://github.com/vuejs/language-tools/releases)
- [Changelog](https://github.com/vuejs/language-tools/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vuejs/language-tools/commits/v3.2.8/packages/tsc)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: mermaid
  dependency-version: 11.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: pagefind
  dependency-version: 1.5.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: pinia
  dependency-version: 3.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: swiper
  dependency-version: 12.1.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: tdesign-icons-vue-next
  dependency-version: 0.4.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: tdesign-vue-next
  dependency-version: 1.19.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: vue-demi
  dependency-version: 0.14.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: vue-i18n
  dependency-version: 11.4.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: webpack
  dependency-version: 5.106.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: "@tsconfig/node22"
  dependency-version: 22.0.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: "@vitejs/plugin-vue"
  dependency-version: 6.0.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: "@vitejs/plugin-vue-jsx"
  dependency-version: 5.1.5
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: "@vue/tsconfig"
  dependency-version: 0.9.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: vue-tsc
  dependency-version: 3.2.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 13:30:24 +08:00
nullkey e236be1ced fix(cli): correct KB id detection, SSE terminal-frame, and CI test isolation
Three defects surfaced during end-to-end RAG verification — the first two
block real chat usage, the third makes Linux CI flaky:

1. KB id detection — `IsKBID` was checking
   `strings.HasPrefix(s, "kb_")`, but WeKnora generates KB ids as bare
   UUIDs (internal/types/knowledge_base.go: `uuid.New().String()` stored
   in a `varchar(36)` column). Real ids therefore fell through to the
   name-resolution path:

     $ weknora chat ... --kb a32a63ff-fb36-4874-bcaa-30f48570a694
     Error: knowledge base not found: a32a63ff-...

   Switched the discriminator to a UUID regex
   (`^[0-9a-fA-F]{8}-…-[0-9a-fA-F]{12}$`). KB names are arbitrary
   user-supplied strings, so the canonical 8-4-4-4-12 form is an
   unambiguous signal. Mirrors gcloud `--project`'s id-vs-name detection.

2. SSE terminal-frame — the accumulator's `Append` was gating
   finalization on `r.Done`, but the server's KnowledgeQAStream protocol
   emits a leading `agent_query` frame with `done=true` to deliver
   session + message metadata *before* the answer fragments arrive:

     event: message
     data: {"response_type":"agent_query","content":"","done":true,…}

     event: message
     data: {"response_type":"answer","content":"你好","done":false}
     …
     event: message
     data: {"response_type":"complete","content":"","done":true}

   The accumulator therefore flipped to `finished=true` on frame #1 and
   discarded every subsequent answer fragment — `weknora chat … --json`
   returned `answer: ""` even though the LLM reported completion_tokens
   > 0. Fixed: terminate only on `response_type == complete`.
   References still captured opportunistically (they may arrive on a
   dedicated `references` event before the terminator).

3. doctor credential_storage CI isolation — the check probes the real
   OS keyring via `secrets.NewBestEffortStore()`: present on macOS dev
   machines → StatusOK; absent on Linux CI runners without libsecret /
   Gnome-Keyring → StatusWarn ("falling back to file store"). That
   host-dependence was leaking into two test classes that assumed
   StatusOK:

     * cmd/doctor/doctor_test.go: TestDoctor_AllOK and
       TestDoctor_NoConfig_StillRunsCredentialStorage already had a
       withCredStoreFactory seam but didn't use it. Added the pin.

     * acceptance/contract/envelope_test.go: doctor.success_offline
       and doctor.error_network golden cases. The contract test runs
       through the cobra tree in-process and shares cmd/doctor's
       package-level credStoreFactory var — but couldn't reach it
       because the existing seam was unexported.

   Fix: export `doctor.SetCredStoreFactoryForTest(fn) (restore func())`
   for out-of-package tests; acceptance/contract/helpers_test.go adds
   a TestMain that pins the factory to a MemStore-returning closure
   for the whole suite (MemStore is neither *FileStore nor a real
   keyring, so doctor's type-switch hits StatusOK). Production stays
   at secrets.NewBestEffortStore — only the test hook is now reachable
   from across packages.

Test fixtures and goldens that used the old `kb_xxx` literals or
`Done: true` terminators were rewritten to use real UUIDs and
`ResponseType: ResponseTypeComplete` respectively. Per-command --help
text and Long descriptions / Examples now show a UUID rather than
`kb_…` so users see the correct shape from the start. New
TestAccumulator_IgnoresAgentQueryDone pins the SSE terminator bug so
it can't regress.

Tests: 24 cli packages green on macOS dev + Linux/macOS/Windows CI
matrix. Verified end-to-end against a live WeKnora server: `weknora
chat "..." --kb <UUID> --no-stream --json` returns the full LLM answer
in the envelope, live token streaming in TTY mode works, and the
credential_storage check renders deterministic envelopes across hosts.
2026-05-12 13:20:42 +08:00
nullkey 93d6fb9f30 ci(deps): apply dependabot grouping + monthly cadence across all ecosystems
Earlier per-dep dependabot PRs against the existing cli/, frontend/,
and miniprogram/ ecosystems flooded the review queue with 40+ PRs at
once. Apply a noise-bounding pattern uniformly to every ecosystem the
repo declares:

  * **Monthly schedule** for routine version updates. Mirrors caddy /
    hashicorp-terraform-actions: explicitly chosen over weekly to keep
    maintainer review-attention bounded for a contributor-driven OSS
    project. Among 10 surveyed mainstream configs (daily 7 / weekly 1
    / monthly 2), monthly is the canonical "minimum-noise" choice for
    the contributor cadence WeKnora actually has.
  * **Two `groups` per ecosystem** so per-dep PRs never flood:
      - `<scope>-deps`        bundles minor + patch updates → ONE PR
                              per ecosystem per month.
      - `<scope>-deps-major`  bundles semver-major bumps the same way.
                              Mirrors grafana's `*-breaking` pattern:
                              surfaces breaking changes as a single
                              review-required PR rather than silently
                              ignoring them. (gh-cli's `ignore:
                              semver-major` style means majors never
                              surface until someone manually edits
                              the .yml or the dep — easier to forget
                              than to act on. Grouping forces them
                              into the review queue.)
  * `open-pull-requests-limit: 3` (was default 5) as a safety net so a
    stalled review queue can't pile up stale group PRs.
  * `commit-message.prefix: "chore(deps)"` so dependabot PR titles
    match the repo's Conventional Commits style out of the box.
    npm gets `prefix-development: "chore(deps-dev)"` for devDependency
    bumps.
  * Note: GitHub Security Advisory CVEs open immediately regardless of
    `schedule.interval` — that field governs *version* updates only,
    so the monthly cadence does NOT delay CVE response.

Coverage:
  - gomod: /, /cli, /client
  - npm:   /frontend, /miniprogram
  - pip:   /docreader
  - github-actions: /

Realistic steady-state with this config: 1–3 grouped PRs per month
total across all 7 ecosystems (vs. 40+ before), with major bumps
appearing as their own group PR every few months when upstream cuts
breaking releases.

Tests / build: not affected (config-only change). YAML validated with
`python3 -c "import yaml; yaml.safe_load(...)"`.
2026-05-12 13:20:42 +08:00
nullkey bdbd15bf75 docs(cli): add CLI README, top-level mention, CHANGELOG, ADR section
Discoverability gaps surfaced by the pre-PR review:

- New cli/README.md: install (build-from-source / pre-built once shipped)
  + 5-minute quickstart (auth login → kb list → link → doc upload →
  chat) + multi-context walkthrough + JSON envelope shape + agent /
  scripting integration overview + dev workflow. Points readers at
  cli/AGENTS.md for the full operational contract.

- Top-level README.md: new "⌨️ Command-Line Interface" section between
  Key Features and Getting Started, with a one-paragraph pitch + four
  representative commands and links to cli/README.md and cli/AGENTS.md.
  English README only this round; CN / JA / KO translations to follow
  in v0.3 to match the existing four-language pattern.

- CHANGELOG.md [Unreleased] gets a "weknora CLI v0.2" bullet listing
  the headline capabilities (10-command surface, project-link,
  envelope, agent affordance, multi-context auth, doctor) and pointing
  at cli/README.md.

- cli/AGENTS.md gains an "Architecture decisions" section documenting
  ADR-3 (gh as primary mainstream north star + the four documented
  deviations: link, chat/search, context use, doctor) and ADR-4
  (Factory closures + narrow Service interfaces). The in-source
  references (`(v0.2 ADR-3)`, `(per ADR-4)`) now point at committed
  prose rather than dangling.
2026-05-12 13:20:42 +08:00
nullkey ca90ce422f feat(cli): add auth logout and auth list commands
gh / lark / gcloud / stripe all ship a logout command and a way to
enumerate stored credentials on day one. WeKnora's `auth` subtree had
only login + status, leaving no documented purge path for keyring
secrets — a real concern for `--with-token` (sk-…) and JWT flows that
write credentials to OS keychains.

auth logout [--name <ctx>] [--all] [--json]
  Clears keyring + file-fallback secrets (access / refresh / api_key
  slots) for the named context (default: current) or every context
  with --all. Removes the context entry from ~/.config/weknora/config.yaml
  and clears current_context if the removed entry was active.

  Mirrors `gh auth logout` and `lark auth logout`. As gh documents,
  this does NOT revoke server-side — for API keys users must rotate in
  the server UI, JWTs continue to be accepted until expiry.

auth list [--json]
  Renders a compact table (NAME / HOST / USER / MODE) with the active
  context marked `*`. Reads only config.yaml — no network, no keyring
  touch. Mode is inferred from which credential ref is set (api_key
  → "api-key", token → "password"; both → "password" wins).

  Mirrors gh's per-host enumeration (gh auth status iterates accounts)
  and lark `auth list`. For weknora the contexts file already had this
  data — the command is a thin renderer to match user muscle memory.

Deferred to a follow-up release:
  - auth refresh + transparent 401 retry in the SDK (we already persist
    refresh_token at login but never spend it; explicit gap)
  - login --web browser OAuth flow (requires a server-side endpoint)
  - auth token printer (cheap; defer with the rest)

Tests: 24 cli packages green. New: cmd/auth/logout_test.go (current
context, named, --all, no-contexts, unknown-name, no-current-no-flag,
mutex flags) + cmd/auth/list_test.go (human render, empty, JSON
envelope, inferMode edge cases). AGENTS.md command-surface note adds
the four-command auth subtree; screenshot section 4 adds `auth list`
alongside `auth status`.
2026-05-12 13:20:42 +08:00
nullkey 8bcbf5a154 refactor(cli): align command surface with mainstream conventions
Empirical mainstream-CLI surveys (gh / kubectl / aws / gcloud / stripe /
flyctl / terraform / vercel / netlify / lark) drove five alignment
fixes — each replaces a weknora-only design choice that mainstream CLIs
do not share. No backwards-compat shims; the CLI has no v0.1 users yet.

1. Single --kb flag (was --kb-id + --kb mutually exclusive)

   Survey: 0/7 mainstream CLIs use two parallel flags for "by id" vs
   "by name". Single flag (gh -R, gcloud --project) or positional
   (kubectl, stripe, terraform). Closest analog — gcloud --project —
   collapses identifier types onto one flag.

   Now: every command exposes one --kb flag; client-side prefix
   detection (cmdutil.IsKBID looks for "kb_") routes id-form values
   through directly and name-form values through ListKnowledgeBases.
   Mirrors gcloud --project's id-or-name auto-detection.

   Touched: search, chat, doc list / upload / delete, link.
   Factory.ResolveKB chain trimmed from 5 levels to 4.

2. link supersedes init

   Survey: only vercel and netlify ship both `init` AND `link` as
   siblings, and they keep them semantically distinct. weknora's pair
   wrote the same .weknora/project.yaml file with the same meaning,
   differentiated only by interactivity — that's a flag concern, not
   a command concern.

   Now: cmd/init/ deleted. cmd/link absorbs the interactive flow:
     - link --kb <id-or-name>  → non-interactive write
     - link on a TTY            → interactive prompt (lists KBs)
     - link non-TTY without --kb → CodeKBIDRequired
   Always overwrites silently (matches vercel link / netlify link /
   kubectl apply rather than git init's refuse-if-exists).

   Dead code purged: --force flag, CodeProjectAlreadyLinked error code.

3. whoami dropped

   Survey: 7/7 mainstream CLIs ship exactly one identity command —
   never both a status and a whoami. gh / gcloud / stripe pick status
   (config + live API); aws / kubectl / flyctl pick whoami (live API).

   weknora's auth status was already a superset of whoami (host +
   context + user + email + tenant_id + tenant_name vs user_id +
   tenant_id), so dropping whoami preserves all functionality and
   aligns with the gh / gcloud / stripe form.

4. kb get alias dropped

   `view` was already primary (gh repo view / gh pr view convention);
   `get` was kept as a cobra alias for v0.0/v0.1 callers. With no
   v0.0/v0.1 users to break, the alias is just noise on the command
   surface. Acceptance contract envelope cases renamed kb_get.* →
   kb_view.*; goldens renamed in lockstep.

5. api refactored to gh shape (-X/--method, default GET, auto-POST)

   gh CLI's signature is `gh api <endpoint> [--method M]` — single
   positional path, method as a flag, default GET, auto-promoted to
   POST when a body is supplied. weknora's previous `api <method>
   <path>` inverted this and forced the method to be passed even for
   GET — a needless deviation from our declared north star.

   Now: `api <path> [-X METHOD] [--data ...]`. Exit-10 protocol
   on the DELETE escape-hatch is preserved; -X DELETE still hits
   ConfirmDestructive when -y absent.

Plus: AGENTS.md gains an explicit note that `doctor` is a deliberate
divergence from gh / lark — borrowed from `flutter doctor` / `brew
doctor` because RAG deployments routinely break on misconfigured
embeddings / storage / credentials and a 4-status structured envelope
is the cleanest surface for it.

Tests: 24 cli packages green (was 26 in PR-14; init + whoami packages
removed). Acceptance contract envelope cases for whoami removed,
kb_get → kb_view renamed, search args / mock path updated for the
kb_<id> form. e2e harness flag args updated. Factory.ResolveKB tests
rewritten for the single-flag shape. api_test driver updated for the
positional-path / -X-method shape.
2026-05-12 13:20:42 +08:00
nullkey f7d7c8054d chore(cli): remove unused v0.0 scaffolding
Foundation PR-1 reserved several internal packages and helpers as
scaffolding for follow-up PRs that ended up taking different routes.
Audit confirms zero production references; this commit removes them so
the cli/ tree reflects what's actually shipped.

Removed (148 LOC):

  cli/internal/safepaths/                 — `Validate` / `WithinRoot` /
                                            three sentinel errors. Reserved
                                            for `weknora doc upload`'s path
                                            scrubbing; that command landed
                                            in PR-10 using its own
                                            `validateUploadPath` (os.Stat +
                                            regular-file check) — sufficient
                                            for the actual threat model
                                            (local CLI invocations).

  cli/internal/cmdutil/json_flags.go      — `AddJSONFlags` helper +
                                            unused --jq / --template flag
                                            registration. Reserved for PR-3
                                            "lipgloss tables / jq evaluator"
                                            which never materialized; every
                                            command directly registers
                                            BoolVar(&JSONOut, "json", ...)
                                            since v0.0 ship time.

  cmdutil.NewTableExporter                — empty alias for jsonExporter,
                                            reserved for the same PR-3
                                            renderer. Removed; jsonExporter
                                            stays under NewJSONExporter.

  cmdutil.Options marker interface        — empty interface{} reserved as a
                                            convention; no command embeds
                                            or asserts against it.

Stale comments fixed:

  - cmd/root.go: package comment updated kb (list+get) → kb
    (list+view+create+delete) and noted the `get` cobra alias.
  - cmd/root.go: dropped --no-version-check forward-reference (no such flag).
  - cmd/root.go: removed "(PR-7)" attribution from NewRootCmd doc comment.
  - cmd/kb/kb.go: same package-comment update.
  - cmd/chat/chat.go: replaced "PR-7" mention in --help example with a
    generic placeholder so cobra-rendered help is review-clean.
  - cmd/search/search.go: removed "Lipgloss tables arrive in PR-3"
    forward-reference; the inline indent helper is the shipped form.
  - internal/agent/annotations.go: ShouldUseAgentMode → DetectAIAgent
    (removed in PR-12).

AGENTS.md "Known limitations" section added:
  Documents that chat / search / doc upload currently surface server-side
  precondition misses (LLM / vector store / storage engine not configured)
  as `network.error` with `context deadline exceeded`. A planned future
  release will introduce a `precondition.*` typed error namespace
  (server returns HTTP 412 before opening the SSE / streaming response).
  This documents the limitation honestly for reviewers and integrators
  rather than claiming a behavior we don't yet have.

Tests: 27 cli packages pass (safepaths_test was the 28th — gone with the
package). go vet clean.
2026-05-12 13:20:42 +08:00
nullkey da9faa9e07 feat(cli): add agent-first affordance — envelope, exit-10, --dry-run
Borrows the lark-cli agent-affordance model
(https://github.com/larksuite/cli/blob/main/AGENTS.md +
skills/lark-shared/SKILL.md) so weknora is designed to be agent-friendly:
error messages, output format, and flag design follow conventions agents
can rely on.

cli/AGENTS.md (operational reference for LLM agents invoking weknora):
  Public document covering envelope schema, exit-code protocol
  (0/1/2/10/130), stdout/stderr separation, and behavioral rules.
  Sensitive commands (\`context use\`, \`kb delete\`, \`doc delete\`, \`init\`)
  gain "AI agents:" paragraphs in their cobra Long descriptions so
  guidance shows in --help.

format.Envelope schema additions:
  Risk    per-operation classification (read / write / high-risk-write +
          action description), populated by write commands on both success
          and failure paths.
  Notice  system advisories (CLI update available, server-CLI version
          skew); type defined, emit sites land in v0.3.
  DryRun  marker for envelopes returned from --dry-run preview paths.

  RiskLevel constants realigned to lark's taxonomy: read / write /
  high-risk-write (was: read / mutating / destructive — not yet wired by
  any command).

  cmdutil.Error gains OperationRisk; PrintErrorEnvelope auto-attaches it
  to envelope.Risk so destructive failure paths surface uniformly.

Exit-10 confirmation protocol:
  New ErrorCode \`input.confirmation_required\` mapped to exit code 10 in
  cmdutil.ExitCode. ConfirmDestructive now returns this code (with
  OperationRisk attached) when stdout is non-TTY or --json was set, with
  -y/--yes absent. Previous behavior — silent proceed in non-TTY — was
  unsafe: scripts and agents could delete resources with no explicit
  approval. Three test cases re-pinned around the new contract.

  This is a wire-contract change for any caller who relied on silent
  proceed; v0.0/v0.1 had no destructive commands, so the blast radius is
  contained to v0.2 itself.

--dry-run global flag:
  cmd write paths (kb create/delete, doc upload/delete, api POST/PUT/PATCH/
  DELETE) check cmdutil.IsDryRun(cmd) and skip the SDK call, emitting an
  envelope with dry_run=true plus a Risk classification. Read commands
  ignore --dry-run by design (no side effect to preview). Human-mode
  prints \`[dry-run] would <action>\` to stdout.

Command discovery: agents introspect via the existing \`--help\` surface
(consistent with gh / kubectl / aws / gcloud / terraform — none of them
ship a CLI-tree self-description command). An earlier draft added a
\`weknora schema\` reflection command; dropped after a mainstream survey
found it has no stable analog (lark-cli's schema describes Lark API
methods, not its own CLI tree).

Tests: 27 cli packages pass at this commit. Added two new tests covering
envelope.risk and envelope._notice serialization.
2026-05-12 13:20:42 +08:00
nullkey 9d2e740753 refactor(cli): align command surface with gh CLI conventions (ADR-3)
Audited the v0.0~v0.2 21-command surface against gh / kubectl / cargo /
npm / git / docker / flyctl / vercel / supabase / brew. WeKnora was
cherry-picking from multiple heritages, producing an inconsistent feel:
the kb subtree mixed gh verbs (create / delete / list) with a kubectl
verb (get); confirmation flag duplicated --force (docker/kubectl) with
global -y/--yes (gh/vercel/npm); the --agent flag stretched Stripe's
telemetry-tag pattern into a behavior-mode switch that no mainstream
CLI does.

ADR-3 picks gh as the primary north star. Documented deviations remain
for project-link (vercel/cargo), chat (openai-cli), context (kubectl-
light), and doctor (brew/flutter). The decision and its deviations are
documented self-contained in cli/AGENTS.md.

Surface changes:

  - kb get → kb view (gh repo view convention); "get" kept as cobra Alias
    for v0.0/v0.1 callers — see https://cli.github.com/manual/gh_repo_view.

  - kb delete --force / doc delete --force removed in favor of the global
    -y/--yes persistent flag (gh repo delete --yes convention). One
    mechanism skips destructive prompts; ConfirmDestructive's parameter
    renamed `force` → `yes` to match.

  - --agent omnibus mode-switch removed. Stripe's DetectAIAgent (the
    cited inspiration) only tags User-Agent for telemetry, never flips
    behavior; gh / kubectl / aws / docker / flyctl all decline this kind
    of flag. The 7-env auto-detect list is reduced to the two entries
    Stripe also recognizes (CLAUDECODE, CURSOR_AGENT) — the other five
    had no agent-documented source. ApplyAgentSugar / ShouldUseAgentMode
    and the dead --no-interactive / --no-progress globals are deleted
    entirely.

  - DetectAIAgent and SetAgentHelp annotations are kept: env detection
    now only triggers AGENT-targeted help text rendering (no behavior
    change), matching Stripe's narrower scope.

Tests: 27 cli packages green (acceptance/contract still pins kb get
golden; the alias keeps it valid).
2026-05-12 13:20:42 +08:00
nullkey 3fb3583a92 feat(cli): add api passthrough, chat streaming, doctor warn status
Close the v0.2 RAG demo loop and ship the validation infrastructure:

  - weknora api <method> <path> [--data X | --data-file F]
      Raw passthrough wrapping client.Raw, gh-style. JSON envelope mode
      surfaces status / headers / parsed body. Non-2xx routes through
      cmdutil.ClassifyHTTPStatus (factored out of ClassifyHTTPError so
      both SDK-error and direct-status paths stay aligned — reuse review).

  - weknora chat <text> [--session-id S] [--no-stream]
      KnowledgeQAStream consumer with two output modes:
        - TTY default: token streaming + references footer
        - --json / --no-stream / non-TTY: buffered single envelope
      Auto-creates a session when --session-id is omitted; the id prints
      to stderr at start AND on stream failure (^C scrolls past the
      first announcement, so the recovery hint is re-surfaced when the
      user is most likely to need it).

  - cli/internal/sse/Accumulator
      buffers Content / References / SessionID across SDK callbacks.
      Idempotent post-Done so misbehaving servers don't corrupt state.

  - doctor: ok → ok / warn / fail / skip
      warn marks soft issues that don't block: server within compat range
      but >=1 minor behind CLI; credential storage falling back to file
      because keyring is unavailable. Envelope.ok stays true on warn,
      flips false on fail (exit 1). doctor.error_network golden updated.

  - cli/acceptance/e2e/    real-server RAG full loop
      Build-tagged //go:build acceptance_e2e — kept out of the default
      `go test ./...`. Exercises kb create → doc upload → poll ready →
      search → chat → cleanup against a server pointed at by
      WEKNORA_E2E_HOST / _TOKEN.

  - .github/workflows/cli-e2e.yml
      manual workflow_dispatch + label-gated PR trigger
      ("acceptance-e2e"). No-ops gracefully when the secrets aren't set
      so cross-fork PRs can't accidentally fail the suite.
2026-05-12 13:20:42 +08:00
nullkey 8a0674186e feat(cli): add kb create/delete and doc list/upload/delete commands
Add the resource-management surface to the v0.2 CLI:

  - weknora kb create --name X [--description Y] [--embedding-model Z]
  - weknora kb delete <id> [--force]
  - weknora doc list [--kb-id X | --kb NAME] [--page N] [--page-size M]
  - weknora doc upload <file> [--kb-id X | --kb NAME] [--name custom]
  - weknora doc delete <id> [--force]

doc/* uses Factory.ResolveKB so the cwd's project link is honored when
--kb-id is omitted. doc upload validates path existence with os.Stat
(rejects directories; follows symlinks to mirror SDK os.Open behavior).
doc list sorts by updated_at desc so newer items surface first.

Both delete commands route through cmdutil.ConfirmDestructive — the
"destructive op needs explicit user opt-in" pattern was about to be
copy-pasted across the new subtree, so it was extracted with the delete
commands as their first consumer. Saves the same dedup pass when v0.3
adds session/agent delete. (PR-12 later renames the flag from --force
to the global -y/--yes for gh-style consistency.)

iostreams.SetForTestWithTTY pairs with the existing SetForTest helper:
the latter never reports stdout as a TTY (singleton replacement uses an
in-memory buffer), so the confirm-yes / confirm-no test branches need a
TTY-on variant.
2026-05-12 13:20:42 +08:00
nullkey 19afd5eed9 feat(cli): add project-link foundation with init and link commands
v0.2 grounds the CLI's resource commands (kb / doc / chat / query) in a
per-project link file (.weknora/project.yaml) so users don't have to pass
--kb-id on every invocation. Mirrors npm/cargo/git: walk up the cwd tree
to find the project root, override via flag or env when needed.

This commit ships the foundation layer:

  - cli/internal/projectlink/  Discover (walk-up, depth=64) / Load / Save
  - cmdutil.Factory.ResolveKB  5-level fallback chain:
      --kb-id flag → --kb name (ListKnowledgeBases lookup) →
      WEKNORA_KB_ID env → walk-up project link → CodeKBIDRequired
  - cmdutil.ResolveKBNameToID   shared name→id helper used by init / link
                                / Factory.ResolveKB (was duplicated 3 ways
                                in early implementation; reuse review #2)
  - cli/cmd/init/               interactive (huh prompt) or flag-driven
                                first-time setup; refuses to overwrite
                                without --force
  - cli/cmd/link/               non-interactive update; --kb-id and --kb
                                are mutually exclusive and one is required

Also registers the v0.2 ErrorCode set (all codes for the eight new
commands) and AST-scan identToErrorCode mapping in one place — keeps the
acceptance/contract suite green across the v0.2 commit chain even before
later commits reference each code.
2026-05-12 13:20:42 +08:00
nullkey fc694d5d21 fix(sdk): silence stdout logging via opt-in slog
The client SDK emitted 17 fmt.Printf / fmt.Println trace events directly to
stdout from KnowledgeQAStream and SearchKnowledge. Any consumer of the SDK —
the new CLI in particular — saw these lines interleaved with its own
output, breaking JSON envelope contracts and polluting human-mode tty.

Replace with a package-level slog logger. Default writes to io.Discard so
existing callers see no output change; set WEKNORA_SDK_DEBUG=1 to route
events to stderr for development.

No public SetLogger() API: the trace events were dev-only and a setter
would expand the SDK surface for a one-off use case.
2026-05-12 13:20:42 +08:00
nullkey c8b2129853 docs(api): restore auth.md and update README/wiki links
Fixes #958.

- 新建 docs/api/auth.md:覆盖 10 个 /auth/* 端点
  register / login / oidc 三件套(config/url/callback)/ refresh /
  validate / logout / me / change-password。
  说明各端点的鉴权方式(无 / refresh_token / Bearer JWT),并对齐
  /auth/oidc/callback 的真实行为(始终 302 跳到 / 并把结果编码进
  URL hash)。
- docs/api/README.md:
  - 增加"最权威参考:Swagger UI"段落,引导读者优先访问
    /swagger/index.html(swagger 由 swag 注解自动从代码生成)。
  - "认证管理"行链接由仅指向 OIDC 流程文档改为同时指向 auth.md
    与 OIDC 流程文档。
  - 新增 "IM 渠道" 行指向 docs/IM集成开发文档.md。
  - 新增 "数据源导入" 行指向 docs/数据源导入开发文档.md。
- docs/wiki/API参考/API文档概览.md:随 api/README.md 的"认证管理"
  行同步更新即可——IM 与数据源在该文件原有的"相关主题"/"反向链接"
  小节已经登记,不在 "API 分类" 表中重复。
2026-05-12 13:16:58 +08:00
nullkey 1c7171b2c6 docs(api): rewrite markdown to match current routes
Refs #890 #1049 #1168.

按集成方视角全量审计 17 个 API markdown 文档与 internal/router/router.go
对齐。每个端点新增参数说明小节(path/query/body 字段含义)和响应字段
含义说明(#1168 的核心诉求)。

【与代码对齐】
- 删除已下线端点:system.md 中的 /system/minio/buckets(代码中已无对
  应路由)。
- 修正路径错误:chunk.md 中 /chunks/get-by-id/:id → /chunks/by-id/:id;
  /chunks/:id/delete-question → /chunks/by-id/:id/questions;
  organization.md 中 /organizations/preview/:invite_code → :code。
- 修正字段类型:faq tag_id / entry_id 由 string 改为 int64;
  knowledge.search 响应结构纠正。
- 补齐缺失端点(move-targets、batch-delete、move/progress、pin/unpin/
  stop/continue-stream、tool-approvals、organization agent-shares 等
  30+ 条)。

【精简】
- knowledge-base.md / model.md 把重复 5 次 / 3 次的完整对象样例
  收敛为指向首次出现("字段结构同 POST /xxx 响应"),节省约 400 行
  而不损失信息(仅去重,原作者写的每个字段定义都保留可达)。
- 示例 X-API-Key 统一为 sk-xxxxx(避免读者复制看似真实的 key)。

【清理】
- 删除内部实现细节引用:mcp-service.md 中 6 处 "issue #1173"、
  organization.md 中 "RegisterOrganizationRoutes" 等。

不动 initialization.md:其中端点(KB 配置、模型连通性测试、Ollama 管理)
对集成方有实用价值,保留原作者写好的内容不删。

格式统一遵循 web-search.md 重写后的范式(路由表 + 每端点方法/路径 +
参数表 + curl + 响应 JSON + 字段说明)。
2026-05-12 13:16:58 +08:00
nullkey 54b6f2dc35 docs(api): regenerate swagger via make docs
由 make docs 一次性重新生成 docs/swagger.{yaml,json} 和 docs/docs.go,
包含前一 commit 中的:
- 24 个新增 swag 注解
- 12 处既有注解 bug 修正
- 几处 response 类型从 map[string]interface{} 收敛到具体 struct

机器生成,建议跳过逐行 review。

Refs #890 #1049
2026-05-12 13:16:58 +08:00
nullkey c753c67608 docs(api): add and fix swag annotations on handlers
将 swag 注解覆盖率从 ~88% 提升到 100%,并修复审计中发现的若干既有
注解 bug。

新增注解(24 个):
- im.go: 4 (UpdateIMChannel/DeleteIMChannel/ToggleIMChannel/IMCallback)
  其中 IMCallback 同时注册 GET 和 POST,两个方法都加了 @Router 声明。
- web_search.go: 1 (GetProviders)
- web_search_provider.go: 6
- wechat_qrcode.go: 2
- weknoracloud.go: 2
- knowledge.go: 2 (MoveKnowledge/GetKnowledgeMoveProgress)
- knowledgebase.go: 1 (ListMoveTargets)
- organization.go: 3 (ListSharedAgents/ListOrgAgentShares/RemoveAgentShare)
- mcp_service.go: 2 (SetMCPToolApproval/ResolveToolApproval)
- chunker_debug.go: 1 (PreviewChunking)

修复既有注解 bug(12 处):
- initialization.go: 10 个 @Router 路径与真实路由不符
  (e.g. /initialization/kb/{kbId}/config → /initialization/config/{kbId}
   /initialization/fabri/tag GET → /initialization/extract/fabri-tag POST)
- session/stream.go: ContinueStream 路径
  /sessions/{session_id}/continue → /sessions/continue-stream/{session_id}
- mcp_service.go: ResolveToolApproval 请求体 {approve: bool}
  → {decision: "approve"|"reject", reason?, modified_args?}

收敛响应 schema 到已有命名 struct(之前用 map[string]interface{}):
- knowledge.go MoveKnowledge → handler.MoveKnowledgeResponse
- knowledge.go GetKnowledgeMoveProgress → types.KnowledgeMoveProgress
- web_search_provider.go GetProvider/UpdateProvider → types.WebSearchProviderEntity
- initialization.go InitializeByKB → handler.InitializationRequest
- initialization.go 三个 model-test endpoint → handler.ModelTestRequest

修正 organization.go 中 errors.AppError 应使用 apperrors 别名(该文件
stdlib errors 未别名化)。

不补 /files 和 /api/v1/files/presigned 内联闭包路由(文件服务,非业务 REST)。

Refs #890 #1049 #1168
2026-05-12 13:16:58 +08:00
wizardchen 1f5970b67e refactor(agent): rebuild multi-turn history from DB, drop llmcontext layer
The Agent ran a parallel context cache (Redis/in-memory) on top of the
messages table to feed multi-turn history into the LLM. That dual-write
caused subtle drift (e.g. compression diverging from DB, system-prompt
swaps lost on restart) and required a separate ClearContext path on
session/IM clear.

Make the messages table the single source of truth:

- Add service.LoadAgentHistory: rebuilds chat.Message history per turn
  from the persisted messages, expanding AgentSteps into proper OpenAI
  assistant_with_tool_calls + tool messages and replaying the canonical
  final answer (with <think> blocks stripped). final_answer tool calls
  are filtered to avoid duplicating the trailing answer.
- Make AgentEngine stateless across turns: drop ContextManager / sessionID
  cache plumbing from the engine, agent service, and CreateAgentEngine
  signature. The engine only uses sessionID for logging/event emission.
- Wire AgentQA to load history from DB on demand using HistoryTurns
  (default 5) when MultiTurnEnabled, otherwise run with empty history.
- Delete the llmcontext package (ContextManager interface, Redis/memory
  storage, factory) and the SessionService.ClearContext API path; IM
  /clear and session message clear no longer need to invalidate cache.

Behavior preserved: KnowledgeQA-mode replay is unchanged (turns with
empty AgentSteps just produce the single canonical assistant message),
and Agent-mode turns now consistently see prior tool calls and results.
2026-05-12 12:26:24 +08:00
wizardchen 0b2de5c412 chore(env): remove WEKNORA_SANDBOX_DOCKER_IMAGE from .env.example 2026-05-12 11:32:26 +08:00
wizardchen bd68a0c377 feat(cloud-image): support apt-based docker install for restricted-egress hosts
Mainland China cloud VMs (Tencent Lighthouse, Aliyun, etc.) frequently
cannot reach get.docker.com, github.com, or even community GitHub
mirrors like gh-proxy.com. The cloud-image bootstrap previously had no
escape hatch for this and failed at the very first curl.

This adds a new DOCKER_INSTALL_MIRROR env var to prepare.sh. When set,
it skips get.docker.com and installs docker-ce + compose-plugin from an
apt mirror of Docker's official repo (e.g. mirrors.tencent.com,
mirrors.aliyun.com).

README.md also gets:
- A GH_PROXY env var threaded through bootstrap methods A and B so the
  initial script pull can route through gh-proxy / ghfast.
- An explicit recommendation to prefer method C (scp from local) on
  mainland China VMs.
- A consolidated "三件套" table mapping WEKNORA_GH_PROXY /
  DOCKER_INSTALL_MIRROR / DOCKER_REGISTRY_MIRROR to per-cloud
  endpoints, so users hit one place to copy the full env.
2026-05-11 21:14:08 +08:00
wizardchen 6b812a54d2 fix(searxng): provide hardcoded default SEARXNG_SECRET for zero-config startup
`${SEARXNG_SECRET:?...}` made the variable mandatory at compose parse time,
which forced *any* compose command (default profile included) to fail when
SEARXNG_SECRET was unset, with a message confusingly claiming the searxng
profile was being started.

Switch to `${SEARXNG_SECRET:-weknora-default-searxng-secret-...}` so the
searxng profile starts zero-config. Default deployments bind searxng to
127.0.0.1 only, so a shared default secret is acceptable; .env.example
now explicitly warns to rotate it before flipping SEARXNG_BIND=0.0.0.0,
since secret_key signs image-proxy URLs.
2026-05-11 16:53:47 +08:00
wizardchen 5fb7e692e5 refactor(web-search): drop dead api_key path in SearXNG provider
The SearXNG provider forwarded `parameters.api_key` as
`Authorization: Bearer <key>` for reverse-proxy auth, but the frontend
never rendered the API key input for self-hosted providers
(`requires_api_key=false`), so the path was unreachable from the UI.

Rather than expose another UI knob for a niche reverse-proxy setup that
the project does not currently support, remove the Authorization header
branch and the `apiKey` field on `SearxngProvider`. Tenants who put
SearXNG behind an authenticating reverse proxy can still front it with
network-level auth (mTLS, IP allowlist) without changes here.

`WebSearchProviderParameters.APIKey` is generic and used by other
providers, so it stays.
2026-05-11 16:53:47 +08:00
wizardchen c2d60933c8 refactor(security_test): standardize struct field formatting in SSRF whitelist tests
- Adjusted the formatting of struct fields in the SSRF whitelist test cases for improved readability and consistency.
- No functional changes were made; this is purely a code style improvement to enhance maintainability.
2026-05-11 16:53:47 +08:00
wizardchen 0f5dc41f4e feat(searxng): enhance SearXNG configuration and validation
- Updated .env.example to clarify SEARXNG_SECRET generation and added SSRF_WHITELIST_EXTRA for improved security.
- Modified docker-compose files to bind SearXNG to localhost by default and introduced a one-time initialization service to set up settings.yml correctly.
- Enhanced SearxngProvider with stricter URL validation, ensuring no query or fragment is present in the base URL.
- Added unit tests for SearXNG validation and date parsing to ensure robustness.
- Updated frontend WebSearchSettings to reflect changes in SearXNG instance URL handling.

This commit improves the security and usability of the SearXNG integration, addressing potential misconfigurations and enhancing the developer experience.
2026-05-11 16:53:47 +08:00
wizardchen d2a1006beb fix(web-search): address review fixups for SearXNG provider
- utils: 合并 SSRF_WHITELIST 与 SSRF_WHITELIST_EXTRA,避免部署侧默认值
  (如 docker-compose 注入的 searxng 主机名)被用户的 SSRF_WHITELIST
  自定义值覆盖。
- docker-compose.yml: 把 searxng 默认值挪到 SSRF_WHITELIST_EXTRA。
- searxng: 抽出导出函数 ValidateSearxngBaseURL,让 service 层保存校验
  和 provider 构造校验完全一致;service 改为调用同一函数。
- searxng: language 由非法的 "auto" 改为 "all";移除强制 safesearch=1
  让实例 settings.yml 决定。
- searxng: publishedDate 增加多格式 fallback(RFC3339Nano/无时区/
  日期-only/RFC1123 等),无法解析时 debug 日志记录。
- searxng: 解析 unresponsive_engines;结果为空时打 warn 日志,便于排查
  "配置正确却搜不到结果"的情况。
- frontend: WebSearchSettings 的 Instance URL 标签/占位符走 i18n,
  zh-CN / en-US / ru-RU / ko-KR 四个 locale 补齐 baseUrlLabel /
  baseUrlPlaceholder。
2026-05-11 16:53:47 +08:00
wizardchen 1110615300 feat(web-search): add SearXNG provider (#1166)
支持对接自建/公共 SearXNG 实例作为网络搜索引擎,缓解免费搜索引擎在国内
网络环境下访问受限的问题。

- types: 新增 WebSearchProviderTypeSearxng 与 BaseURL 参数字段;
  类型元数据新增 RequiresBaseURL,前端可动态渲染 Instance URL 表单。
- infrastructure/web_search/searxng.go: 调用 /search?format=json,强制
  utils.ValidateURLForSSRF 校验 base_url,可选 api_key 透传给反代鉴权。
- service: isValidProviderType 与参数校验接入 searxng。
- container: 注册 NewSearxngProvider 工厂。
- frontend: WebSearchSettings 表单根据 requires_base_url 渲染 Instance
  URL 输入框;编辑回填、free 判定同步更新。
- docker: 新增可选 searxng 服务(profile=searxng/full),附带最小化
  settings.yml(启用 JSON 格式、关闭 limiter、关闭遥测),
  docker-compose 默认 SSRF_WHITELIST 包含 searxng 容器名。
- .env.example: 补充 SEARXNG_PORT / SEARXNG_SECRET 说明。

Closes #1166
2026-05-11 16:53:47 +08:00