53 Commits
Author SHA1 Message Date
薄生andCursor 4632d0f429 feat(users): limit resource visibility by user group (#2224)
* feat(users): limit resource visibility by user group

Admins can create groups and assign members. Skill packages, knowledge
bases, connectors, models, and named storage backends can then be
restricted to those groups without granting extra edit rights.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(users): gate connector and storage use by group and show the catalog

Replace per-instance connector and storage grants with one feature-level control, list every resource kind on the group page, and make skill-package sharing follow a single audience choice.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-20 15:38:30 +08:00
58327d2ebb feat(skills): shared packages, file tree editor, and BOM-safe frontmatter (#2226)
* feat(skills): shared packages, file tree editor, and BOM-safe frontmatter

Add skill-package sharing (private by default), package skill file-tree APIs
aligned with personalization, and strip UTF-8 BOM when parsing SKILL.md.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(tests): bump backup schema assertions to v22

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-19 21:16:08 +08:00
42e41ed33e feat: add one-shot tasks and split personalization permissions (#2157)
Scheduled jobs can run once and then stop, personalization tabs can be granted separately, and rotated logs use a date-before-extension name.

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-18 07:11:24 +08:00
mengzhangand薄生 043f845498 feat(skills): export selected skills and skill packages as ZIP (#1990)
* feat(skills): export selected skills and skill packages as ZIP

Workspace skills can be checked and downloaded together, and a skill package
exports in the same top-level folder layout the ZIP importer already accepts. (#260)

* feat(skills): let skill packages disable ZIP download

Creators and admins can turn off package export. Other users can still view
and mount the package, but cannot download it.

* feat(skills): default package download from the copy policy

* test(db): expect schema v21 after package download migration

---------

Co-authored-by: 薄生 <67680641+Bosheng0422@users.noreply.github.com>
2026-10-16 20:56:57 +08:00
seed30andCursor 067d4b45c4 fix(weixin): keep a durable send token and repair old cron columns (#1999)
* fix(weixin): keep a durable send token and repair old cron columns

Rename legacy cron_jobs.trigger to schedule_spec on startup. Store the WeChat context token on the session so cron can still deliver after a restart, and drop tool preambles on team WeChat streams.

* refactor(weixin): keep the send-token rules in one place

The session table no longer imports the gateway package. Token merge and team-stream preamble filtering behave the same.

* chore: require octop-gateway 1.0.2

The WeChat reply fixes and the QQ single-bubble replies ship in this gateway release.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-14 19:53:32 +08:00
seed30 a6db56af98 Merge origin/develop into fix/provider-revoke-api-key
Keep the provider revoke fix in Unreleased and take the 1.0.2b7 notes from develop.
2026-10-13 10:34:25 +08:00
seed30 6f19e9a268 fix(providers): clear the API key when authorization is revoked
Revoke sends api_key null, and the patch treated null as leave unchanged, so the provider stayed authorized. Explicit null now clears only that field.
2026-10-12 20:44:18 +08:00
jubaoliang aaa0dbde48 feat(dashboard): align the permission picker with custom navigation (#1941)
Keep chat always available, and let experts, automation, and token usage be granted in the same groups and order as the operator's sidebar.
2026-10-12 16:40:41 +08:00
Bosheng0422 b5b3d49ad9 merge develop into fix/delete-persisted-conversation-data 2026-10-10 15:45:15 +08:00
7f19f9222e fix: preserve desktop listen config and accept folder drops in chat (#1874)
Desktop startup was saving a hardcoded bind address and could launch a second Octop when the preferred port was busy. Chat uploads dropped folders, shared peer experts are no longer offered for delete, and the state backend stays available only for experts that already use it.

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-10 14:42:37 +08:00
Bosheng0422 9ba836e0b1 delete conversation and expert data 2026-10-09 21:01:08 +08:00
Fei.Chenandvicfei aef219100f feat(skills): per-package copy policy for skill packages (#770) (#1336)
skill_packages gains copy_policy (snapshot default / lock / deny), set by the
creator or admin via PATCH. deny rejects the workspace copy endpoint with
SKILL_PACKAGE_COPY_DENIED and disables the dashboard button (can_copy). lock
stamps each copied SKILL.md with origin/locked frontmatter; the existing
package-only write guard now also rejects writes to stamped copies for
everyone but the origin package creator (admins keep an escape hatch for
orphaned copies). Copy attempts are audited. Agent-tool-level write
protection for locked copies needs harness support, tracked separately.

Co-authored-by: vicfei <4058491+vicfei@users.noreply.github.com>
2026-09-30 14:52:43 +08:00
f5e46c974b feat: add Octop↔Octop cloud collab for remote experts (#1281)
* feat: add Octop↔Octop Bridge for remote agent access

Enable admin-managed peer connections with WS tunnel, path allowlist,
hello_ack handshake, SSRF guards, and Chat shadow-agent hydrate so
operators can probe and use remote agents from the local dashboard.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: serialize bridge turn chunks and flag remote experts

LangChain HumanMessage objects in peer turn.chunk frames crashed
json.dumps; add a bridge JSON default. Show a 远端/Remote badge on
shadow experts in the picker and sidebar lists.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: bridge avatars, named remote badges, and auto-reconnect

Keep bundled / CDN icon URLs for shadow experts and only proxy uploaded
avatars. Show the bridge display name on remote badges. Add a default-on
auto-reconnect switch that backs off on disconnect and disables itself
after repeated failures, recording the reason in last_error.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat: add card/table views for bridge connections

Match the storage page card layout and add a Segmented toggle so
admins can switch between a card grid and a table of remote links.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: render bridge expert icons correctly on the chat page

Encode bridge agent ids in avatar URLs the same way as chat WS paths,
fall back to Lucide when the image fails, size portraits to fill the
sidebar avatar, and refresh AgentContext when icon_url changes.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat: tunnel peer models and knowledge bases for bridge chat

Allow read-only GET of peer providers/resolved, active-model, and
knowledge-bases (plus capability) through the Bridge tunnel, expose
local bridge connection routes, and point the chat composer at those
sources when talking to a shadow expert. Hide local connectors for
remote sessions. Also allow agent subagents paths on the tunnel.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: scope bridge chat expert picker to peer agents

When the active expert is a Bridge shadow, the composer expert picker
and @-mentions only list peers on that connection (not local experts).
Encode bridge agent ids for skills and subagents list/install paths.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: hint remote chat pickers to manage settings on the peer

In Bridge sessions, replace local “manage …” footers for models,
skills, knowledge bases, experts, and subagents with a muted
“edit on remote” tip and a toast instead of navigating to local admin.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat: polish bridge remote UX and tunnel agent status

Allowlist GET …/status so hubs can read real peer harness state (peers need
this build). Keep history-migration hub-local, skip noisy bridge polls in the
UI, move Bridge under Settings, and mark remote experts with cable + name.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat: tunnel remote expert catalogs and polish bridge connection UX

Hub can edit peer subagents, memory, channels, tools, plugins, and MBTI
through the tunnel; surfaces that cannot hop show an in-drawer hint. Peer
must run this build so the new allowlist takes effect.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat: group cloud-collab experts and unify header-tunneled composer APIs

Keep the selected remote expert on disconnect, gate peer-only surfaces in the UI, and stop forking composer/task requests through dedicated bridge endpoints.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat: add search to the Experts toolbar

Filter my experts, teams, and the library from the existing button row so long catalogs stay scannable.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: keep inbound cloud-collab cards peer-owned

Inbound links can only edit name/icon/notes; disconnect, delete, and auto-reconnect stay disabled. Peer offline shows as 离线, peer delete removes the card, and the default inbound name is the short connection id.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: polish inbound cloud-collab UX and unify 对端 copy

Peer-initiated links can only edit display info and cannot redial;
offline cards may be deleted. Local-only pages hint when a peer
expert is selected.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: map peer team speakers onto Bridge shadows

Peer team chats stamped local member ids, so the hub fell back to the host
avatar. Rewrite roster and stream speakers onto bridge:{cid}:{id} shadows,
and keep the local team picker from mixing in peer experts.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: stop rewriting team thread ids in the Bridge tunnel

Member job threads are {room}~{agent}. A blanket JSON replace of the peer
agent id turned those into hub shadows, so history 404ed on the peer.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: rewrite peer media URLs and keep bridge turn composer fields

Live send_file_to_user frames still pointed at peer-local /api/agents/{id}.
Map every teammate id in tunneled JSON, and copy the full dashboard turn
body so knowledge bases and HITL policy are not dropped on the peer.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: rename bridge probe tests to avoid pytest module clash

tests/unit/bridge/test_probe.py collided with tests/unit/mobile/test_probe.py
during collection (same basename).

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat: collapse extra experts on Bridge cards and fill avatars

Show at most four experts on a connection card, with the rest behind
expand. Portraits fill the 40px ring without a tinted background.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: lulinzhi37-alt <lulinzhi37@gmail.com>
2026-09-29 16:49:37 +08:00
5b59b03959 feat: store role-template id on users.role and harden mobile composer (#1220)
Collapse the dual user_role_id / role model so users.role and invites.role
hold the template public id, block deleting roles still in use, and keep
the chat composer visible under mobile browser visualViewport.

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-27 19:43:30 +08:00
6cf61fa458 fix(db): apply schema v18 via idempotent helper for old restores (#1183)
Raw 018 SQL alters user_invites even when the table is missing on pre-invite backups. Route v18 through _ensure_user_role_schema and bump watermark assertions to 18.

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-26 23:53:19 +08:00
ac8c233180 feat(users): add role templates, invite snapshots, and profile avatars (#1180)
* feat(users): add role templates, invite snapshots, and profile avatars

Roles fill defaults for create, edit, and invite without rewriting existing users. Account type stays independent of the selected role.

Co-authored-by: Cursor <cursoragent@cursor.com>

* style: format role and invite repositories for ruff

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: narrow invite role name before lookup

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-26 22:43:09 +08:00
347dee56f4 refactor(infra): group agents modules and clarify package ownership (#1164)
* refactor(agents): group thin modules into domain subpackages

Move plugin helpers, memory, settings stores, persona/MBTI, and avatar
bootstrap code under plugins/, memory/, settings/, persona/, and experts/
while keeping top-level import shims so existing call sites stay stable.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(agents): drop compatibility shims after subpackage move

Call sites already import the new package paths; remove the top-level
re-export stubs so the agents tree only shows real modules.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(agents): move thread helpers into threads/

Group artifact shaping, fork, and context breakdown under
agents/threads so top-level only keeps lifecycle/config adapters.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(agents): fold profile/runtime/tool catalog into settings/

Move the remaining config-surface helpers under settings/ and drop the
skill_package id-list aliases in favor of dump/parse_id_list.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(agents): group workspace_dir and execute_env under workspace/

Keep path resolution and harness execute-env injection together as one
workspace package; leave only manager and conversation_mode at top level.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(infra): fix history/SkillHub ownership and drop thin providers/

Move history_projection under history/, share SkillHub host/limits and
route expert skill downloads through skills.skillhub_market, and fold
Codex OAuth helpers into agents.providers to remove the tiny providers/
package.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs: sync AGENTS.md and guides with infra/agents layout

Reflect subpackages (settings/workspace/threads/persona, history/, skills/)
and drop stale runtime.py / mbti_profiles paths after the agents reorg.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-25 22:32:41 +08:00
694a8cea8d feat(teams): 主持人先改写再派工,成员回复同步到 IM 通道 (#1064)
用户原话不再原样转给成员;通道原先只看得到主持人短答,成员收口后补推带说话人的完整消息。

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-23 22:48:26 +08:00
jubaoliangandCursor 69f31656c3 feat(chat): add per-thread HITL allow policy
Keep tool-approval bypass on the conversation (allow this tool / allow all)
without changing global security settings. Also let expert create carry
welcome quick prompts, and replace the login forgot-password tip with a
platform-specific CLI dialog.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-22 17:14:28 +08:00
jubaoliangandCursor ae7dfc8b0f feat(chat): add Ask / Plan / Craft conversation modes (#934)
* feat(chat): add Ask / Plan / Craft conversation modes

Keep mode sticky per thread, enforce Ask/Plan in harness-agent, and let Plan write a workspace plan before Craft executes it.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Update pyproject.toml
2026-09-21 22:18:28 +08:00
jubaoliang b46bb8a480 fix(db): 写事务改用 BEGIN IMMEDIATE,避免多进程下「先读后写」被中止
Merged from #888.
2026-09-21 03:04:50 +00:00
IronMurphyandsclfcz 353a85bcf2 fix(knowledge): 删除文件夹时不再误删名字相近的文件夹 (#889)
KnowledgeRepo.delete_document() 用 path LIKE '<目录>/%' 匹配子项,其中目录名来自
用户输入且未被清洗(normalize_kb_path 保留 % 与 _),于是:

1) `_` / `%` 被当作 LIKE 通配符 —— 删除文件夹 a_b 会连带删除 axb/ 下的文档:

     removed == {'a_b', 'a_b/keep.txt', 'axb/survive.txt'}   # 应为前两项

2) SQLite 的 LIKE 对 ASCII 不区分大小写,PostgreSQL 区分 —— 删除 Docs 在 SQLite
   上会连带删除 docs/ 下的文档,同一操作在两种后端删除的集合不同。

改为大小写敏感的前缀比较 substr(path, 1, ?) = ?(两种后端语义一致、无通配符)。

Co-authored-by: sclfcz <hepanshuo@gmail.com>
2026-09-21 10:53:37 +08:00
jubaoliang 12e5b706cc feat(teams): add expert team hosts without changing 1:1 chat (#868) 2026-09-21 10:24:09 +08:00
24c00b0297 feat(auth): multi-provider OAuth SSO (Feishu, DingTalk, WeCom) (#687)
* feat(auth): add pluggable Feishu OAuth and multi-identity SSO binds

Introduce App OAuth (Feishu) alongside OIDC, persist multiple SSO
identities per user, and simplify the admin provider UI for coexistence.

* fix(dashboard): restore OIDC SSO checklist and login preview

Keep the OIDC admin card unchanged; only App OAuth cards use the
callback-only aside.

* feat(auth): add DingTalk and WeCom App OAuth SSO adapters

Enable dashboard login/bind for DingTalk and WeCom alongside Feishu, with
WeCom CorpApp wwlogin (CorpID + Agent ID) and DingTalk authCode callback support.

* feat(dashboard): redesign account SSO bind list and default names

Use an icon + status + action row list in personal settings for App OAuth
binds, and prefill empty provider display names in the admin SSO cards.

* feat(dashboard): split admin SSO settings into per-provider tabs

* fix(auth): log SSO callback failures and silence httpx URL leaks

* docs: changelog for multi-provider OAuth SSO

* style: ruff format users/manager.py after SSO conflict merge

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 11:55:26 +08:00
jubaoliang 5b6c91302c feat: expert composer defaults (KB + MCP) and per-user policies
Allow experts and skill packages to carry composer defaults so that
installed/created agents start with the author's chosen knowledge bases
and MCP servers. Defaults are persisted as agent profile columns and
validated against the installing user. Adds the per-user policy resource
table (migration 014) and wires the dashboard composer fields plus
locale strings.

- Add knowledge_base_ids and mcp_servers to the agent profile schema
- Validate KB/MCP ids on expert/skill-package install and create paths
- Persist defaults via migrate.py helper and 014_user_policy migration
- Surface composer default fields in the dashboard expert/skill UI
2026-09-11 02:00:01 +08:00
jubaoliang 52bad9c4d0 feat(users): per-user resource policies (workspace root + token quota) and slash parser
Add a `user_policies` table (migration v14) backing per-user `workspace_root_dir`
(restricts local backend roots) and `token_quota` (lifetime token limit). Token
quota is enforced in the agent runtime via TokenQuotaMiddleware. Extract slash
command parsing into infra/gateway/slash/parser.py and expose policies on the
users API. Frontend adds admin policy UI, storage/chat/experts restyle, and a
shared TabLabel / PageLoading component.
2026-09-08 14:21:28 +08:00
HUANG Cheng cda6e3000f feat(usage): date-range filter and Excel export for token stats (#599)
* feat(usage): date-range filter and Excel export for token stats

Add RangePicker presets/custom ranges, multi-sheet Excel export with
localized headers and charts, and filter coverage for #154.

* fix(usage): export detail sheet in ascending time order

Keep the newest N rows when truncating, then reverse so Excel opens
oldest-first for chronological reading.

* fix(usage): sort export detail ascending in SQL

Order detail rows with a newest-N subquery then ts ASC so Excel opens
oldest-first; restart-sensitive Python reverse was easy to miss.

* fix(usage): keep Excel TOTAL row out of Sort range

Leave a blank spacer above the SUM TOTAL so Excel contiguous Sort
does not move 合计 with the filtered detail rows.
2026-09-08 14:21:00 +08:00
jubaoliangandCursor 3358d01542 fix(backup): restore old archives after schema changes without 500s
Migrate immediately after overlay and repair folded v13 connectors schema so existing backups stay usable. Refuse newer schema versions with BACKUP_SCHEMA_INCOMPATIBLE. Also drop the knowledge-bases Beta nav badge.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-06 11:43:15 +08:00
jubaoliang 05b7548284 feat(connectors): support multiple connector instances and shared connectors 2026-09-06 10:30:40 +08:00
HUANG Cheng b67a124598 feat(chat): Trajectory drawer with ledger and live stream (#553)
Synthesize tool-call-only parents, stamp turn/duration metadata, and fall
back to content-size estimates so Turns/Calls/Duration toggles work on
legacy and burst-stamped events. Gather harness turn context and rename
conflicting trajectory unit test modules.
2026-09-03 20:36:17 +08:00
jubaoliang fc03a941c3 feat(cron): persist scheduled turns and keep gateway transport-only (#549)
Move cron delivery out of Gateway so dashboard text jobs write canonical history, AI jobs notify consistently, and inbound turns stay serialized with the published harness APIs.
2026-09-03 17:59:37 +08:00
liukewia c305010e86 feat(cron): add name field to cron jobs and update related interfaces (#525)
* feat(cron): add name field to cron jobs and update related interfaces

- Introduced a `name` field to the `OctopCronRow`, `OctopCronCreateBody`, and `OctopCronPatchBody` interfaces.
- Updated localization files to include validation messages for the new `name` field.
- Added a constant for maximum name length.
- Enhanced the UI to display the job name in the cron jobs table and detail views.
- Updated API documentation to reflect the new optional `name` parameter in cron job creation and updates.
- Implemented database schema changes to support the new `name` field in cron jobs.

This change improves the user experience by allowing users to assign descriptive names to their cron jobs, making them easier to identify.

* feat(cron): restrict cron job management to owners only

- Updated the cron job management logic to ensure that only the owner of a cron job can create, view, update, or delete it.
- Modified the API endpoints to return empty lists for non-owners attempting to access cron jobs.
- Enhanced the frontend logic to reflect these changes, ensuring a consistent user experience across the application.
- Updated related tests to verify that cron jobs are correctly scoped to their owners, preventing unauthorized access.

This change improves security and clarity in the management of cron jobs within shared agents.

* refactor(cron): improve code readability in cron management functions

- Reformatted the `_assert_cron_manage` function for better readability by adjusting the parameter layout.
- Simplified the invocation of the `create` function in the test case for clarity.

These changes enhance the maintainability of the code and improve the overall structure of the cron management logic.
2026-09-03 11:13:10 +08:00
10e862406e fix(db): duplicate v10 migration skipped thread projection tables (#461)
* fix(db): resolve duplicate schema v10 migrations skipping projection tables

Two 010_*.sql files raced: kb_max_documents bumped the watermark first and
skipped thread_message_projection. Keep a single 010 and repair missing tables.

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(agents): disable memory in harness create/close unit tests on Windows

Avoid Windows access-violation when memory GC races HarnessAgentManager.close
under pytest-xdist; unrelated to the schema v10 fix but was failing PR CI.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-27 17:27:04 +08:00
chujieHong 90b8ca2560 feat(knowledge): 支持按知识库配置文档数量上限 (#427)
- schema v10: knowledge_bases 新增 max_documents 列(默认 100,0=不限制,上限 10000)
- 上传时按 KB 自身上限在 SQL 事务内原子拦截,第 N+1 个文档被拒绝
- 前端编辑模态框在"描述"与"图标"之间新增"文档数量上限"输入项,保存即同步
- 详情面板"X/Y 文档"文本、上限 Alert、上传按钮均改用该 KB 自身上限
- SQLite 通过启动兜底加列,PostgreSQL 使用 ADD COLUMN IF NOT EXISTS 幂等迁移
2026-08-27 15:38:05 +08:00
薄生andCursor c38e5c028f Feature/long session issue fix (#453)
* 长session卡死优化

* chore: cut 0.9.29b0 and pin harness-agent 0.9.27

Long-session testers pull this branch from source; bump above 0.9.28 and
lock vacuum-safe harness-agent / harness-memory so Codex installs pick them up.

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore: retag beta as 0.9.27b0 so PyPI 0.9.28 still looks newer

Lets non-editable installs click Update to leave the long-session trial.

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore: cut 0.9.29 for merge (drop beta tag)

Current main is 0.9.28; this branch ships as the next stable version.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-27 15:06:43 +08:00
chujieHong 76db0e1752 feat(knowledge): 支持知识库文件夹重命名 (#417)
* feat(knowledge): 支持文件夹重命名

- repo: 新增 rename_document,使用 path_parent + normalize_kb_path 计算新路径,
  对文件夹执行基于 substr 的精确前缀匹配(替代 LIKE,避免 _/% 通配符误匹配),
  同步重写所有后代文档的 path 字段
- service: 新增 rename_document,处理权限、名称校验、幂等性与重名冲突,
  同名重命名直接返回避免无谓写库
- api: 新增 POST /{kb_id}/documents/{doc_id}/rename,新增 KNOWLEDGE_NAME_INVALID
  错误码(400)与 KNOWLEDGE_NAME_TAKEN 错误码(409)路由映射
- 前端: KnowledgeBases 文件夹行删除按钮左侧新增重命名按钮(type=text size=small),
  弹窗复用 Modal + Input,名称未变时直接关闭、不发请求
- i18n/locales: 新增 KNOMEDGE_NAME_INVALID 错误消息及重命名成功/失败提示
- tests: 新增 4 个 repo 测试、5 个 service 测试、2 个 api 错误映射测试,
  覆盖后代路径改写、跨根/嵌套文件夹、重名冲突、含分隔符拒绝、幂等、ACL 拒绝

* fix(knowledge): remove stray SKILL_DETAILS_PROTECTED error code

The folder-rename PR accidentally carried SKILL_DETAILS_PROTECTED from an
unrelated feature branch into ErrorCode and _DEFAULT_STATUS without its
i18n entries, failing test_dashboard_api_errors_match_backend and
test_every_error_code_has_i18n_entry in CI. Drop it here; the
published-expert skill-details feature ships it separately with locales.
2026-08-26 10:28:48 +08:00
jubaoliangandjubaoliang 18ab9f6ba9 feat: workspace backend sandboxing, execute-env injection, and ephemeral image refs (#376)
* feat: workspace backend sandboxing, execute-env injection, and ephemeral image refs

Workspace file-I/O hardening across backend and dashboard:
- Host directory sandboxing via root_dir allow-list and denied prefixes
- Execute-environment defaults injected into harness backend specs
- Ephemeral workspace image rematerialization for model calls
- Attachment hint expansion and inbound store improvements
- Portable memory backend and skill workspace catalog updates
- Dashboard UI for agent backend fields and root-dir selection
- Bump harness-agent 0.9.23 / harness-memory 0.9.7; docs + install notes

* feat: add user invitation codes with admin management and redeem flow

- Add user_invites table (migration 009) plus SQLite/Postgres reconcile paths
- Add InviteRepo and InviteService for create/revoke/list/redeem
- Expose public validate/redeem endpoints and admin create/revoke/list routers
- Extract default-agent bootstrap into octop.infra.agents.default_agent
- Add invite error codes and en/zh i18n strings
- Dashboard: invite drawer, login redeem UI, users list, and locales

* fix: add Windows cross-platform guards for pre-existing sandbox/rootfs tests

- Guard POSIX/container-only tests (rootfs-absolute /.octop/... workspace
  paths) with posix_only in test_thread_artifacts.py and test_agent_manager.py
- Normalize the rendered workspace path assertion in test_octop_builtin_skills.py
  (forward slashes on Windows, not str(tmp_path) backslashes)
- Canonicalize ws_dir before the prefix check in attachment hint/path tests
  (tempfile may yield an 8.3 short path on Windows while the resolved
  attachment path uses the long form)

These failures predate the user-invites commit and are unrelated to it; the
product path logic is correct.

---------

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
2026-08-21 22:32:48 +08:00
Pandaandleoxyang 8c21334022 fix(usage): add cache-aware token accounting (#352)
Co-authored-by: leoxyang <leoxyang@tencent.com>
2026-08-20 16:25:21 +08:00
e07824e6a9 Fix/agent env usage workspace (#351)
* fix: inject Admin env into running agents and sum turn token usage

Running shells and Docker sandboxes now pick up ~/.octop/env (and workspace .env) without a full reload; MCP stdio no longer inherits the entire host environment. Usage accounting adds every model call in the turn, and workspace I/O survives the harness rebuild window.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat: schema v7 identity, expert profiles, chat artifacts, and KB citations (#346)

* feat: schema v7 identity, expert profiles, chat artifacts, and KB citations

Fold integer PKs plus public string ids, document folders, agent profile columns, and thread artifacts into v7 SQL (not only Python helpers). Experts get workspace avatars and a single welcome_message; chat keeps file changes across sessions, shows knowledge citations, and can drag workspace files.

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore: drop cron JobDrawer UX from the schema v7 PR

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: prefer tool-arg paths when recording chat artifacts

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 10:17:39 +08:00
jubaoliangandjubaoliang 041628cb76 feat: per-user module permissions (RBAC) with admin bypass (#276)
* feat: add per-user module permissions (RBAC) with admin bypass

Introduce a module-level permission system so non-admin users can be
scoped to a subset of dashboard modules. Adds a `permissions` TEXT column
on the `users` table (migration 006, SQLite + PostgreSQL), a central
permission catalog in `infra/users/permissions.py`, backend ACL checks
across routers, and dashboard gating via `RequirePermission` /
`ForbiddenPage` keyed by nav module. `admin` always bypasses every gate;
read access and chat/agent use are never gated.

* fix: gate connector install-cli by connectors permission (not admin-only)

The host CLI installer is a connectors-module operation and should be
gated by the `connectors` module permission, consistent with the rest of
the connector routes, instead of being admin-only.

The earlier RBAC change demoted this route from `current_admin` but the
test `test_install_cli_forbidden_for_non_admin` still failed because the
`create_user` test helper grants `BASELINE_PERMISSIONS` (which includes
`connectors`) by default, so the "non-admin" user actually held the
permission. Gate the route with `require_permission("connectors")` and
create the test user with `permissions=[]` so it genuinely lacks the
key and is rejected with 403.

---------

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
2026-08-14 14:05:37 +08:00
jubaoliangandCursor 64403fda88 feat: squash schema v5, HITL tool picker, runtime installs, KB/skills UX
Consolidate unreleased develop migrations 005–009 into one v5 file with
ensure/clamp paths for pre-squash local DBs; add HITL catalog picker,
shared runtime package install for ONNX/desktop, and short-id list UX for
knowledge bases and skill packages.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-13 12:00:53 +08:00
jubaoliangandCursor 1af14b8031 chore: wire shared agents, SSO, experts, ONNX, and knowledge into the app
Register routers/repos/migrations, OpenAPI tags, i18n/error codes, sidebar routes, and docs for the new platform capabilities.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-12 18:56:23 +08:00
jubaoliangandCursor e8a824bb1e feat(knowledge): add knowledge bases with chat retrieval
Introduce document indexing, embedding (ONNX/remote), and chat/IM injection with default-open selection in the dashboard composer.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-12 18:56:23 +08:00
jubaoliangandCursor d9a20b40ef feat(auth): add OpenID Connect SSO login
Support admin-configured OIDC with PKCE, one-time login code exchange, and dashboard SSO management/complete flows.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-12 18:56:23 +08:00
jubaoliangandCursor 8cbb94262a feat(experts): publish workspace snapshots as installable templates
Let owners publish an agent workspace as a reusable template, refresh/unpublish it, and let others install a private fork. Also adds expert color/emoji pickers used by subagents and publish UI.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-12 18:56:23 +08:00
jubaoliangandCursor e62073a602 feat(agents): allow sharing agents with other users
Add is_shared so owners can expose a runtime agent for others to chat with while keeping config writes owner-only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-12 18:56:23 +08:00
Panda 860cdc3912 feat: add per-user model and reasoning preferences (#221) 2026-08-11 10:12:56 +08:00
jubaoliang ecad9ec3da feat: chat stream resume, shared terminal dock, and thread title repair (#157)
Keep dashboard chat turns attachable after reconnect, reuse one terminal
session store across Workbench and the chat dock, and migrate legacy
hard-cut thread titles to clipped titles with ellipsis.
2026-08-04 15:40:58 +08:00
jubaoliang 2a3df89642 feat: global skill packages with ZIP import and personalization layout (#108)
* feat: add global skill packages with local ZIP import and personalization layout

Introduce instance-level skill packages (DB + disk), mount them on agents, and
support SkillHub/URL/ZIP import. Merge related schema into migration v2 and
cover the zip import path with frontend and API tests.


* fix: hot-sync skill package mounts and dark-mode package cards

Avoid full agent rebuild when mounting packages so Experts UI no longer
hits AGENT_NOT_FOUND; accept workspace-scoped local backends on Windows;
use theme token for package list card background.
2026-07-31 11:03:17 +08:00
薄生 dca16ccc21 Feat/postgresql dual backend (#60)
* feat: PostgreSQL dual-backend for control plane

Add SqlitePool|PostgresPool behind DatabasePool, parallel PG migrations,
setup wizard defer/bind, pg_dump backups with cross-engine refusal, and
memory defaulting to the control-plane DSN when using PostgreSQL.

* fix(chat): delete checkpoint data when a conversation thread is deleted

Deleting a thread only removed Octop's own metadata row; the actual
message history stayed in the agent's LangGraph checkpointer forever,
making "delete conversation" cosmetic. Also confirm before deleting a
session in the UI, since the action is now genuinely destructive.

Checkpoint deletion runs before the metadata row is removed: if it
fails outright (not just "nothing to delete"), the thread stays
visible/retryable instead of orphaning data with no remaining handle.

* fix(memory): stop suggesting pg_dump for portable export of postgres memory

The 501 hint told users to "use pg_dump on the memory schema instead".
That advice predates the shared-table layout: memory for ALL agents now
lives in one harness_memory schema isolated by a namespace column, so a
schema-level pg_dump would export every agent's memory, not just the
requester's — a cross-agent data exposure if followed on a multi-user
install.

Document the two migration models where the refusal is implemented:
sqlite memory is per-agent files moved via pack/adopt; postgres memory
is shared, and the supported way to use it from another host (e.g.
OpenClaw's harness-memory bridge with --backend postgres) is pointing
that host at the same DSN and namespace — shared, not migrated.

* fix(test): update test_slash_compact to renamed SqlitePool

The /compact test module still imported the pre-rename DBPool, which
broke collection (ImportError) on this branch after develop's compact
feature was merged in — DBPool was renamed to SqlitePool (the concrete
class) with DatabasePool now the Protocol.

DBPool -> SqlitePool at all three sites: the import, the _agent_manager
type hint, and the fixture's DBPool(path) instantiation. SqlitePool is
the byte-for-byte successor of DBPool and matches how every other test
constructs a pool; DatabasePool cannot be used at the instantiation
site (a Protocol is not instantiable).

pytest -m live now collects cleanly (31 selected, 0 errors);
test_slash_compact 3 tests pass.

* fix(test): make memory_backend db_path assertion separator-agnostic

test_explicit_sqlite_overrides_postgresql_control_plane compared the
resolved db_path against the literal "/tmp/ws/memory.sqlite", which the
code never produces on Windows: it builds the path with pathlib, so the
Windows CI job got "\tmp\ws\memory.sqlite" and the string equality failed.

Compare as Path objects so the assertion holds on every OS separator,
matching the .as_posix() discipline already used in test_config.py.
2026-07-24 14:45:53 +08:00