Commit Graph

271 Commits

Author SHA1 Message Date
matevip
fe68f22aa8 feat(memory): bound always-on memory growth with injection budget, consolidation, and file ceilings
Always-on memory (structured user/feedback blocks, PROFILE.md, MEMORY.md) is injected into every system prompt but only ever grew, inflating per-turn context over time. This adds deterministic size control across all always-on sources:

- Injection budget: cap the always-on structured block by total chars and per-type entry count, keeping the most-recently-updated entries (LRU by Updated date) and disclosing how many were omitted
- Nightly consolidation: a dedicated scheduled pass merges duplicate/stale user & feedback entries via the LLM, preserving each entry's original Updated date; runs per owner bucket (shared + personal) with a per-run cap and a never-grow safety guard
- File ceilings: deterministic backstop truncates PROFILE.md / MEMORY.md at a section boundary when a rewrite overruns its budget
- Manual trigger endpoint for the consolidation maintenance task

All knobs under mate.memory.*; covered by unit tests.
2026-06-17 11:04:19 +08:00
matevip
1affbd7b82 feat(agent): loop-engineering robustness — goal continuation, plan re-plan, stall detection
- goal: continue (not skip) on max-iterations and evidence-insufficient turns.
  A max-iterations turn grants a fresh iteration budget ("hard continuation"),
  bounded per run and sized into the graph recursion ceiling, so a task too big
  for one budget keeps going instead of stalling until the next user message.
- plan-execute: re-plan the remaining work on a step exception, and on a
  signature-based stall (repeated failures / identical results / no usable
  result) instead of advancing dependent steps with junk; bounded by a per-run
  re-plan cap, with a graduated change-strategy nudge before the hard stop.
- plan-execute: auto-derive a goal from a genuine multi-step plan, seeding the
  acceptance criteria from the plan steps, so the goal subsystem engages without
  the model calling setGoal; broadcast goal_created so the UI hydrates.
- react: refund the iteration for setup-only rounds (load_skill / enable_tool)
  so a tight budget is not eaten by the load-then-use two-step.
- ui: re-fetch the active goal when a turn finishes so a goal created or mutated
  mid-conversation surfaces without depending on an SSE event.
- streaming: make retry backoff / total-time budget instance fields with a
  test-only seam; clarify that the wall-clock budget (not max-retries) bounds a
  sustained SERVER_ERROR loop to ~8 attempts, fixing the slow/flaky retry test.
2026-06-17 06:37:08 +08:00
matevip
85ceafa055 fix(agent): scope KB grounding to wiki-equipped agents and wiki tools
The knowledge-base trust verification recorded wiki citations from every
non-readFile tool response by sniffing its JSON for a top-level title /
pages / chunks field. Tools like getGoalStatus return a top-level title,
which falsely populated the citation set and then forced [n] citations on
the final answer (otherwise flagged EVIDENCE_INSUFFICIENT). Gate citation
mining on the wiki_* tool name instead.

Likewise, the grounded answer contract (cite-or-refuse) was appended to
every ReasoningNode call unconditionally, degrading general agents that
have no knowledge base. Append it only when the agent has a wiki_* tool
bound, scoping the strict regime to KB-grounded scenarios.

