项目简介
后台运行的编码代理,可自动执行 PR、审核和问题解决等任务。支持多种 AI 模型并与 Slack、GitHub、Linear 集成。专为组织内部的单租户部署设计。
README 预览
# Background Agents: Open-Inspect\n\nAn open-source background agents coding system inspired by\n[Ramp's Inspect](https://builders.ramp.com/post/why-we-built-our-background-agent).\n\n## Overview\n\nOpen-Inspect provides a hosted background coding agent that can:\n\n- Work on tasks in the background while you focus on other things\n- Access full development environments (Node.js, Python, git, browser automation, VS Code)\n- Connect from anywhere — web UI, Slack, GitHub PRs, Linear issues, or webhooks\n- Enable multiplayer sessions where multiple people can collaborate in real time\n- Create PRs with proper commit attribution to the prompting user\n- Run on a schedule — cron jobs, Sentry alerts, and webhook-triggered automations\n- Spawn parallel sub-tasks that work in separate sandboxes simultaneously\n- Use your choice of AI model — Anthropic Claude, OpenAI Codex (via ChatGPT subscription), or\n OpenCode Zen\n\n## Security Model (Single-Tenant Only)\n\n> **Important**: This system is designed for **single-tenant deployment only**, where all users are\n> trusted members of the same organization with access to the same repositories.\n\n### How It Works\n\nThe system uses a shared GitHub App installation for git operations (clone, fetch, push). The\ncontrol plane mints short-lived installation tokens server-side and brokers them to sandboxes\nthrough the git credential helper on demand. This means:\n\n- **All users share the same GitHub App credentials** - The GitHub App must be installed on your\n organization's repositories, and any user of the system can access any repo the App has access to\n- **No per-user repository access validation** - The system does not verify that a user has\n permission to access a specific repository before creating a session\n- **GitHub users' OAuth tokens are used for PR creation** - For GitHub logins, PRs are created using\n the user's GitHub OAuth token, ensuring proper attribution and that they can only create PRs on\n repos the
常见问题 (5)
故障排除如何修复 Claude Opus 4.8/5.5 出现的 HTTP 400 分类器失败:'temperature is deprecated' 或 'tool_choice type tool not supported'?
更新 packages/slack-bot/src/classifier/index.ts 和 packages/linear-bot/src/classifier/index.ts 中的 Slack 和 Linear 分类器请求:
1. 移除 temperature: 0;Claude Opus 4.7+ 会拒绝非默认的 temperature 值。
2. 对于 Opus 5.5,将强制工具选择(例如 tool_choice: { type: "tool", name: "classify_target" })替换为 tool_choice: { type: "auto" }。
3. 在提示词中指示模型必须调用 classify_target 工具。
4. 对于未包含工具调用的响应,保留现有的工具输入验证和目标选择器回退逻辑。
一旦省略 temperature,Opus 4.8 即可正常使用强制工具调用;Opus 5.5 则需要 auto,因为 tool 和 any 这两种 tool-choice 类型均不受支持。作为即时变通方案,设置 classification_model = "claude-haiku-4-5",即不受影响的默认模型。
故障排除为什么从 Slack 或 Linear 创建的 PR 使用的是应用/机器人的 GitHub 身份,而不是我的个人凭据?
这是由 Web 登录迁移到 Better Auth 之后出现的一个凭证查找 bug 导致的。Slack、Linear 和 GitHub 的机器人会话仍然从旧的 user_scm_tokens 表中读取 OAuth 令牌,而新的 GitHub 令牌则存储在 Better Auth 的 user_identities.access_token 表中。由于找不到用户令牌,PR 创建回退到了 GitHub App 安装令牌。该修复通过 Better Auth 的受信任服务器 API 来路由机器人服务主体,使用在路由准入期间确定的规范用户及其关联的 GitHub 账户,验证 GitHub 个人资料,并仅将 user_scm_tokens 保留为迁移前凭证的回退方案。请升级或部署包含 issue #1912 修复的控制平面版本,然后确认受影响的用户在 Better Auth 中拥有已关联的 GitHub 账户。
故障排除为什么在“Load more”页面中,重命名的会话标题会在侧边栏恢复为旧名称?
这是 open-inspect Web UI 中的一个已知 bug,已由 PR #2404 修复(合并到 main,提交为 9eee5a4c02b418fec570581fd85d98e01dbee25e)。根本原因:useSessionRename 为每个会话保留了一个共享的乐观标题。当打开的会话页面头部同步到已确认的重命名后,它会为所有订阅者清除该乐观标题。通过 'Load more' 加载的页面中的侧边栏行仅存在于 React 状态中,从不重新获取数据,因此它们回退到了重命名前的过期标题。修复方法:更新到包含该提交的构建 —— 它在 useSidebarSessions 中添加了一个标题覆盖层(结构与已读覆盖层相同),从重命名结果写入,并在页面卸载或重新获取数据时丢弃。验证命令:npm test -w @open-inspect/web -- src/hooks/use-sidebar-title-reconciliation.test.tsx src/hooks/use-session-rename.test.tsx src/hooks/use-sidebar-sessions.test.tsx --maxWorkers=1(74 个测试应全部通过)。
故障排除在 Fable Modal 沙箱从旧快照恢复后,我该如何找回工作内容?
在 Fable 5.1 中,supervisor.restored_from_snapshot 表示会话恢复了一个较旧的 snapshot_image_id。恢复路径只会运行 git fetch;不会运行 git checkout、reset 或 clean。数据丢失通常由以下原因造成:Modal 的 2 小时硬性超时在快照生成之前终止了容器、打开的浏览器标签页抑制了无活动快照,或者快照失败后静默保留了之前的镜像。
恢复步骤:
1. 获取最后一次会话的差异:GET /sessions/<session_id>/diff,或在 Web UI 中打开 Diff 视图。session_diff 存储包含在一轮结束后捕获的最后一批已跟踪和未跟踪文件,限制为每个文件 512 KiB、总计 1.5 MiB。如果缺失的文件存在,则重新应用该差异。
2. 在 Cloudflare Worker 日志中搜索 sandbox.snapshot_saved 事件,并检查其 image_id 值。如果较新的镜像已保存但后来被替换,请尽可能手动从该镜像启动或恢复。
3. 每个会话仅保留一个 snapshot_image_id;没有快照历史表,且 snapshot_saved WebSocket 事件不会被持久化。
为防止问题再次发生,请在长时间运行的轮次或 2 小时沙箱限制之前提交并推送到 Git,不要假设打开的浏览器标签页会创建无活动快照,并排查 Snapshot failed 日志消息;快照操作在 300 秒后超时。永久修复方案是 "Preserve sandbox state before provider expiry" 变更,它会在硬性到期之前执行与提供商无关的最终保存,缓冲区可配置,最小为 5 分钟,默认为 10 分钟。
故障排除如何阻止 Modal 沙箱在无限循环中反复创建并导致意外费用?
将控制平面升级/部署到包含 issue #1894 修复的版本:它现在会忽略来自已被 connect watchdog 判定失败的沙箱的致命报告,并且熔断器会统计启动失败次数。这可以防止执行缓慢或失败的 .openinspect/setup.sh 在每个启动周期都触发 createSandbox。作为即时变通方案,请设置 Modal 预算上限/告警,使沙箱创建失败时停止该循环,然后优化 setup.sh——将耗时的安装移至预构建镜像中,或缓存依赖项,使启动能在 connect watchdog 超时之前完成。在日志中验证 setup.complete 是否紧随 setup.start 快速出现,并且带有 exit_code: 0。