88 Commits

Author SHA1 Message Date
dolphin 3e96e963d7 build(frontend): pnpm workspace + @bisheng/ui shared component library
- Convert src/frontend to a pnpm workspace (catalog-pinned shared deps,
  only-allow pnpm, npm lockfiles removed, both Dockerfiles on corepack/pnpm)
- New packages/ui (@bisheng/ui): source-shipped presentation-only library.
  First component Button (moved from client, which keeps a re-export shim so
  all call sites work unchanged), cn util, two-layer design tokens
  (tokens.css + tailwind-preset incl. dark ramp), design-token.cjs SSOT
  moved here (client re-exports it)
- Component docs move into packages/ui/docs (git-tracked); rspress site stays
  hosted in client, root/outDir repointed, button demos import @bisheng/ui;
  doc_build + playground artifacts gitignored
- pnpm-migration fixes: pin vite-plugin-node-polyfills to 0.23.0 (0.23.1
  unenv rewrite breaks CJS named-export detection), rollup/vite overrides
  matching the old npm resolutions, fs/promises + node:fs/promises stubs
- Harness rules: new packages/ui/AGENTS.md (library contract, token SSOT
  discipline, interaction rules, component definition-of-done); client
  AGENTS.md gains design-system hard rules; commands/docs updated to pnpm
2026-07-22 18:52:21 +08:00
LineWalker 7669c1a3cf docs(agents): dedupe layered AGENTS.md, add runtime topology + backend pitfalls
- root: fix client react-query v5->v4 (@tanstack ^4.28), add 5-line runtime
  topology block to §1, release-contract.md path in SDD step 0, accurate §7
  pitfall pointers, docs-index pointers and instruction-file loading map in §8
- frontend platform/client: remove the 7 hard rules duplicated from root §4
  (single source of truth; kills the <600 vs <=600 drift), keep only
  app-specific rules; promote any-minimize + named-exports to root §4
- backend: new Known Pitfalls section (tenant auto-filter is SELECT-only —
  bulk UPDATE/DELETE and raw SQL need hand-written tenant conditions; ruff
  PostToolUse hook drops not-yet-used imports; Celery Beat x multi-tenant
  context; DB config 100s Redis TTL) + Quick Map accuracy fixes
- docs/README.md: drop dead links (qa/, archive/, gateway-deploy dir), add
  PRD/ and observability/ rows

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 19:07:21 +08:00
LineWalker 7050b7d165 fix(linsight): bound write_file truncation loop with tool-loop breaker + salvage
Root cause: a large write_file `content` arg is truncated (finish_reason=length)
before its bytes are emitted, so parse_partial_json drops the key and every retry
re-raises "content: Field required", spinning to recursion_limit=200 (~19min). Not
a model-can't-count-2-args problem — the huge tool argument gets cut off/parsed away.

- L2: detect finish_reason=length + a truncated tool call in the resilience
  middleware, nudge to write in smaller parts, bounded retry (truncation_retry_limit).
- L3: new LinsightToolLoopBreakerMiddleware — soft corrective hint then hard stop
  (aafter_model raises LinsightToolLoopError) on consecutive same-tool failures,
  with guards against aborting a model that recovered / switched tools.
- L4: classify GraphRecursionError / LinsightToolLoopError as TASK_ABORTED.
- Salvage: _handle_task_partial renders the intermediate analysis + retrieved
  knowledge as a normal (COMPLETED) result instead of a raw recursion error;
  shared across the fresh/resume/continue drivers via _stash_partial_abort.
- Config (LinsightConf): tool_failure_soft_limit=3 / tool_failure_hard_limit=8 /
  truncation_retry_limit=2.

72 unit tests + 1 integration test (aafter_model raise propagates through a real
create_agent().ainvoke(), beating recursion_limit).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 17:32:12 +08:00
GuoQing Zhang 0156395a6a docs(F042/T012): 监控层指标日志契约文档 + 收尾
- docs/observability/metric-log-contract.md: BS_METRIC 字段字典 + 6 类指标算法口径
  + Loki LogQL/ES 查询示例 + 运维开关表 + 契约变更约束
