Commit Graph

1519 Commits

Author SHA1 Message Date
matevip
0141b00270 docs(agent): document per-agent primary knowledge base binding (1.5.0)
Add the user-facing and API-reference docs that explain how an employee
can declare a primary knowledge base, what the runtime fallback chain
looks like, and how the binding is driven from the API.

agents.md (zh + en)
- New section "Knowledge base binding (per-agent primary KB)" right after
  the tool-binding section, with a 1.5.0 New In badge
- Lays out the design intent explicitly: KBs stay workspace-shared, the
  binding only chooses a default target, multiple agents may pick the
  same KB as primary
- Documents the runtime resolution order used by wiki tools: explicit
  kbName/kbId, agent.primaryKbId, most-recently-updated workspace KB
- Migration note about the legacy kb.agent_id to agent.primary_kb_id
  backfill and the visibility change for anyone who relied on the old
  one-to-one isolation

api.md (zh + en)
- Under Agents: document the primaryKbId field with the three-state PUT
  semantics (omit / null / value) and example curl calls
- Under LLM Wiki: document GET /api/v1/wiki/knowledge-bases/bindable and
  the explicit warning that PUT /api/v1/wiki/knowledge-bases/{id} no
  longer processes the agentId field
2026-05-29 06:33:46 +08:00
matevip
69bea272dd fix(memory-ui): escape < in <!-- user-edited literals to unblock vite dep-scan
Vite's dep pre-bundling runs esbuild's lite parser over .vue script blocks
to find imports. On esbuild 0.27.5 that parser interprets the
HTML-style sequence `<!--` inside a JS string/regex literal as the start
of a legacy line comment, which made it conflate two unrelated string
literals on lines 95 and 110 of MemoryBrowser.vue and report a fake
"Unterminated string literal" against a phantom line that doesn't exist
in the source.

Replacing the raw `<` with `\x3c` keeps the runtime behavior identical
(includes/regex match the same `<!-- user-edited` marker) but breaks the
HTML-comment heuristic so the scanner no longer chokes. The two call
sites — userEdited detection in parseSections and the strip regex in
stripMarker — both need the escape.

Repro: `pnpm dev` from a cold cache surfaces the error during dep scan,
runtime tests passed already because the actual JS parser handles the
strings fine.
2026-05-29 06:16:41 +08:00
matevip
51e1bd2582 fix(migration): renumber agent primary_kb to V130 to clear V129 collision
PR #237 introduced V129__agent_primary_kb.sql while dev also has
V129__wiki_page_broken_links.sql shipped from the broken-link lint work.
Flyway rejects duplicate version numbers at startup, so the agent
primary_kb migration moves to V130 across both H2 and MySQL dialects.

