* docs: refresh README roadmap, anchors, and product sync (#1211)
Align EN/CN README with shipped features and current install/channel
docs; fix GitHub heading anchors and drop obsolete extras examples.
Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(dashboard): define missing --fn-bg-container theme variable (#1216)
Dark-theme surfaces that use var(--fn-bg-container, #fff) — most
visibly the knowledge-base Markdown preview body, toolbar and outline
panel — resolved to a white background while text stayed light, leaving
preview content invisible. Define the variable as #ffffff (light) and
#141414 (dark), and point the Admin/Users badge tints that borrowed the
name for a translucent fill at --fn-bg-tertiary so their look is
unchanged.
Fixes#1215
* feat(dashboard): let each account customize the sidebar (#1218)
Store group order, item placement, and hidden entries on the user so navigation can be rearranged without showing items the account cannot access.
Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* style(dashboard): apply Prettier to files that drifted from the formatter (#1222)
Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* 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>
* docs: use product names for sibling project links in the README (#1225)
Link labels now match the product names while the repository URLs stay unchanged.
Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* chore: release 1.0.2b4
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Dang Zitou <dengzitao888@163.com>
Align EN/CN README with shipped features and current install/channel
docs; fix GitHub heading anchors and drop obsolete extras examples.
Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
CodeQL flags is_dir on an admin-supplied path unless realpath is contained with startswith first. Keep the denylist, and stat the directory only inside that guard.
Co-authored-by: Cursor <cursoragent@cursor.com>
CodeQL treats a "pypi.org" substring as an incomplete URL check, and SHA-256 of the OAuth verifier as password hashing. Label only the parsed hostname, and verify S256 with the RFC 7636 vector.
Co-authored-by: Cursor <cursoragent@cursor.com>
origin/develop already carried two identical copies of the same case;
keep a single assertion.
Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
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>
The 两种安装包 table listed octop-<ver>.fpk / octop-native-<ver>.fpk, which
no build stage emits: build-fpk.sh always appends the kind to the prefix,
CI sets FPK_NAME_PREFIX=Octop-fnos, and the v1.0.2b2 release carries
Octop-fnos-docker-1.0.2b2.fpk / Octop-fnos-native-1.0.2b2.fpk. The rest of
the file, including the manual-install step, already used those names.
Match the admin reset-password inputs by prefixing current/new password with Lock and confirm with LockOpen.
Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Avoid leaking internal names like execute in the live process hint; always use the shared “正在调用工具” copy while a tool is running.
Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* 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>
Lock in that a team member stays in liveSpeakers through tool rounds even after the host done frees the composer.
Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(chat): default-collapse thinking in team rooms only
Keep solo chat expanded by default, and store team/solo preferences under separate localStorage keys so toggling one does not affect the other.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(chat): keep team member replies in one bubble and clear stale live state
Continue member answer text across completed tools in team rooms, and stop
snapshots/wrap-up from leaving finished speakers marked live in the footer.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Default stays persistent (localStorage). Unchecking keeps the JWT in
sessionStorage for this tab only; SSO popups post the token back so the
opener can store it correctly.
Co-authored-by: Cursor <cursoragent@cursor.com>
GET /api/admin/audit-log forwarded an unvalidated `limit` into `LIMIT ?`,
the same gap #1018 closed for the thread list. SQLite reads a negative LIMIT
as "no limit", so ?limit=-1 returned the whole audit log in one response and
?limit=0 returned an empty page. Bound it with Query(ge=1, le=500), the
largest page the Settings -> Security audit panel offers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README.md documents `octop memory list/slim` and the /memory slim
chat commands, but README_CN.md's CLI reference table predates them.
Add the three memory rows and the /memory slim paragraph in Chinese,
matching the English README.
Improve team streaming visibility (live speakers, generating footer, IM
dispatch/wrap-up), relax ACP tool enable under sandbox while locking
runners, strip channel think tags per show_thinking, and clarify provider
CLI usage in the assistant skill. Includes self-update/UpdateConfig WIP
from the same working tree.
Co-authored-by: Cursor <cursoragent@cursor.com>
Plugin tools returning large octop_ui payloads (e.g. a bangumi season
with 1200+ episodes, ~228KB JSON) blew up the LLM context because the
same tool-result string served both the model and the UI.
Add OctopUiOffloadMiddleware at the innermost agent middleware layer:
when a ToolMessage content is a >=4000-char string carrying a non-empty
octop_ui renderer and data (and no file:// media refs), the payload is
moved in-place to ToolMessage.artifact and the model-visible content is
replaced by a compact result that keeps title/summary. Tool id,
tool_call_id, name and status are preserved.
Frontend restores rendering from artifact: ToolCallData.artifact,
closeToolCall extraction, history replay path, and resolvePluginUiData
prefers explicit data over data_ref. serialize.py surfaces artifact on
tool_result blocks; history recorder backfills artifact as fallback.
Spec: docs/octop-ui-payload-offload.md
Co-authored-by: jubaoliang <jubaoliang@gmail.com>
* 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>
Persist member file refs and tool history on team walls, open docks by producer agent, and inject truncated member answers into host follow-up so wrap-up can follow their advice.
Co-authored-by: Cursor <cursoragent@cursor.com>
Apply the remaining working-tree changes: connectors empty-state layout,
plus the knowledge, HITL, captcha, workspace, user-cache, and SSRF
adjustments with matching tests.
Co-authored-by: Cursor <cursoragent@cursor.com>
The harness-* libraries are now published as octop-harness, octop-gateway,
octop-memory, and octop-browser.
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat: admin user batch policies, token UX, default FS root, and media push hardening
Add admin user batch enable/disable/delete and resource policies (token quota,
max experts), improve token inputs with K/M presets, default unrestricted
local backends to host filesystem root, and tighten gateway tool-media push
with clearer path-outside-root stream errors.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(workspace): treat Windows drive roots as host-root sentinels
Default FS-root backends use C:/ on Windows; treating that as a scoped
jail put workspaces under the drive root and broke bootstrap/invite tests.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
`_map_knowledge_error` matched the literal "at most 100" to classify the
document-cap error, but `KnowledgeRepo.create_document` interpolates the
per-base `max_documents`, which has been user-configurable since 90b8ca25.
Any cap other than the default 100 therefore fell through to the base-cap
branch (the repo message also contains "knowledge bases") and the user was
told they had created too many knowledge bases.
Classify both caps by the stable wording of their own messages instead of
a magic number, and drive the mapping from the real repo in a regression
test so the wording coupling cannot silently rot again.
Co-authored-by: sxh <sunxianhong@ncti-gba.cn>
Co-authored-by: sxh313 <sxh313@users.noreply.github.com>
Co-authored-by: jubaoliang <jubaoliang@tencent.com>
files.document_path() keys the stored bytes on {doc_id}{suffix}, so a rename
that drops or swaps the extension moves the row off its own file: the
original-file route 404s, delete_document() unlinks the wrong key with
missing_ok=True and leaks the bytes, and re-saving an md/txt document
writes a second file. rename_document() now restores the document suffix
the way create_text_document() already normalises it; folders and names that
already carry the right extension are untouched.
Closes#1107
Co-authored-by: sxh313 <250161920+sxh313@users.noreply.github.com>
Co-authored-by: jubaoliang <jubaoliang@tencent.com>
GET /api/agents/{agent_id}/threads forwarded an unvalidated `limit` into
`LIMIT ?`. SQLite reads a negative LIMIT as "no limit", so ?limit=-1 returned the
caller's whole thread collection and ?limit=0 returned an empty page; the same
statement reaches psycopg unchanged, where a negative LIMIT is an error. Bound it
with Query(ge=1, le=HISTORY_MAX_LIMIT), the ceiling this module already uses for
message pages.
Co-authored-by: sxh <sunxianhong@ncti-gba.cn>
Co-authored-by: sxh313 <sxh313@users.noreply.github.com>
Co-authored-by: jubaoliang <jubaoliang@tencent.com>
wiki_summary interpolates its `lang` argument straight into the URL host
(`https://{lang}.wikipedia.org/...`), and the tool schema the harness
builds from the signature gives the model an unconstrained `str`. A value
like "evil.com#" makes httpx resolve host=evil.com, and "localhost:8443/"
reaches a loopback port -- the response's `extract` is then echoed back
into the chat, so it is also a read-back channel.
Validate `lang` as a bare subdomain label and return the usual error card
otherwise; real codes (zh, en, zh-classical, simple, nb) are unaffected.
Managing skills and subagents already covers install and copy, so the extra add actions only duplicated that entry.
Co-authored-by: Cursor <cursoragent@cursor.com>
Digits-only sed left VER as the whole pyproject line for 1.0.2b1, so
native upload and GHCR wait both failed and no .fpk was attached.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(acp): block outbound runners under directory sandbox
Host-spawned acp_runner would bypass a scoped root_dir jail; gate the
per-agent tool in API/runtime and gray the ACP UI while inbound octop acp stays available.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(acp): allow workspace-scoped local roots for outbound runners
Windows rewrites host `/` to the agent workspace; treating that as a
directory sandbox made ACP enable/round-trip fail on win32 CI.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Team rooms used a hardcoded "#管理团队" / "#Manage team" string instead of
the agent name already passed into WelcomeScreen.
Co-authored-by: Cursor <cursoragent@cursor.com>