- 实现完成 12/12(Wave 1+2+3);design 修订历史 + tasks 状态更新
- 回归:89 相关测试全过 + bisheng.main 导入干净;9 个 tenant_mount 失败为
  pre-existing MySQL 集成测试(seed 去重,CI 中间件territory,非本feature)
2026-07-03 17:16:00 +08:00
LineWalker 644ceea911 feat(linsight): restore tenant skill runtime via copy-time provisioning (F035 Fork X)
Re-enable the F035 task-mode Skill runtime that was disabled 2026-06-16. Instead of
the dormant TenantSkillsMiddleware runtime whitelist, use a copy-time gate (Fork X):
at task startup materialize_session_skills copies the run's allowed bundles
(governance-enabled ∩ user-selected) into the session workspace /skills/ subtree, then
a plain deepagents SkillsMiddleware (FilesystemBackend over the workspace cache, which
is dir-aware unlike the MinIO WorkspaceBackend.ls) enumerates them; the model reads the
same /skills/<name>/SKILL.md paths back through the workspace. The copy is the whitelist
gate, so unselected skills never reach the agent — no per-run active_skills config.

- skill_provisioning.materialize_session_skills (new) + SkillStore.read_bytes
- thread skills: LinsightQuestionSubmitSchema + linsight_session_version.skills (JSON col
  + migration f035_linsight_skills) + workbench_impl + task_exec._create_agent
- agent_factory attaches SkillsMiddleware when skills_present
- TenantSkillsMiddleware retired to dormant (docstring); whitelist semantics moved here
- fix(client): selecting a skill in /c task-mode no longer toggles task mode OFF
- tests: test_skill_provisioning (gate, byte fidelity, cross-tenant, enumeration loop)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 21:09:54 +08:00
LineWalker 7a910160c8 refactor(linsight): segment-stream execution flow via write_todos boundaries
Replace the implicit-cursor todo attribution with a single segment stream cut
at write_todos calls (B2 single-bucket), so parallel/loose todo marking can no
longer mis-attribute or strand steps in empty "running" todos.

Backend (stream_event_mapper.py):
- stamp all main-graph steps (tool-start / thinking / interrupt) to ctx.svid
- delete the current_in_progress_task_id cursor (_refresh_in_progress + its
  _diff_todos call + the StreamContext field); _diff_todos / _status_transition
  / GenerateSubTask are untouched (TaskPanel stays status-driven, zero regression)
- agent_factory.py: drop the "single in_progress at a time" prompt rule

Frontend:
- stepUtils: write_todos becomes the segment boundary (kept through merge, only
  namespaced subagent-internal ones dropped); buildTimelineGroups flushes on it
- R1: segment titles are activity summaries + elapsed (com_linsight_act_summary)
- R3: full subagent flattening — explodeSubagentGroup renders each subagent as
  its own top-level segment; remove SubagentTeamGroup / SubagentTrack
- R2: degraded narration (in-segment thinking last sentence), collapsed-only

TaskStepRow self-nullifies on empty history, so the existing
ExecutionTimeline(sessionSteps) becomes the single stream with no carrier
changes and free backward-compat for old reload data.