No content change beyond the rename — the column add, index, and
backfill SQL are identical to the V129 originals from #237.
2026-05-29 06:01:02 +08:00
lichuan
bd02734d61 feat(agent): add knowledge base binding tab to agent editor (#237)
Agents now have a per-agent primary wiki KB stored on
mate_agent.primary_kb_id. KBs remain workspace-shared — selecting one in
the agent editor only chooses the default wiki target for that agent, it
does not change the KB's ownership or visibility.

Backend
- AgentEntity: add primary_kb_id field (FieldStrategy.ALWAYS so the UI
  can clear it back to "no primary")
- AgentController#update: switch body to Map<String, Object> so we can
  tell "field missing" apart from "explicit null" via containsKey, then
  convertValue back to AgentEntity
- WikiKnowledgeBaseService:
  - new resolvePrimaryKb(agentId): prefers agent.primary_kb_id when it
    points to a workspace-visible KB; falls back to legacy
    kb.agent_id marker, then to most-recently-updated workspace KB
  - listByAgentId now returns the full workspace set (KBs are
    workspace-shared under the new model)
  - update(id, name, description) no longer touches agent_id
- WikiController: new GET /knowledge-bases/bindable for the UI picker;
  PUT /knowledge-bases/{id} no longer reads agentId
- WikiKnowledgeBaseEntity: add FieldStrategy.ALWAYS on embeddingModelId
  and configContent so explicit nulls actually unbind/clear instead of
  being silently skipped by MyBatis-Plus's NOT_NULL default
- Migrations V129 (H2 + MySQL): add primary_kb_id column + index, backfill
  from legacy kb.agent_id, MySQL uses INFORMATION_SCHEMA guard +
  PREPARE/EXECUTE for idempotency
- WikiKnowledgeBaseServiceTest: 13 cases, all passing

Frontend
- Agents.vue: new "Knowledge Base" tab, radio-select bindable KBs
- API: listBindableKBs() + Agent.primaryKbId typed string | number | null
- IDs handled as strings throughout (Snowflake-safe)
- i18n keys for the new tab in zh-CN and en-US
2026-05-29 06:00:52 +08:00
matevip
0ef735588a fix(wiki): 3 bugs caught by browser-driven chat e2e + 12-round trace 2026-05-28 10:55:30 +08:00
matevip
7c9db74886 docs(wiki): seventh-pass — post-restart full sweep, 8/8 green 2026-05-28 09:26:14 +08:00
matevip
f6b36d915a docs(wiki): end-to-end recovery loop — chat toast → rename → click works 2026-05-28 09:26:07 +08:00
matevip
0e01b2b526 feat(wiki): chat-rendered wikilinks navigate via cross-KB lookup 2026-05-28 09:25:58 +08:00
matevip
f488be690e docs(wiki): fifth-pass e2e — live verification of fixes + chain/concurrent 2026-05-28 09:25:49 +08:00
matevip
af9928bf54 fix(wiki): case-only rename portability + SpringBootTest regression suite 2026-05-28 08:18:01 +08:00
matevip
b6ae7322a9 docs(wiki): fourth-pass e2e — edge cases and negative paths 2026-05-28 08:17:55 +08:00
matevip
3a5b29f13e docs(wiki): third-pass e2e — full sweep on restarted server post-fix 2026-05-28 08:17:48 +08:00
matevip
296c91d6da fix(wiki): cascade + scan must not null content/summary via FieldStrategy.ALWAYS 2026-05-28 08:17:42 +08:00
matevip
e9bbce862c docs(wiki): end-to-end verification spec + dev-box run results 2026-05-28 08:17:35 +08:00
matevip
a71c49d374 feat(wiki): analyze-stage slug whitelist + code-aware enrich applier 2026-05-28 08:17:27 +08:00
matevip
16eac232c4 feat(wiki): cascade delete + rename to keep wikilinks consistent 2026-05-28 08:17:19 +08:00
matevip
105b075f13 feat(wiki): slug-first prompt contract and same-batch link safety 2026-05-28 08:17:13 +08:00
matevip
2b3c068db9 feat(wiki): broken-link lint with job-based async scan 2026-05-28 08:17:04 +08:00
matevip
66d3d90ea9 feat(wiki): slug-first wikilink resolution and safe DOM postprocess 2026-05-28 08:16:56 +08:00
matevip
ee04340742 feat(wiki): expose per-raw progress in processing-status 2026-05-28 08:16:50 +08:00
matevip
d8dedbeda3 fix(wiki): processing-status reads truth from page table, self-heals drift 2026-05-28 08:16:40 +08:00
matevip
b81660a2a1 polish(approval-grants-ui): fix active-count pill + reuse mcConfirm for revoke 2026-05-27 15:54:47 +08:00
matevip
fe4f051672 polish(approval-grants-ui): pin the Actions column to the right edge 2026-05-27 15:09:18 +08:00
matevip
5f2adf15f6 polish(approval-grants-ui): show granter name, fix note cell rendering, tighten layout 2026-05-27 15:09:11 +08:00
matevip
b34de4e078 refactor(approval-grants-ui): strip Element Plus, reuse project list+pagination 2026-05-27 15:09:04 +08:00
matevip
6a754f5bfa refactor(approval-grants-ui): rebuild create dialog to match ToolGuard pattern 2026-05-27 15:08:56 +08:00
matevip
b9c5ec03d4 refactor(approval-grants-ui): header aligned with project conventions 2026-05-27 15:08:49 +08:00
matevip
65cf53779a refactor(approval-grants-ui): paginated list, Element Plus icons, shorter sidebar label 2026-05-27 15:08:41 +08:00
matevip
2f5e06f286 fix(approval): three minor issues surfaced by end-to-end testing 2026-05-27 14:08:12 +08:00
matevip
f15b2dced3 feat(ui): auto-approve banner dropdown, management page, and workspace chip 2026-05-27 14:08:04 +08:00
matevip
fe072191ea feat(approval): REST surface for auto-grant strategies with tiered authorization 2026-05-27 14:07:56 +08:00
matevip
2653356613 feat(approval): record human-approval and timeout resolutions, retire grants on conversation delete 2026-05-27 14:07:48 +08:00
matevip
b7e923fac4 feat(approval): grant-based auto-approve with safety floor and resolution log 2026-05-27 14:07:39 +08:00
matevip
38dce5c20a chore(deps): bump spring-ai to 1.1.7 2026-05-27 14:07:23 +08:00
matevip
f163c0b5bc feat(ui): rewrite chat welcome subtitle and suggestions around agent capabilities 2026-05-27 06:58:52 +08:00
matevip
ac090afde3 fix(workflow): pre-check unique name on create/rename, return 409 instead of 500 (Fixes Gitee #IJPYWA) 2026-05-26 23:35:04 +08:00
matevip
b64a312994 fix(skill): harden GitHub token handling against credential leaks
The previous private-repo support inlined the access token into the
clone URL and then logged that URL on success — leaking the token to
log files, container stdout, and any IOException thrown when the clone
failed. The token also appeared in the process command line, visible
to anyone with shell access via `ps`.

Switch to git's GIT_CONFIG_COUNT/KEY/VALUE environment variables, which
inject `http.extraHeader: Authorization: Bearer <token>` into the child
process without ever touching argv or the repo URL. The URL stays
pristine, so the existing INFO log and error message are safe.

Other changes:
- Resolve token from `mateclaw.skill.github-token` property first, then
  fall back to GITHUB_TOKEN env var. Keeps the original deployment
  contract while letting admins manage the credential via configuration.
- Tighten the host check (prefix match on `https://github.com/` etc.)
  so a crafted URL like `https://evil.com/?u=github.com/...` cannot
  trick the fetcher into forwarding the token to a third party.
- Set GIT_TERMINAL_PROMPT=0 so a bad token fails fast instead of
  blocking on an interactive password prompt.
2026-05-26 23:11:46 +08:00
shenyuya
1c1409e309
feat(skill): support private GitHub repos and bump clone timeout
Adds GITHUB_TOKEN env var support for private GitHub repo cloning and raises the git clone timeout from 60s to 120s for slow networks.
2026-05-26 23:07:57 +08:00
matevip
c8b25e1bfb fix(agent): deny skill-discovery tools when skillsDisabled (#184 follow-up) 2026-05-26 22:16:51 +08:00
matevip
0ac325a337 feat(agent): explicit "no skills / no tools" opt-out flags (#184) 2026-05-26 22:07:12 +08:00
matevip
ff2620dfcf fix(wiki): harden kbName/kbId routing — ambiguous fail-closed, kbId param, prompt cleanup (#224) 2026-05-26 14:31:07 +08:00
matevip
d2b23c049c fix(wiki): let agents reach every visible KB via kbName + wiki_list_kbs (#224) 2026-05-26 13:53:32 +08:00
matevip
3ae4498f38 fix(channel,agent,chat): unify channel binding / conversation agent / model pin state sources 2026-05-26 09:40:49 +08:00
matevip
7f5652b2f0 fix(agent): replace per-loop head/tail trim with anchored token-budget budgeter 2026-05-26 07:34:25 +08:00
matevip
6c8c490bd3 chore(feishu): bump oapi-sdk to 2.7.1 and replace WS-close reflection with public API 2026-05-25 21:36:33 +08:00
matevip
e9ead959b8 fix(feishu): invoke SDK disconnect() directly and surface cleanup failures 2026-05-25 21:31:09 +08:00
倪程伟
54e3f7f3fa
fix(feishu): properly close WebSocket connection to prevent resource leak (#221)
stopWebSocket() only nullified the wsClient reference without calling
disconnect() on the SDK client. This left the old WebSocket connection's
pingLoop thread and ExecutorService running, leaking file descriptors
and threads on each reconnect. Over time, accumulated leaks prevented
new connections from being established, causing the Feishu channel to
silently stop receiving messages.

Fix: use reflection to access the SDK's protected `conn` field and call
close(1000) on the OkHttp WebSocket, triggering the SDK's onClosed →
disconnect() cleanup chain.

Note: oapi-sdk 2.7.1 adds a public close() method that would make this
reflection unnecessary. Consider upgrading as a follow-up.

Closes #220
2026-05-25 21:28:05 +08:00
matevip
a01f0354eb feat(conversation): introduce ChatResult to carry token usage through sync chat paths 2026-05-25 21:15:53 +08:00
matevip
8d01396130 fix(conversation): capture runtime model/provider with token usage in IM and webchat paths 2026-05-25 20:31:09 +08:00
倪程伟
727373f67c
fix(conversation): capture token usage in IM channel and webchat paths (#217)
IM channels (Feishu, DingTalk, WeCom, etc.) and the WebChat widget were
calling saveMessage without token usage parameters, causing promptTokens
and completionTokens to default to 0. This made the Token Statistics
module report significantly lower numbers than actual usage.

Root cause: the _usage_final event (containing promptTokens /
completionTokens) emitted by the agent graph at stream end was not being
captured in these paths, unlike ChatController's StreamAccumulator which
already handles it correctly.

Fix: capture _usage_final events in doOnNext handlers for:
- ChannelMessageRouter sync path (non-streaming IM adapters)
- ChannelMessageRouter streaming path (DingTalk, etc.)
- WebChatController SSE stream

Refs #214 (remaining String-API paths covered by follow-up).
2026-05-25 20:25:22 +08:00