Commit Graph
1609 Commits
Author SHA1 Message Date
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
wizardchen 9dcb61fb45 feat(frontend): enable gzip compression for static resources in nginx configuration
- Added gzip compression settings to improve loading times for static assets, significantly reducing the size of files served and enhancing performance for users, especially in low bandwidth regions.
2026-05-11 15:51:11 +08:00
wizardchen 0cfbad7f97 fix(cloud-image): enhance firstboot and cleanup scripts for improved security and functionality
- Updated cleanup.sh to avoid recreating .env during cleanup, preventing exposure of default passwords before firstboot.
- Modified firstboot.sh to create .env from .env.example only if it doesn't exist, ensuring no sensitive data is present before initialization.
- Added support for Docker Hub and GitHub tarball download acceleration via new environment variables WEKNORA_GH_PROXY and DOCKER_REGISTRY_MIRROR.
- Implemented a mechanism to prune old WeKnora images based on the current version, reducing image size and maintaining a clean environment.
- Enhanced README.md with instructions for using the new acceleration features and image pruning options.
2026-05-11 15:51:11 +08:00
qingfhuangandCursor 0eb95ccbd8 fix(client): correct GetChunkByIDOnly endpoint
Use /api/v1/chunks/by-id/{id} to match backend route.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 15:34:29 +08:00
wizardchen 1e3aa337db fix(cloud-image): refine cleanup process to prevent unwanted image deletions
Updated the cleanup script to replace the broad `docker system prune` command with more targeted commands. This change ensures that only unused containers, build cache, and dangling volumes are removed, preventing the accidental deletion of important images like `wechatopenai/weknora-*` that are pre-pulled for firstboot. The script now explicitly prunes containers, builders, and dangling volumes to maintain a clean environment without disrupting the intended image setup.
2026-05-11 12:25:19 +08:00
wizardchen cdfbf05524 fix(cloud-image): make firstboot idempotent and pin image versions
Address review feedback on PR #1249:

- prepare.sh: when WEKNORA_REF looks like a version tag (v*), write the
  matching WEKNORA_VERSION into .env so docker compose pulls images that
  match the compose YAML's git ref (previously stuck on :latest).
- prepare.sh: detect docker binary path via `command -v docker` and
  template it into weknora.service (replacing hardcoded /usr/bin/docker
  that fails when docker lives in /usr/local/bin).
- firstboot.sh: write a /opt/WeKnora/.firstboot.done marker immediately
  after rewriting .env, before `docker compose up -d`. If compose fails
  mid-run, the next boot is gated by ConditionPathExists=!marker so we
  never regenerate DB_PASSWORD against an already-initialized postgres
  volume (which previously bricked the database).
- firstboot.sh: stop deleting its own unit file / script while the
  oneshot is still executing; rely on the marker + `systemctl disable`
  instead, avoiding "job failed" markings from systemd.
- firstboot.sh: use detected docker path instead of /usr/bin/docker;
  add note in credentials file that .env is the source of truth.
- weknora-firstboot.service: add ConditionPathExists=!.firstboot.done.
- cleanup.sh: scope docker volume deletion to compose project label
  (com.docker.compose.project=<name>) instead of fuzzy substring match
  that could nuke unrelated postgres/redis volumes.
- cleanup.sh: also remove .firstboot.done marker, firstboot log, and
  any leftover /root/weknora-credentials.txt so the image is clean.
- README.md: clarify how to actually disable registration (edit the
  `replace` call list in firstboot.sh, not run that command in shell).
2026-05-11 12:25:19 +08:00
wizardchen 155f3b3e72 docs(cloud-image): clarify sudo + redirection pitfall in setup steps
Recommend `sudo -i` to avoid the classic `sudo cmd >> file` failure
where the shell redirection runs as the unprivileged user. Also document
the `sudo tee -a` workaround and add a scp option C.
2026-05-11 12:25:19 +08:00
wizardchen afd7d1fdf8 docs(cloud-image): add cloud-agnostic image packaging scripts
Add scripts and docs for packaging WeKnora into cloud images (AMI,
custom images, snapshots) so users can distribute one-click deployable
templates on any cloud provider.

- scripts/cloud-image/: cloud-agnostic prepare/cleanup/firstboot scripts
  plus systemd units. Downloads only the 4 runtime files needed by the
  compose stack (~100KB) instead of cloning the full repo, and pins to
  any git ref via WEKNORA_REF for reproducible builds.
- firstboot.sh randomizes DB/Redis/JWT/AES secrets on first boot,
  writes credentials to /root/weknora-credentials.txt and self-removes.
- docs/cloud-image/: per-platform packaging guides. Includes a guide
  for Tencent Cloud Lighthouse / CVM covering image creation, sharing,
  and marketplace listing.