Tests: test/linsight 327 passed; Execution/* 39 passed; tsc clean on touched files.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 15:58:51 +08:00
LineWalker 856d8f3cb0 Merge origin/feat/2.6.0-beta4: 灵思任务模式前端双线重写汇合
本地 timeline 架构重写为 UI 主线,完整保留远端独有功能逻辑与修复。

冲突解决(3 处手工 + 4 处自动):
- useLinsightManager.tsx: 自动合并 — 本地 roundId/历史终态字段 + 远端
  mapSessionVersionStatus(not_started/in_progress/waiting_for_user_input
  → Running,HITL/排队状态刷新后保留)
- tailwind.config.cjs: keyframe 取并集 — thinking-appear(本地) +
  sheen-sweep/text-shimmer(远端)
- TaskTurnPanel.tsx: generating 提示用本地 BreathingRow,弃用远端内联 div
- SubagentRow.tsx: 保持删除 — 本地 SubagentTeamGroup/SubagentTrack 替代
- ExecutionFlow/TaskPanel/test_subagent_reintroduction.py: 自动合并

远端独有工作整体保留:OBS 403 fix、task-mode HTML 预览修复、HITL/排队
刷新保留、task turn 终止持久化、workspace 面板动画、bisheng-icons 0.2.20、
task-mode UI polish。

验证:前端 vite build 通过(1m19s);后端 test_subagent_reintroduction
+ test_stream_event_mapper 35 passed;4 个被删组件零残留引用。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 18:02:12 +08:00
GuoQing Zhang ed009d3938 fix(telemetry): prefix event_data keys with enum value, not member repr
Since Python 3.11, f-string formatting of a str-mixed Enum member returns
str(member) (the repr 'ClassName.MEMBER') instead of its value. This
corrupted every telemetry event_data key into e.g.
'BaseTelemetryTypeEnum.APPLICATION_PROCESS_app_id' instead of the expected
'application_process_app_id'.

Use event_name.value explicitly when building the per-field keys. Add
regression tests asserting key prefixes, and sync docs to Python 3.11
(pyproject already pins requires-python >=3.11).
2026-06-18 17:15:15 +08:00
LineWalker ccde364d97 feat(linsight): fix task-mode render — subagent 22→3, thinking aggregation, B2 delegation
Increment 1 of the execution-flow render optimization (design docs under PRD/).

Backend (B2): the main-graph `task` call becomes the delegation row —
step_type=subagent, name from tc.args.subagent_type (default general-purpose),
call_reason/extra_info.delegate_goal from description. Namespaced subagent-internal
tools keep their real tool/knowledge type (B1 already landed upstream). Rewrites
the subagent-reintroduction tests + step_types fixture to match.

Frontend: buildFlowNodes groups subagent-internal steps by distinct subgraph
namespace with lazy team-group creation — 22 mislabeled "delegate <tool>" rows
collapse to the 3 real subagents, with no empty-group crash during streaming.
mergeAdjacentThinking stitches token-delta thinking into one passage; firstLine
row titles fix the hardcoded English "thinking"; MergedStep reads frame.timestamp;
SubagentRow shows "N tools · M thoughts" (was counting thinking as tools); the
node build is memoized; tailwind gains the thinking-appear keyframe; +7 i18n keys
across 3 locales.

Verified: jest 14/14, pytest test/linsight 306 passed; deployed and confirmed on
114 (22→3, no crash, correct tool counts; DB: subagent=3, namespaced web_search
all step_type=tool, task frames step_type=subagent/general-purpose).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 16:34:28 +08:00
LineWalker b6f8340084 docs(linsight): add task-mode runtime-chain vs deepagents context-engineering comparison
Single merged analysis of the linsight task-mode execution chain (submit ->
worker -> create_deep_agent -> astream) and how its context engineering
compares to the deepagents demo. Serves as the basis/background for the #1
subagent re-introduction.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 02:41:10 +08:00
LineWalker 8c2ea7797e feat(linsight): re-introduce task subagent delegation (#1)
Re-enable the deepagents `task` tool with a single "general-purpose"
researcher subagent, defusing both original root causes by construction
(not by stripping the tool):
- HITL bubbling (root cause B): the subagent spec carries an explicit tools
  list without ask_user and no permissions/interrupt_on, so it has NO
  interrupt source — a subagent can never park, so the bug cannot recur.
- over-delegation (root cause A): depth-1 (subagent has no nested task) plus
  a delegation-budget prompt section.

agent_factory.py
- drop _disable_subagent_delegation + _ToolExclusionMiddleware({"task"})
- add _subagent_tools blacklist (_SUBAGENT_TOOL_DENY/_KNOWN_HITL_TOOL_NAMES)
  and _build_researcher_subagent (name="general-purpose" same-name override)
- add 派发预算 section to LINSIGHT_SYSTEM_PROMPT_ZH + LINSIGHT_RESEARCHER_PROMPT_ZH

stream_event_mapper.py
- drop namespaced (subagent) todos from the main plan (if ns: continue)
- _infer_step_type DORMANT -> LIVE

stepUtils.ts (+ test, + fixture)
- read the subgraph namespace from extra_info.namespace (real backend
  contract) so subagent steps fold under their parent task step

task_exec.py
- resume path passes allowed_knowledge_ids: restores the parked tool/subagent
  topology and closes the C4 knowledge-whitelist bypass on resume

Tests: test_subagent_reintroduction.py (4) + stepUtils.test.ts (4), green.
Design doc: 灵思任务模式 #1 子代理重引入技术方案.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 02:28:32 +08:00
LineWalker c2494d0beb feat(F035): auto-run linsight backfills on startup; drop LLM from SOP→Skill migration
- Move the task-mode menu grant (WEB_MENU linsight_task_mode) and the
  default-model config migration into idempotent domain backfills invoked from
  main.lifespan (mirrors the F034 relation-model pattern; failure only logs and
  never blocks startup, self-heals on next boot). The two standalone scripts are
  now thin dry-run/apply CLIs over the shared domain logic.
- SOP→Skill migration no longer calls the LLM: a missing skill description falls
  back to the SOP name (description is mandatory — NOT NULL + rejected empty by
  SkillService), and the --no-llm flag is removed.
- Update the F035 upgrade checklist (08-deployment) + scripts/README: steps 2/3
  auto-run at startup, step 4 (SOP→Skill) stays a manual ops script.
- Add unit tests for both backfill pure transforms.
- main.py also picks up incidental ruff-format normalization (quotes/imports).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 14:22:47 +08:00
GuoQing Zhang 00d23dadb1 fix(dm): support specifying schema via ?schema= query string
DaMeng selects the active schema through the dmPython 'schema' connect
kwarg (default = login user). SQLAlchemy maps a URL path (/SCHEMA) to the
'database' kwarg, which dmPython rejects, so the old code stripped the path
for the sync engine only -- making sync (login user) and async (path schema)
diverge.

Replace _dm_sync_url with _normalize_dm_url: at construction, move any
path- or query-specified schema into ?schema= and clear the path, so the
sync (dmPython) and async (dmAsync) engines share one normalized URL and
resolve to the same schema. Explicit ?schema= wins over the path.

Verified live (sync+async) against DM and with unit tests. Documented the
?schema= convention in deployment docs and the config template.
2026-06-16 19:30:44 +08:00
LineWalker c96b97e5ea feat(F035): Linsight Skill 管理 — deepagents 迁移落地
- 后端:新增 skill endpoints/service/store/middleware + schema,router 挂载 skill 路由
- 模型:linsight_skill 扩展 display_name,新增 v2_6_0_f035 alembic 迁移
- 配置:LinsightConf 增加 skills_root(磁盘技能根目录,多节点需共享卷)
- 迁移脚本:migrate_sop_to_skill(SOP→Skill,slug 拼音化,依赖 pypinyin)
- 前端:SkillManagement/FormDrawer/DetailSheet/UploadDialog 组件 + AppCenter 页面,linsight API 扩展
- i18n:en/zh-Hans/ja 三端补全技能相关文案
- 测试:skill api/dao/service/store/middleware + 迁移脚本单测
- 文档:F035 spec/design/tasks/契约更新,PRD 重命名 + 新增 RAG 检索上下文优化 PRD
- chore: .claude/scheduled_tasks.lock 加入 gitignore

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 16:09:24 +08:00
LineWalker 46dcc3986e docs(linsight): revise deepagents migration PRD — workbench config merge & skill naming
- Add display_name / skill ID (name) dual-field definition for skills
- Add §4.8: merge Linsight workbench tab into daily tab (entry switch
  removed, task-mode naming, shared tool config, SOP library -> skill mgmt)
- Downgrade migration reconciliation report to ops summary log (AC-4)
- Restructure "+" menu into general-context and task-mode groups

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 11:09:36 +08:00
GuoQing Zhang 0e98aa6315 docs(linsight): 灵思任务模式 deepagents 迁移 SDD 文档 (F035)
编号 034→035(034 已被 knowledge-space-file-move 占用)。

features/v2.6.0/035-linsight-task-mode/:
- spec.md   薄 spec,AC-1..8 收口(需求真相在 docs/PRD 的 PRD)
- design.md 原《技术方案》,park-and-release / WorkspaceBackend / task_id 稳定性等终稿修订已内联
- tasks.md  9-Track 多人并行拆分 + Wave 编排
- 依赖与契约约定.md  C1–C7 接口冻结

release-contract 登记 F035:LinsightSkill 领域归属 / 110 段错误码 11050–11069 / linsight_skill 表。
PRD 与流程图保留在 docs/PRD/。
2026-06-11 16:32:29 +08:00
GuoQing Zhang 25da7800b5 Merge branch 'feat/2.6.0-beta4' of github.com:dataelement/bisheng into feat/2.6.0-beta4 2026-06-11 16:28:45 +08:00
GuoQing Zhang 6cadb65319 Merge branch 'feat/2.6.0-beta4' of github.com:dataelement/bisheng into feat/2.6.0-beta4 2026-06-11 16:28:01 +08:00
LineWalker b44691e880 docs: remove obsolete docs/archive directory
Drop archived v2.5 PRDs, review-process notes, cleanup-task lists and
legacy SDD plans/specs that are no longer referenced.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 16:17:14 +08:00
GuoQing Zhang 0b20674cb7 docs: add linsight task docs 2026-06-11 11:08:16 +08:00
LineWalker 5e4a21235d docs(linsight): add deepagents migration PRD for v2.6
Add PRD, technical design (adapter layer), and drawio flow diagrams
for migrating Linsight from the self-built ReAct engine to the
deepagents/Skill framework.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 18:15:44 +08:00
GuoQing Zhang 467d2e0b98 Merge OFD upload support (F032) + ES/Milvus langchain-1.x compat fixes into 2.6.0-beta4 2026-06-09 15:03:58 +08:00
GuoQing Zhang 1b804a1fb5 docs: record ElasticsearchStore client rename in upgrade impact doc 2026-06-09 11:39:35 +08:00
GuoQing Zhang a0f7be81d6 docs: record Milvus ORM-connection fix in upgrade impact doc 2026-06-09 11:12:21 +08:00
RUCYancy 3182059546 优化品牌定制运行时配置加载
新增品牌运行时静态脚本,管理后台和工作台启动前统一加载品牌配置。

新增品牌运行时 JSON 配置接口,返回已保存的品牌名称、Logo、加载页和 favicon 配置。

修复品牌素材相对路径在不同部署路径下可能重复拼接的问题。

更新品牌定制 PRD 中运行时配置接口和前端加载方式说明。
2026-06-09 09:53:02 +08:00
GuoQing Zhang 154f746ddc docs:remove unused docs 2026-06-08 16:54:15 +08:00
GuoQing Zhang ee725dcf01 Merge remote-tracking branch 'origin/feat/2.6.0-beta4' into feat/2.6.0-beta4
# Conflicts:
#	docs/archive/legacy-sdd/plans/2026-06-06-remove-autogen-ragas-evaluation-module.md
#	docs/archive/legacy-sdd/specs/2026-06-06-remove-autogen-ragas-evaluation-module-design.md
2026-06-08 16:42:05 +08:00
dolphin 9268fbefec feat: merge feat-2.6.0beta3 2026-06-08 16:07:38 +08:00
GuoQing Zhang 7576c18731 docs: LangChain 1.x upgrade impact scope and testing focus 2026-06-08 15:32:34 +08:00
GuoQing Zhang 17d1b7c49f docs: implementation plan for autogen/ragas removal + evaluation DDD module 2026-06-08 12:06:39 +08:00
GuoQing Zhang d30135fd66 docs: design for removing autogen/ragas deps and rebuilding evaluation as DDD module 2026-06-08 12:00:17 +08:00
dolphin cee2207f5b refactor: update architecture documentation, clean up local dev environment, and consolidate coding rules 2026-06-07 14:26:14 +08:00
RUCYancy cdc80ee619 feat: add brand customization settings 2026-06-05 17:49:25 +08:00
GuoQing Zhang 448ee894c3 feat(filelib): fair file-parse scheduling with per-queue concurrency cap
Replace the per-user in-flight ceiling (max_per_user_inflight) with a
global per-queue concurrency cap as the only hard limit, plus weighted
least-in-flight backfill for fairness.

- settings: queue_concurrency (per-queue cap) + per_user_pick_size
  (fairness weight); drop max_per_user_inflight/limit_for.
- run_dispatch_round: fill each queue up to its cap by repeatedly serving
  the user with the smallest in_flight/weight, so a single user can
  saturate a queue and a freed slot goes to the most-starved user (not the
  longest queue).
- lua: DISPATCH_ONE drops the per-user limit; new CONFIRM_DISPATCH bumps a
  per-queue inflight_total counter + records inflight_queue mapping;
  COMPLETE_FILE returns the slot to the right queue.
- reconcile: authoritatively recompute per-queue counters from the
  inflight_queue map to heal drift; purge_file/release_file return slots.

Tests: config, dispatch (fairness/weight/OCR dual-queue/saturation/D3
refill), reconcile recompute, plus Redis-backed Lua + e2e integration
tests against the configured Redis.
2026-06-05 15:31:16 +08:00
GuoQing Zhang 40dd9f0763 fix: F030 retrieve 支持知识库检索(不再仅限知识空间)
/api/v2/filelib/retrieve 之前对知识库 id 返回 18000(底层 aretrieve_chunks
是 F029 为知识空间建的,硬校验 type==SPACE)。现按 row.type 分派:

- 新增 _aretrieve_chunks_dispatch:type=3 走空间路径(view_space/view_file);
  type 0/1 走知识库路径;type=2 不可检索
- 新增 _aretrieve_chunks_for_knowledge_base:KB 读权限(ensure_knowledge_read)
  + KB 维度标签过滤 + 复用同一套 milvus/es 检索(去掉文件夹/版本逻辑)
- 新增 _resolve_kb_file_ids_by_tags(TagBusinessTypeEnum.KNOWLEDGE / KNOWLEDGE_FILE)
- 清理 beta3 遗留的未使用 import KnowledgeFileDao

附 F030 改动接口的 OpenAPI 规范 JSON(docs/PRD/知识空间优化/)。
e2e 实测:KB 检索 18000 → 200+chunks。已知限制:空 KB(无 ES 索引)检索
500 index_not_found,与知识空间 fresh-index 行为同类。
2026-06-02 20:16:08 +08:00
GuoQing Zhang 9cd673dd32 feat: F030 知识资源统一对外 API (v2 filelib facade)
统一 /api/v2/filelib 对文档知识库(0)/QA库(1)/知识空间(3)的处理:
endpoint 退化为 facade,按 type / row.type 分派到 KnowledgeService /
KnowledgeSpaceService,不在 endpoint 写业务、不新增 DAO 入口。

- 列表/文件列表改 cursor 分页(对齐 v1 + INV-6,无 total);KB 文件列表
  用 F027 AD-15 伪游标包现有 offset 查询
- 创建按 type 分派:KB 走 acreate_knowledge(忽略 auth_type/is_released);
  知识空间走 create_knowledge_space(忽略 model);type=2/非法 → 10962
- 检索新增 user_id 代用户检索(绑定 resolved 身份,闭合 F029 遗留越权口子);
  保留 filters 每库标签结构,不引入扁平 tags(无破坏性)
- 上传按 row.type 分派:空间走 add_file(parent_id),不改 KnowledgeFileProcess
- 文件列表空间分支:无 keyword 走 list_space_children,有 keyword 走
  search_space_children(新增 cursor 适配)
- delete/clear 按 row.type 分派:空间走 delete_space / 新增 clear_space
- 新增错误码 KnowledgeTypeNotSupportedError(10962)
- 个人库 type=2 对外不暴露(枚举保留,workstation/linsight 内部继续使用)

测试:facade 单测 16 + 真实后端 e2e 12 全过。
SDD: features/v2.6.0/030-knowledge-resource-unified-api
2026-06-02 14:39:44 +08:00
GuoQing Zhang 6b5639ef78 chore: remove unused code 2026-06-01 19:16:22 +08:00
GuoQing Zhang 388889ed90 refactor(user-group): 移除默认用户组的全部特殊逻辑,按普通用户组处理
默认用户组(group_id=2)不再有任何特殊之处:

- C1 资源解耦:删组不再迁移资源到兜底组、不清理 group_resource
- C2 角色解耦:删组不再级联删除组下角色
- C3 用户解耦:SSO/组织同步建号不再兜底进默认组(保留显式配置的
  default_groupid);用户可不属于任何用户组,访问由默认部门承载
- 移除 DefaultGroup 常量、预置仪表盘对默认组的授权
- 移除按组名隐藏默认组的过滤(后端 4 处 + 前端 UserGroup.tsx)
- 删除死代码错误码 UserGroupDefaultProtectedError(23002)/
  UserGroupHasMembersError(23003) 及一次性清理脚本
- 删组副作用去重:新旧两套删组路径共用 purge_user_group_residual_sync
- 清理随之孤立的 LegacyRBACSyncService.sync_group_resource_move

测试:test_org_sync_service 改为断言建号不绑组;test_user_group_service
新增删组解耦用例(不级联删角色、仍清理自身权限元组)。
2026-06-01 17:23:42 +08:00
GuoQing Zhang 13b797c777 Merge origin/feat/2.6.0-beta3 into file-parse-scheduler branch
Resolves conflicts in:
- core/config/settings.py: kept both FairSchedulerConf/KnowledgeFileWorkerConf
  and KnowledgeQAFilterConf as sibling settings fields.
- knowledge/domain/services/knowledge_service.py: took remote's F027 cursor
  pagination for list_knowledge; Task 8 scheduler swaps in process_knowledge_file
  / aprocess_knowledge_file unaffected (auto-merged).
- knowledge/domain/services/knowledge_space_service.py: took remote's F-feature
  additions (PRIVATE-switch notification, approval gate imports, cursor-paged
  list_space_children); Task 8 enqueue_or_dispatch call in add_file preserved.
2026-06-01 16:23:01 +08:00
GuoQing Zhang 7c3a70c947 docs(F026): knowledge QA permission filter spec + tasks + PRD
Add SDD artifacts for F026-knowledge-qa-permission-filter:
- PRD: docs/PRD/知识空间优化/知识空间AI问答-权限过滤.md
- spec.md ( 已评审, 14 项 sdd-review + 7 项修复)
- tasks.md ( 已拆解, 21 项 sdd-review + 4 项修复, 12 atomic tasks)

Scope: filter AI Q&A retrieval and citation source resolution
by the current user's view_file permission, across whole-space /
folder / file-preview / home & workstation chat entries; replaces
arch-guard RULE-8 VIOLATION in CitationResolveService._has_file_access.
2026-06-01 15:56:05 +08:00
GuoQing Zhang 588116d508 docs: update docs 2026-05-29 11:40:31 +08:00
GuoQing Zhang f6c7b4021e docs(scheduler): add file-parse-scheduler implementation plan
13-task TDD breakdown of the OCR-queue + fair-scheduler design spec at
docs/superpowers/specs/2026-05-20-file-parse-scheduler-design.md.
2026-05-28 17:28:03 +08:00
LineWalker d1fbd19cfd feat(knowledge): add POST /api/v2/filelib/retrieve open endpoint
Expose pure chunks retrieval as an OpenAPI surface so external systems
(e.g. DeepAgents-style agents bringing their own LLM) can use BiSheng
knowledge bases as a retrieval tool without engaging the SSE RAG path.

- POST /api/v2/filelib/retrieve, authenticated as default_operator
- Supports multiple knowledge bases in one call with per-KB tag filters
  (ANY mode; ALL reserved for future use)
- Each returned chunk is tagged with knowledge_id for source attribution
- Reuses _build_folder_search_kwargs + KnowledgeRetrieverTool (RRF +
  primary-version filter) from KnowledgeSpaceChatService
- 13 unit tests covering input validation, multi-KB merge, top_k
  truncation, tag-name resolution, and KB-not-found
- API reference at docs/api/filelib-retrieve.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 18:39:23 +08:00
dolphin 74f4241f70 feat: implement knowledge base version management infrastructure 2026-05-21 17:49:28 +08:00
GuoQing Zhang 1c74515f03 docs(testcases): add approval center test cases (66 cases, 11 groups)
Covers: gateway behavior, flow runtime, exception handling, admin config,
my-approvals, my-applications, 3 business scenarios (menu/channel/knowledge),
permission isolation, notifications, audit log, and boundary cases.
2026-05-20 18:15:00 +08:00
GuoQing Zhang 0599230a9d doc(scheduler): implement fair scheduling and OCR queue separation for file processing 2026-05-20 18:02:03 +08:00
GuoQing Zhang 4af83a2fe8 fix(approval): address code review findings — security, spec alignment, missing APIs
Security fixes:
- approval_gate: raise ApprovalScenarioDisabledError directly when scenario
  not configured or disabled; stop creating scenario_disabled exception instances
- approval_center_service: add tenant_id isolation check in get_task_detail and
  get_instance_detail to prevent cross-tenant data access
- approval_center_service: add approver identity check + task status idempotency
  guard in decide_task to prevent unauthorized decisions and double-processing
- resubmit_instance: create a new approval_instance instead of mutating old task
  records; preserves audit history and matches spec AC-21

Error codes (errcode/approval.py):
- Add 18104 ApprovalHandlerNotRegisteredError, 18105 ScenarioDuplicate,
  18106 ScenarioDisabled, 18107 RouteNotMatched, 18108 ApproverEmpty,
  18109 DuplicatePending to align with spec §6.4
- Move former 18104 ApprovalSettingsPermissionDeniedError to 18112

Missing admin APIs (approval_admin.py + service + repository):
- Add DELETE endpoints for scenario, route, flow, node
- Add PATCH /routes/reorder for branch ordering
- Add PUT /flows/{id}/nodes for full-node-list submission (triggers new version)
- Add GET /flows/{id}/versions/{version_id} for flow preview (AC-35)
- Fix _ensure_admin to raise HTTPException(403) instead of bare PermissionError

Other fixes:
- approval_user.py: pass operator_user_name in withdraw call so action_log records
  the operator name instead of None
- approval_instance.py: remove SCENARIO_DISABLED from ApprovalExceptionType
- approval_exception_service.py: remove dead retry_scenario_disabled branch/method

Docs & spec alignment:
- PRD: update gate return types; disabled scenarios return error, not PASS
- spec.md: add AC-33/34/35, missing API endpoints, error codes 18104-18109,
  test file entry; update AD-08, AC-02, AC-17 for new disabled behavior
- tasks.md: split T002→T002A/B, fix AC range notation, add T004 dep to T006,
  split T010A→test+impl, split T015→A/B/C, T016→A/B/C, add T017

Tests: update three test files to match new behavior (58 tests all pass)
2026-05-20 17:56:53 +08:00
GuoQing Zhang af2e916173 feat: upload 2.6.0 prd and spec 2026-05-19 14:05:46 +08:00
GuoQing Zhang d5a72b8bb6 Merge branch 'feat/2.5.0' into feat/2.6.0-beta1 2026-05-18 11:16:49 +08:00
GuoQing Zhang bdc9ca45c8 fix: deprecated old sso login api 2026-05-15 16:12:10 +08:00