Adds a regression test asserting a non-wiki tool with a top-level title
creates no wiki citations.
2026-06-16 07:48:04 +08:00
jack
88be1f748a
[#305] [Feature] Add knowledge base trust verification (#334)
Co-authored-by: SuperCoderMan521 <SuperCoderManqq.com>
2026-06-16 07:47:04 +08:00
matevip
d9a9d07704 fix(wiki): broken-link rescan precision, slug/title resolution, and dangling-link reconcile (#333)
- rescan: keep the KB id as a string end to end so the 19-digit snowflake id
  isn't truncated past Number.MAX_SAFE_INTEGER (rescan no longer 404s)
- lint: resolve [[...]] targets against page slugs AND titles like the viewer,
  so a title reference to an existing page is no longer reported broken
- ingest: derive the slug deterministically from the title (no inconsistent
  romanization), auto-recompute broken links once a KB finishes importing,
  and reconcile dangling [[concept]] links — redirect to the covering page via
  declared aliases, or demote to plain text when uncovered
- add the page aliases column migration for h2 / mysql / kingbase
2026-06-15 16:14:25 +08:00
matevip
4cbd2b50f3 feat(dashboard): show the connected database on the dashboard
Surface the connected database product as a subtle chip in the Dashboard
header. SystemHealthService now reports a database label on /system/health
(reused by the front-end — no extra request), derived from a new
DatabaseBootstrapRunner.getDatabaseLabel() that reads the JDBC product name
once and normalizes it to a canonical label (MySQL / MariaDB / PostgreSQL /
H2, and 人大金仓 for the KingbaseES family), collapsing driver version noise.
2026-06-15 08:47:53 +08:00
matevip
710b756281 test(chat): cover gateway-resilience error classification; fix PKIX casing
Add ErrorClassificationTest regression cases for the AI-gateway retry
hardening: 5xx-before-4xx ordering (a proxy 502 whose body says
"bad request" stays retryable), Chinese / numeric provider billing
patterns, and DNS / TLS infrastructure-fatal detection.

Fix the cert-trust pattern while adding its test: Java's ValidatorException
emits "PKIX path building failed" with an uppercase PKIX and the error
chain is not lower-cased, so the previous lowercase pattern never matched
— an untrusted/expired cert chain fell through to the retryable
SERVER_ERROR bucket and was retried in vain instead of failing over.
2026-06-15 08:09:59 +08:00
MIST
42f1d5b685 fix(chat): resilient retry for transient AI gateway errors 2026-06-15 08:02:02 +08:00
倪程伟
7c4380a116
feat(docs): expose bundled help docs via in-app viewer
Closes #330
2026-06-15 07:48:49 +08:00
倪程伟
515cba88ee test(feishu): add TTL filter and unit tests for recent-file disk fallback
loadRecentFilesFromDisk now filters out files older than RECENT_FILE_TTL_MINUTES
(60 min) so the disk fallback matches the Caffeine cache TTL and does not inject
stale attachments into future conversations.

Testability refactoring:
- recentFileCache: private → package-private (tests can seed the cache directly)
- chatUploadsRoot: new package-private Path field (tests redirect to @TempDir)
- loadRecentFilesFromDisk: add (Path dir, long cutoffMs) package-private overload;
  private (String) wrapper delegates to it
- injectRecentFiles: private → package-private

New test class FeishuRecentFileCacheTest (14 cases):
- loadRecentFilesFromDisk: non-existent dir, empty dir, fresh files sorted
  newest-first, stale files excluded by TTL, mixed fresh+stale, >5 files capped,
  timestamp-prefix stripping, MIME guessing from extension
- injectRecentFiles: Caffeine cache hit, cache-miss disk fallback, empty disk,
  duplicate-path dedup, image vs file part typing, null textContent guard

Relates to #325
2026-06-14 16:57:13 +08:00
matevip
936c8621ed fix(wiki): extract uploaded documents via a sandbox-exempt path (#323) 2026-06-13 07:29:39 +08:00
matevip
48024e4a83 fix(wiki): dedup pages by title and bound route prompt growth (#321) 2026-06-12 15:17:32 +08:00
matevip
e6f8da9606 fix(agent): recover tool-call follow-up on interleaved-thinking models (#256) 2026-06-12 11:07:55 +08:00
matevip
5235e30138 fix(tool): keep Snowflake ids precise across the tool boundary (#319) 2026-06-11 15:17:51 +08:00
matevip
bad216d686 feat(tool): add image_analyze for on-demand image re-analysis (#303) 2026-06-11 13:53:56 +08:00
matevip
aaf06b262c feat(agent): retain image context across turns for follow-ups (#303) 2026-06-11 13:53:56 +08:00
matevip
4a3d4cf568 fix(mcp): auto-heal stale MCP connections after server restart (#317) 2026-06-11 09:59:25 +08:00
倪程伟
18daad79b2
feat(wiki): unify raw materials & source watcher into a Sources tab with per-KB auto-sync (#316)
* feat(wiki): unify raw materials & source watcher into a Sources tab with per-KB auto-sync

The raw-material directory scan and the Advanced "source watcher" sub-tab were
the same engine (same kb.sourceDirectory, same WikiDirectoryScanService) split
across two surfaces with two editable directory inputs. Merge them into one
"Sources" tab (upload / paste / directory manual scan + auto-sync toggle +
the raw-material list) and drop the watcher sub-tab from Advanced.

Auto-sync is now per-KB opt-in: a new watcher_enabled column (V146) gates the
periodic scan per knowledge base. The server-global mate.wiki.watcher-enabled
stays as an ops master switch — a KB is auto-scanned only when both are on
(AND). Manual scans are unaffected. Scan interval stays global for now
(tracked separately).

Closes matevip/mateclaw#314

* docs(wiki): document source-watcher global switch env vars

Expose MATE_WIKI_WATCHER_ENABLED / MATE_WIKI_WATCHER_INTERVAL_MS as
explicit placeholders in application-mysql.yml, .env.example and
docker-compose.yml, mirroring MATE_WIKI_ALLOWED_SOURCE_ROOTS. Notes the
AND semantics (global ops gate + per-KB toggle) so operators know the
global switch alone is not sufficient.
2026-06-11 09:29:26 +08:00
matevip
83615593cd fix(tool/guard): harden workspace filesystem sandbox (#313)
- Fail closed to a global fallback sandbox root when a conversation has no
  per-workspace base path, instead of leaving file/shell tools unconstrained
- Refuse shell commands that delete the workspace root directory itself
- Block workspace-boundary escapes at the policy layer before the approval
  prompt, not only at execution time
- Approval bar now shows the actual command / target path being approved
2026-06-10 17:17:07 +08:00
matevip
7478491652 feat(llm): add Claude Fable 5 support 2026-06-10 10:14:51 +08:00
matevip
c1fd39a1e2 fix(agent/plan): 分流器证据闸门防止复杂任务不执行就停止(v2 剥离 memory-context) 2026-06-09 17:55:26 +08:00
matevip
846c1c31ca fix(channel): bound webchat conversationId/username to prevent VARCHAR(64) overflow
The webchat conversationId (webchat:<key8>:<visitorId>[:<sessionId>]) and the
derived username (webchat:<visitorId>) are written to VARCHAR(64) columns, but
visitorId had no validation and sessionId allows 64 chars — so a long visitorId,
or a legitimate 64-char sessionId, overflows the column and the getOrCreateConversation
INSERT throws (500 on /stream). Validate visitorId (charset + blank->UUID) and
fold the variable part into a stable hash when the derived id/username would
exceed 64 chars, keeping short ids byte-identical (backward compatible). Also
make listSessions filter on exact owner username, not just the conversationId
prefix, so system-owned rows can never leak via a crafted visitorId. Adds
boundary regression tests.
2026-06-09 11:36:41 +08:00
倪程伟
77b6baeccc feat(channel): webchat session-management endpoints (list / messages / delete)
Add per-visitor session management for the WebChat Web/API access mode:
list a visitor's conversation threads, fetch a thread's messages, and
delete a thread.

Authorization: visitorId is a client-asserted request param, so it cannot
be trusted on its own — deriving conversationId from it and then checking
ownership against it is tautological (any caller passes). Instead, /stream
issues a per-visitor token = HMAC-SHA256(jwtSecret, channelId:visitorId),
returned in the meta event; the management endpoints require it back via
the X-MC-Visitor-Token header and verify it in constant time. The signing
secret is server-only (unlike the public channel API key) and the channelId
in the payload makes tokens non-portable across channels.

Includes regression tests for token issuance/verification semantics
(forged visitorId rejected, cross-visitor and cross-channel tokens rejected,
tampered tokens rejected).
2026-06-09 11:10:13 +08:00
倪程伟
a40868eff2 refactor(feishu): 群会话 ID 改用完整 chatId 避免后缀碰撞
旧实现群会话 conversationId = feishu:{appId后4}_{chatId后8},截断后缀
存在碰撞风险:不同群 chatId 后 8 位相同 → 消息落进同一会话、上下文串台。
群会话改用完整 chatId(feishu:{chatId})消除碰撞。

存量迁移(读时别名回退,不重写存量行):
- 旧后缀不可逆推完整 chatId,故不做一次性回填;
- 但每条入站群消息都带完整 chatId + appId,可在路由前重算 legacy key;
- 新群 / 已迁移群 → 用 feishu:{chatId};存量群(canonical 无、legacy 有)
  → 沿用 legacy key,历史无缝延续,零停机、零破坏性写。

- ChannelMessageRouter 增只读 conversationExists(id)(委托 findByConversationId)。
- 私聊不受影响(DM 经 buildConversationId 直接用完整 senderOpenId,后缀本就不参与)。

Closes #299
2026-06-09 11:10:09 +08:00
matevip
c362d12425 test(llm): update MultimodalRouterTest for honour-explicit-sidecar behavior
The multimodal sidecar selector change made resolveSidecar honour an explicit
sidecar selection even when the built-in capability heuristics don't recognize
the model (it now logs a diagnostic and returns the model instead of rejecting
to NONE). The test still asserted the old reject->NONE path. Update it to assert
SIDECAR and the honoured model, matching the current production behavior.
2026-06-09 10:53:56 +08:00
matevip
f699746d65 test(memory,wecom): align two stale tests with current production behavior
Both failed on dev independently of the recent merges (confirmed against a
pre-merge baseline):

- MemorySummarizationStructuredRoutingTest reflected applyStructuredEntries by
  its old (Long, JsonNode) signature; owner-isolation added a trailing ownerKey
  param. Update the reflective lookup to (Long, JsonNode, String) and the
  remember() verifications to the 6-arg overload.

- ToolGuardCardHandlerTest still asserted the old 'system-owned pending accepts
  any clicker' behavior, but the handler now rejects a group click on a
  system/cron-owned approval fail-closed (no human requester to match), routing
  it to the admin console. Assert no synthetic injection + the unauthorized card
  render instead.
2026-06-09 10:15:36 +08:00
matevip
3209868274 test(trigger): await async dispatch in ChannelMessageTriggerTest
Decoupling the channel-message event bridge onto an @Async listener means the
downstream workflow run is produced off the event-publishing thread. The test
read the run table synchronously right after publishEvent, racing the listener
— the positive cases failed and the negative cases passed for the wrong reason.
Poll briefly for the run (positive) / give the listener time then assert none
(negative) so the test reflects the async dispatch semantics.
2026-06-09 10:00:30 +08:00
matevip
fcc2dd5ccf fix(feishu): stop co-mentioned humans being learned as bot aliases
The mention alias-learning fed every identifier of every mention in a
delivery into the per-chat alias cache. A single delivery of "@bot @alice"
matched the bot by its global id and then learned alice's openId as a bot
alias, so every later "@alice" message was misdetected as @bot and the agent
replied to messages never addressed to it.

Only single-mention deliveries are unambiguous bot identities, so restrict
alias learning to them — a multi-mention delivery mixes the bot with
co-mentioned humans, and Feishu's dual-delivery alias form is itself a single
mention, so this is safe and keeps the learning feature working. Also cap the
per-chat alias set size. Adds a [bot, human] co-mention regression test.
2026-06-09 09:36:10 +08:00
倪程伟
74b2607e40 feat(feishu): 群聊 @机器人 别名学习,修复部分 mention 漏检
mention 事件里 bot 的标识可能是 unionId/userId 或群内自定义别名,
仅用 botOpenId 直接比对会把确实被 @ 的消息判为「未 @我」。

- 拉取并缓存 botName(/bot/v3/info 的 app_name),mention 比对增加按 name 命中
- eventMentionsContainBot 对 openId/unionId/userId/name 做集合命中判断
- detectBotMentionWithLearning:双投递场景下机会性学习群内别名,
  按群隔离写入 chatBotAliases[chatId],后续单事件投递即可命中
- mentionTracker(带 TTL)做短期相关性跟踪,cleanupMentionTracker 按 TTL 淘汰

仅影响群聊 mention 判定;私聊不变。不改会话 ID / 去重 / 日志级别。

Closes #298
2026-06-09 09:36:10 +08:00
matevip
94cf812207 feat(tool): add execute_code for running agent-authored code (#257)
Add an execute_code built-in tool that runs python/bash/node code the agent
writes on the fly, so a documentation-only skill (a SKILL.md with no bundled
scripts) can be acted on. Scoped runs inject the skill's secrets and run in
the skill directory; otherwise a private scratch directory is used. Host
secret env vars are scrubbed from the subprocess. execute_code is an
agent-wide capability, registered in the tool catalog (V143), and screened
by the tool guard with a dedicated set of destructive-pattern rules.

Tests cover python/bash/node execution, scratch-dir fallback, env scrubbing,
argument decoding, and guard gating.
2026-06-09 08:05:50 +08:00
倪程伟
cd3ae0c001 feat(agent): append static About You identity block to system prompt 2026-06-08 20:53:39 +08:00
倪程伟
2e1ef6b4b1 feat(agent): thread runtime model/provider into per-turn context injection 2026-06-08 20:53:39 +08:00
倪程伟
bd1ceace74 feat(agent): render runtime model identity line in RuntimeContextInjector
Add 5-arg buildContextMessage overload that emits [system-context] Model:
for every origin (web/cron/IM). Legacy 3/4-arg overloads delegate to the
new one with null model args, keeping their output byte-identical.

Also fix pre-existing FeishuMentionTest compile error caused by removed
mentionMatchesAnyAlias/collectMentionIdentifiers methods.
2026-06-08 20:53:39 +08:00
倪程伟
37e9afa9de fix(wiki): match glob against symlink-resolved scan root
The base directory is canonicalized via toRealPath before walking, so the
walked files carry the symlink-resolved prefix. The PathMatcher was built
from the literal pattern, so a symlinked base never matched and files were
silently dropped. Rebuild the glob against the resolved scan root, escaping
glob metacharacters in the base so a real directory name containing */?/{}/[]
is treated literally.
2026-06-08 20:51:03 +08:00
matevip
3c87efdb15 feat(chat): 购物推荐结果渲染为可点击商品卡片
- 聊天 markdown 渲染器解析 product-cards 围栏为卡片网格(图片/价格/平台/去购买按钮),整卡可点跳购买页
- DOMPurify afterSanitizeAttributes 钩子补回被 ALLOWED_URI_REGEXP 剥掉的 target/referrerpolicy,确保防盗链图片加载与新标签打开
- 后端在购物推荐工具结果尾部追加卡片渲染指令,保证模型稳定输出卡片而非表格
- 技能:购物意图优先调用参考价工具并约定 product-cards 输出格式
2026-06-08 15:11:56 +08:00
matevip
be7bbd9644 fix(skill): persist skill workspace on the existing data volume; skip binary entries in ZIP packages (#273) 2026-06-07 23:09:42 +08:00
matevip
5ebdccb1f6 feat(agent): scope agent knowledge base access to a bound subset (#261) 2026-06-07 22:41:14 +08:00
matevip
86cb449bd5 fix(skill): keep skill workspace paths stable while fixing non-ASCII collision
The #254 fix changed resolveConventionPath to {name}-{hashCode} and folded
hyphens to underscores, which re-pathed every existing skill (browser-cdp ->
browser_cdp-<hash>) with no migration, orphaning already-created workspaces and
breaking SkillWorkspaceManagerApplyBundleTest. Drop the hash suffix and keep
hyphens: the bare Unicode-preserving sanitized name already prevents the
non-ASCII collision (distinct CJK names map to distinct dirs) and leaves ASCII
kebab-case paths identical to the legacy scheme. Add path regression tests.
2026-06-07 20:06:19 +08:00
倪程伟
398d7a2d80
feat(agent): deterministic Markdown normalization for final answers (#275)
LLMs routinely emit malformed Markdown (missing heading spaces, glued `---`, unaligned table pipes) that prompt rules cannot reliably prevent. Add a zero-token, regex-only MarkdownNormalizer applied on the FinalAnswerNode convergence path before persistence / channel delivery. It is code-fence aware, idempotent, and conservative (em-dash `---`, `#5`-style refs, stray prose pipes are left untouched). RETURN_DIRECT verbatim output and approval-wait paths return earlier and are unaffected.

Closes #274
2026-06-07 19:10:53 +08:00
matevip
39b6bdc522 test(skill): fix listAvailableSkills arity and cover agent-binding enforcement 2026-06-07 17:34:43 +08:00
matevip
7894a50067 fix(tool): emit absolute download URLs for streaming-generated files (#164)
Streaming chat ran render tools on an async thread with no bound request,
so download links lost their host and arrived without a domain. Resolve the
host on the request thread and carry it through ChatOrigin/ToolContext;
falls back to a configurable public-base-url, then a relative path.
2026-06-07 15:03:48 +08:00
matevip
76c6504527 fix(llm): preferred provider now drives primary model selection — per-provider model resolution + unconfigured-provider skip 2026-06-04 07:36:31 +08:00
matevip
b22462105c test(agent): exercise real capability gate in ProviderRouter primary-selection tests 2026-06-03 23:39:19 +08:00
倪程伟
5746bcf8cc
feat(agent): 偏好提供商作为主模型选择依据 (#223)
偏好提供商从「仅 capability 触发」改为两轮筛选,使 Agent 偏好提供商能决定主模型选择;并在 Agent 显式配置 modelName 时优先 honour,不被偏好提供商覆盖。

Closes #222
2026-06-03 23:33:14 +08:00
matevip
3883b68cca fix(goal): drop score gate, bill failed evaluator calls, fix Evaluator SPI + tool prompt + bootstrap cap 2026-06-03 21:19:27 +08:00
matevip
a756da7817 test(goal): rewrite evaluator tests for bootstrap/verdict modes 2026-06-03 21:19:27 +08:00
matevip
77196acbcd test(goal): checklist codec + service coverage; final internal-ref sweep 2026-06-03 21:19:27 +08:00
matevip
c5ccce8ebc feat(goal): deterministic completion + remaining-criteria followup + auto-followup gates 2026-06-03 21:19:26 +08:00
matevip
cd1c66fc0e feat(goal): structured checklist data model — criteria column, criterion records, dual-carrier evaluation result 2026-06-03 21:19:26 +08:00
matevip
48611a6f4d feat(memory): per-owner memory isolation with owner_key + visibility scope (#235) 2026-06-02 17:04:06 +08:00
matevip
40ce1c67ac fix(tool): persist generated files to disk so download links survive restart and 10-min window (#243) 2026-06-01 21:35:53 +08:00
matevip
1388b6eec8 feat(wiki): add wiki_update_page (in-place edit) and wiki_stale_pages tools 2026-05-31 08:00:19 +08:00
matevip
e18e0f1029 feat(wiki): per-agent pageType permission config API and pending-approval recording 2026-05-31 07:59:48 +08:00
matevip
7363ee8668 feat(wiki): pipeline definition CRUD/YAML API, run query API, page-created trigger 2026-05-31 07:59:41 +08:00
matevip
ea0ace1e49 feat(wiki): propagate staleness when a fact page is updated during ingest 2026-05-31 07:59:27 +08:00
matevip
55cf2a8458 feat(wiki): wire layer derivation and fact-dependency persistence into ingest 2026-05-31 07:59:20 +08:00
matevip
8e8c1e34c7 feat(wiki): inject pageType profile into route/create/merge prompts + content templates 2026-05-31 07:59:13 +08:00
matevip
551321b542 fix(wiki): make pageType permission service a mandatory dependency 2026-05-31 07:58:59 +08:00
matevip
6583aa1e42 fix(wiki): close symlink TOCTOU and size-bypass in scan; single-read binary hash 2026-05-31 07:58:17 +08:00
matevip
aac04cdfa4 fix(wiki): re-ingest modified binary files via content-hash detection 2026-05-31 07:58:10 +08:00
matevip
4ffe7026d2 fix(wiki): block per-file symlink escape and stop sourcePath clobbering 2026-05-31 07:57:57 +08:00
matevip
f3a335f4f6 fix(wiki): re-ingest modified text files via content-hash change detection 2026-05-31 07:57:50 +08:00
matevip
4c56df2ed3 fix(wiki): add fail-closed option for empty source-path allow-list 2026-05-31 07:57:44 +08:00
matevip
3a781ef0d9 test(wiki): cross-feature end-to-end domain scenario 2026-05-31 07:57:31 +08:00
matevip
8b4e1a12f9 feat(wiki): scheduled single-owner source-directory watcher 2026-05-31 07:57:25 +08:00
matevip
cc8c9cf951 feat(wiki): knowledge-layer filter on wiki search 2026-05-31 07:57:18 +08:00
matevip
ad1f5b4a15 feat(wiki): fire count-threshold pipeline triggers after ingest 2026-05-31 07:56:58 +08:00
matevip
526a361488 feat(wiki): restricted Skill pipeline step executor 2026-05-31 07:56:51 +08:00
matevip
15a8b2d73c feat(wiki): LLM pipeline step executor via model routing 2026-05-31 07:56:45 +08:00
matevip
85f5df394b feat(wiki): page-type count-threshold trigger for pipelines 2026-05-31 07:56:38 +08:00
matevip
5278568594 test(wiki): drop unnecessary @DirtiesContext from new E2E tests 2026-05-31 07:56:31 +08:00
matevip
6e0e62556f feat(wiki): pipeline run orchestration with pluggable step executors 2026-05-31 07:56:24 +08:00
matevip
c3388c3f1e feat(wiki): pipeline runtime schema — definitions, runs, step runs 2026-05-31 07:56:17 +08:00
matevip
66e4788226 feat(wiki): fact/experience dependency graph and stale propagation engine 2026-05-31 07:56:10 +08:00
matevip
28284fbcac feat(wiki): layered-knowledge schema — layer, dependency table, stale columns 2026-05-31 07:55:55 +08:00
matevip
7a79fe93d0 test(wiki): isolate profile/metadata E2E tests from the shared file DB 2026-05-31 07:55:44 +08:00
matevip
16a7aadbcd feat(wiki): unified source-path validation with symlink resolution and allowed roots 2026-05-31 07:54:48 +08:00
matevip
eb63ce4865 feat(wiki): validate and persist structured page metadata on ingest 2026-05-31 07:54:41 +08:00
matevip
b50e384e0d feat(wiki): inject KB pageType profile into the batch-create prompt 2026-05-31 07:54:34 +08:00
matevip
bea48bcf89 feat(wiki): pageType profile CRUD API and service operations 2026-05-31 07:54:27 +08:00
matevip
7cd9971596 feat(wiki): schema validator for structured page metadata 2026-05-31 07:54:20 +08:00
matevip
7f4987c30a feat(wiki): resolve effective pageType profile per KB with built-in default 2026-05-31 07:54:13 +08:00
matevip
368797e619 feat(wiki): add KB-scoped pageType profile table and page metadata columns 2026-05-31 07:54:06 +08:00
matevip
ec47d19bf8 feat(wiki): gate wiki write/mutate tools by pageType permission 2026-05-31 07:53:59 +08:00
matevip
502b8406a6 feat(wiki): per-agent pageType read permission gate for wiki tools 2026-05-31 07:53:48 +08:00
matevip
f1c55b80e8 feat(memory): route summarized typed facts into structured memory 2026-05-30 07:36:20 +08:00
matevip
de98368b4e feat(channel): shared inbound media pipeline with magic-byte typing and retry 2026-05-30 07:30:38 +08:00
matevip
7e9f2ee54c fix(memory): prefer recalled personal memory over knowledge base for user/project questions 2026-05-29 18:03:13 +08:00
matevip
d4ea75a806 fix(approval): deny approval-required tools in non-interactive runs 2026-05-29 18:03:13 +08:00
matevip
ceb4da642b fix(memory): rebuild agent on workspace file change so memory edits apply 2026-05-29 16:05:21 +08:00
matevip
a27084f9cf feat(memory): recall project facts via query-conditioned prefetch 2026-05-29 16:05:10 +08:00
matevip
96ed3e8aa7 fix(feishu): mirror router conversationId fallback for recent-file cache 2026-05-29 10:15:06 +08:00
matevip
237f649e7e fix(tool-guard): trust shared skill root outside the workspace boundary 2026-05-29 09:59:19 +08:00
matevip
82538ca3aa feat(llm): add Claude Opus 4.8 + 4.8 Fast model entries 2026-05-29 07:06:19 +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
af9928bf54 fix(wiki): case-only rename portability + SpringBootTest regression suite 2026-05-28 08:18:01 +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
2b3c068db9 feat(wiki): broken-link lint with job-based async scan 2026-05-28 08:17:04 +08:00
matevip
65cf53779a refactor(approval-grants-ui): paginated list, Element Plus icons, shorter sidebar label 2026-05-27 15:08:41 +08:00