Default-on services match the unprofiled compose stack (frontend, app,
docreader, postgres, redis); optional services (qdrant, milvus,
neo4j, langfuse, etc.) remain opt-in via compose profiles to keep the
image size small.
2026-05-11 12:25:19 +08:00
wizardchen 7c0964bb95 fix(agent): enhance user authorization and concurrency handling in tool approval
- Introduced a new test to ensure that empty user IDs are rejected when a waiter has a user, preventing unauthorized approvals.
- Added RequestNonce to resolve messages to uniquely identify Resolve calls, ensuring concurrent requests do not interfere with each other.
- Updated waiter structure to use atomic operations for the resolved state, improving thread safety.
- Enhanced error handling in the Resolve method to properly manage user mismatches and ensure accurate acknowledgment delivery across instances.
- Updated MCP service handler to reject unauthenticated requests early, providing clearer feedback on authorization requirements.
2026-05-10 22:57:12 +08:00
wizardchen 6d0f09d75f fix(agent): 加固 MCP 工具人审批的跨实例与并发语义
- 跨实例 Resolve 通过 Redis reply channel 接收 owning 实例的 ack
  (ok / not_found / tenant_mismatch / user_mismatch / already_resolved),
  HTTP 不再静默 200,超时退化为 NotFound。
- PendingRequest 增加 UserID,Resolve 校验会话所有者,避免同租户
  其他用户越权批准/篡改参数。
- 新增 ErrAlreadyResolved,timer/ctx 命中后再次 Resolve 返回 400 而
  不是静默成功;waiter.deliver 暴露胜出语义。
- NeedsApproval 默认 fail-close(DB 故障要求审批),可经
  WEKNORA_AGENT_TOOL_APPROVAL_FAIL_OPEN=true 回退。
- Pub/Sub 增加 OriginID 自过滤、退避重连、namespace 后缀,避免自回
  环噪声与多部署串扰。
- 工具执行超时常量统一通过 ToolExecContext.ExecTimeout 注入,
  mcp_tool.go 不再硬编码 60s。
- handler 修正 path 二次解码、错误用 errors.Is、modified_args=null 的
  静默清空、ListMCPToolApprovals 的 404/500 误判。
- repository 用 clause.OnConflict 做原子 upsert,消除并发 500。
- 增加 NotFound / TenantMismatch / UserMismatch / AlreadyResolved /
  Race 等用例。
2026-05-10 22:57:12 +08:00
wizardchen 5510ea8f5a feat(agent): human-in-the-loop approval for MCP tool calls (#1173)
Add an opt-in human approval gate so Agent runs pause before executing
MCP tools that operators flag as dangerous, surface an approval card in
the chat UI, and only resume after the user approves (optionally with
edited args) or rejects.

Backend
- New mcp_tool_approvals table + repo/service to mark per-tool approval
  required (PG migration 000042 + sqlite init).
- approval.Gate coordinates RequestAndWait / Resolve with sync.Once
  delivery, configurable timeout, and Redis Pub/Sub fan-out so multi-
  replica deployments work without sticky sessions.
- MCPTool.Execute integrates the gate; uses a round-level ApprovalCtx
  (without the per-tool 60s timeout) for the wait, and re-derives a
  fresh 60s exec ctx after approval so CallTool keeps a full window.
- New SSE response types (tool_approval_required / _resolved) and
  EventBus events plumb approval state to AgentStreamDisplay.
- REST: list/set per-tool approval flag, resolve pending approval.
- Configurable via agent.tool_approval_timeout_seconds (yaml) or
  WEKNORA_AGENT_TOOL_APPROVAL_TIMEOUT env (accepts seconds or Go
  duration).

Frontend
- MCP settings: per-tool "require approval" switch on the test panel.
- Chat: ToolApprovalCard renders the pause point with editable JSON
  args, validation feedback, mm:ss countdown that turns warning/danger
  near deadline, and a resolved state that retains context.
- i18n strings added for zh-CN / en-US / ko-KR / ru-RU.

Docs
- docs/zh/mcp-approval.md covering behavior, config, API, deployment
  considerations (Redis cross-instance, restart limitations).
2026-05-10 22:57:12 +08:00
wizardchen c1826030ab fix(frontend): 修正 LLM 调用超时文案与实际行为一致,上限放宽至 3600s
前端原文案'0 表示无限等待(不推荐)'与后端实际行为不符——
internal/agent/const.go 中 getLLMCallTimeout 在配置为 0 时回退到
defaultLLMCallTimeout (120s),并不会无限等待,文案误导用户。

- 同步 zh-CN/en-US/ru-RU/ko-KR 四种语言 hint 为'0 表示使用默认值(120s)'
- placeholder 推荐范围由 60-600 调整为 60-1800,与后端兜底超时上调保持一致
- AgentEditorModal 输入框 :max 由 600 放宽到 3600,避免长推理模型场景被卡住
2026-05-10 00:26:53 +08:00
wizardchen 24a010ff59 fix(chat): reduce default LLM timeout values to 300s for chat and 600s for stream 2026-05-10 00:16:12 +08:00
wizardchen e83378ecd1 fix(chat): 调大 LLM 兜底超时默认值(chat 600s / stream 1800s) 2026-05-10 00:16:12 +08:00