opengeni-client
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOpenGeni Client
OpenGeni Client
Use this skill when a customer's product and OpenGeni remain separate systems.
That is the normal integration shape: the product owns its users and business
UI, while a standalone OpenGeni deployment owns agent sessions and execution.
For first-time organization and workspace provisioning, start with
OpenGeni developer setup, then return here to write
the embedding code. That skills-only workflow uses the coding agent's own
browser and public REST/SDK, with a scoped Developer setup key; no OpenGeni MCP
server is required.
Do not confuse two meanings of "skill": this file teaches a customer's coding
agent how to integrate OpenGeni; session are runtime capabilities or
instructions attached to an OpenGeni agent. The former designs the integration.
The latter is product data sent through the installed SDK contract.
skillsCode and the live service are authoritative. Prefer ,
, the installed package types, and live probes over memorized
route, model, tool, or backend lists. When source is available, verify exact
behavior in , , contracts, and API routes.
Read when the repository is available; it is the
canonical product boundary for organization keys, workspace mapping, and Skill
ownership.
/v1/config/client/v1/access/mepackages/sdkpackages/reactdocs/product-integration.mdWithout repository access, start at https://docs.opengeni.ai/llms.txt and fetch
the relevant Markdown pages. Before replacing an AI provider, answering a cost
question, or reporting a setup blocker, read
Compatibility and troubleshooting.
当客户的产品与 OpenGeni 保持为独立系统时,使用此 skill。这才是常规的集成形态:产品负责自身用户和业务 UI,而独立的 OpenGeni deployment 负责 agent session 和执行。
首次配置 organization 和 workspace 时,先阅读 OpenGeni developer setup,然后返回本文编写嵌入代码。该仅限 Skills 的工作流使用编程 Agent 自身的浏览器以及公共 REST/SDK,并配以权限受限的 Developer setup key;无需 OpenGeni MCP server。
不要混淆 "skill" 的两种含义:本文教授客户的编程 Agent 如何集成 OpenGeni;session 的 则是附加到某个 OpenGeni Agent 的运行时能力或指令。前者用于设计集成,后者是通过已安装 SDK 契约发送的产品数据。
skills代码和线上服务才是权威依据。相较于凭记忆列出 route、model、tool 或 backend,应优先使用 、、已安装 package 类型及实时探测。若可访问源码,应在 、、contracts 和 API routes 中核实确切行为。仓库可用时,务必阅读 ;它是界定 organization key、workspace 映射和 Skill 归属的权威产品边界。
/v1/config/client/v1/access/mepackages/sdkpackages/reactdocs/product-integration.md无法访问仓库时,先访问 https://docs.opengeni.ai/llms.txt 并获取相关 Markdown 页面。在替换 AI provider、回答成本问题或报告 setup blocker 之前,务必阅读 Compatibility and troubleshooting。
Work Adaptively
灵活应变
This same guide is bundled as in ordinary OpenGeni
sessions and lives in for external coding agents.
No Pack, installation, repository clone, or sandbox is needed to read the bundled
copy. It is guidance, not authority to access a repository, secret, or deployment.
Embedded products may narrow bundled guidance with .
builtin:opengeni-client.agents/skills/opengeni-clientbundledSkillIds- Inspect before you build. In the customer's repository: authentication,
tenancy, data routes, frontend conventions, installed packages, tests, CI,
deployment guidance, and any OpenGeni code already there. In OpenGeni:
(is
getClientConfig()? which capabilities are offered?), the workspace'sagentConfig.enabled, and an existing session'ssettings.sessionAgentDefaultsandagent. Only then ask questions or choose an integration shape.effectiveTools - If the target repository or resources are missing, first inspect available authorized resources and connection/setup tools. Help the user connect or attach the specific missing source; explain the next action in product terms. Continue useful discovery without requesting broad credentials or pretending missing access is configured. Read Discovery and autonomy for that workflow.
- Two choices belong to the user: who can see a chat (only the person who
started it, or their team) and whether the agent may change data. If the
request or repository does not settle one, ask ONE short, plain-language
question with a recommended answer, before building. Never ask what the
repository answers. How chats map to OpenGeni workspaces (including
) is your implementation decision: never offer it as an option or mention OpenGeni workspaces in a question.
chats: "isolated" - Decide local-development mechanics yourself (ports, local HTTPS, cookie
flags, seed data, test logins). When you test against a local app, OpenGeni
must reach its tool endpoint over public HTTPS, so open a temporary tunnel
(for example ) and tell the user you did; don't ask.
cloudflared - Do not ask about background work, schedules, session length or credential lifetime up front. Long agent sessions just work. Only when the requested feature itself is scheduled or runs in the background (for example "email me a weekly report"), ask for the missing details (day, time, time zone, where results appear) and say in one sentence why you need them. See Discovery and autonomy.
- Use a reversible, clearly stated default only for choices outside those four, or when the user explicitly said not to ask. A busy user is not that signal.
- Match the requested delivery autonomy. Repository or cloud access is technical capability, not permission to push, deploy, merge, or change production.
- This Skill guides an implementation agent. Never copy it into the runtime Skills of the customer-facing agent.
本指南既会作为 打包进普通 OpenGeni session,也会位于外部编程 Agent 的 。读取内置副本无需 Pack、安装、克隆仓库或使用 sandbox。它只是指导,并不授予访问仓库、secret 或 deployment 的权限。嵌入式产品可通过 收窄内置指导范围。
builtin:opengeni-client.agents/skills/opengeni-clientbundledSkillIds- 构建前先检查。在客户仓库中检查:认证、租户、数据路由、前端约定、已安装 package、测试、CI、部署指南以及已有的 OpenGeni 代码。在 OpenGeni 中检查:(是否启用了
getClientConfig()?提供了哪些 capabilities?)、workspace 的agentConfig.enabled,以及现有 session 的settings.sessionAgentDefaults和agent。完成这些检查后,再提出问题或选择集成形态。effectiveTools - 如果目标仓库或资源缺失,先检查可用的授权资源和连接或配置工具。帮助用户连接或附加具体缺失来源;以产品术语说明下一步操作。在不索要宽泛凭据、也不假装缺失访问已配置的情况下,继续开展有价值的发现。阅读 Discovery and autonomy 以了解该工作流。
- 有两个选择属于用户:谁能看到某个 chat(仅发起者,还是其团队),以及 Agent 是否可以更改数据。如果请求或仓库无法确定,应在构建前提出一个简短、平实的问题,并给出推荐答案。绝不要询问仓库本身已能回答的问题。如何将 chat 映射到 OpenGeni workspace,包括 ,属于实现决策:绝不能把它作为选项提出,也不要在问题中提及 OpenGeni workspace。
chats: "isolated" - 自行决定本地开发机制,包括端口、本地 HTTPS、cookie 标志、种子数据和测试登录。针对本地应用进行测试时,OpenGeni 必须通过公共 HTTPS 访问其工具端点,因此应开启临时隧道(例如 )并告知用户;不要询问。
cloudflared - 不要预先询问后台任务、计划、会话时长或凭据有效期。长时间 agent session 可以直接运行。只有当所请求的功能本身需要计划执行或在后台运行时,例如“每周给我发送一份报告”,才询问缺失信息,包括日期、时间、时区和结果显示位置,并用一句话说明为何需要这些信息。参阅 Discovery and autonomy。
- 仅对上述四项之外的选择,或用户明确表示无需询问时,才采用可逆且明确说明的默认值。单纯说用户很忙并不构成这一信号。
- 匹配请求所要求的交付自主权。拥有仓库或云访问权限是技术能力,并不等于获准 push、deploy、merge 或更改 production。
- 此 Skill 用于指导 implementation agent。绝不能将其复制到面向客户的 Agent 的运行时 Skills 中。
Default: the full conversation behind a packaged proxy
默认方案:通过打包代理提供完整对话
Default to OpenGeni's complete conversation experience: ,
(the user's chat list plus ) from
, and . For custom-branded
embeds, theme with scoped tokens. For stock UI, use the shipped components
and stylesheet without cosmetic host CSS or token overrides; see
Stock and host-branded appearance.
Import from , not the package root: the root also
exports the workbench, whose editors, terminal and desktop viewer are optional
peer dependencies your bundler would try to resolve. The UI is backed by the
normal session SDK through , a tenant/user-scoped
same-origin proxy on the product server with Next.js, Express, and Hono
adapters (other backends: see
Proxy from any backend). It already
provides streaming, replay, queue, steer, approvals,
human input, attachments, and pause/resume. Deviate only when the product needs
a materially different interaction model, a non-React frontend, or compute
surfaces, and record why.
OpenGeniProviderOpenGeniChatSessionConversation@opengeni/react/session-ui@opengeni/react/compiled.css--og-*session-uicreateSessionProxyHandlerts
// Server only: the organization API key never reaches the browser.
import { OpenGeniClient } from "@opengeni/sdk";
import { createSessionProxyRoute } from "@opengeni/sdk/next";
const og = new OpenGeniClient({
baseUrl: process.env.OPENGENI_API_BASE_URL!, // the deployment you target
apiKey: process.env.OPENGENI_API_KEY!, // organization API key
});
const source = "acme-app"; // stable external-identity namespace
// 1. Onboarding, once per tenant and admitted user (persist workspace.id and operationId).
const { workspace } = await og.ensureWorkspace({
accountId: process.env.OPENGENI_ORGANIZATION_ID!, externalSource: source,
externalId: tenant.id, name: tenant.name,
});
await og.addExternalWorkspaceMember(workspace.id, {
identity: { externalId: user.id, source },
permissions: ["workspace:read", "sessions:create", "sessions:read", "sessions:control",
"files:upload", "files:read", "mcp_servers:attach"], // attach: per-session mcpServers
operationId,
});
// 2. The proxy, as a Next.js App Router catch-all: app/api/opengeni/[...path]/route.ts.
// Express: toNodeMiddleware(createSessionProxyHandler(og, options)) from
// "@opengeni/sdk/express"; Hono: toHonoHandler(...) from "@opengeni/sdk/hono".
const acme = (token: string) => ({ id: "acme", headers: { Authorization: `Bearer ${token}` } });
export const dynamic = "force-dynamic";
export const { GET, POST, PUT, PATCH, DELETE } = createSessionProxyRoute(og, {
chats: "private", // the default: each user's chats are theirs; "shared" | "isolated"
resolve: async (request) => {
const me = await authenticate(request); // the product's own session check
return me
? { workspaceId: me.openGeniWorkspaceId, user: me.id, source }
: new Response("Unauthorized", { status: 401 });
},
authorizeMutation: verifyCsrf, // the product's existing CSRF policy
// New chats: the browser sends only the first message; the server picks the rest.
createSession: async ({ initialMessage, idempotencyKey }, { user }) => ({
initialMessage,
idempotencyKey,
agent: {
identity: "You are Acme's support assistant. Friendly and brief.",
capabilities: "none", // Acme's tools, asking questions, reading Skills; nothing else
},
skills: productSkills, // product-owned, inline
mcpServers: [{ ...acme(await mintUserToken(user)), url: ACME_MCP_URL, allowedTools }],
tools: [{ kind: "mcp", id: "acme" }], // a per-session server must also be selected here
sandboxBackend: "none", // pure chat/tool agent: no sandbox to start or shell around tools
}),
// Every forwarded message: fresh per-user token and server-owned page context.
beforeForwardMessage: async (_message, { user }) => ({
mcpCredentialUpdates: [acme(await mintUserToken(user))],
modelContext: `Today ${new Date().toISOString().slice(0, 10)}, time zone ${tz}`,
}),
});tsx
// Browser: the unmodified SDK client, pointed at the mount.
import { OpenGeniClient } from "@opengeni/sdk";
import { OpenGeniChat, OpenGeniProvider } from "@opengeni/react/session-ui";
import "@opengeni/react/compiled.css";
const client = new OpenGeniClient({ baseUrl: "/api/opengeni" });
<OpenGeniProvider client={client} workspaceId={workspaceId}>
<OpenGeniChat /> {/* the user's chats (sidebar/drawer) + conversation */}
</OpenGeniProvider>;agentagentConfig.enabledfirstPartyMcpTools: []agentFor an assistant bound to one record (a ticket, a dashboard), create the session
server-side as the user (
with a stable ) and render .
The proxy calls per request, acts only through , pins the
workspace, and serves only provider/conversation routes; the chat list shows
only chats the user created ( widens it). Never replace the
proxy with a raw passthrough of arbitrary paths under the organization key.
Reset UI state when the user or tenant changes.
og.asUser(user.id, { source }).createSession(...)idempotencyKey<SessionConversation sessionId>resolveasUsersessionList: "visible"默认采用 OpenGeni 的完整对话体验:、(用户的 chat 列表以及 ),二者来自 ,并使用 。对于自定义品牌的嵌入,使用限定作用域的 token 进行主题化。对于原生 UI,直接使用随附的组件和样式表,不添加外观层面的宿主 CSS 或 token 覆盖;参阅 Stock and host-branded appearance。
OpenGeniProviderOpenGeniChatSessionConversation@opengeni/react/session-ui@opengeni/react/compiled.css--og-*从 导入,不要从 package 根路径导入:根路径还会导出 workbench,其 editors、terminal 和 desktop viewer 是可选 peer dependency,而 bundler 会尝试解析它们。该 UI 通过 连接到普通 session SDK;这是一个运行在产品服务端、按 tenant 和 user 限定范围的同源 proxy,提供 Next.js、Express 和 Hono adapter(其他后端参阅 Proxy from any backend)。它已经支持 streaming、replay、queue、steer、approvals、human input、attachments 以及 pause/resume。只有当产品需要实质上不同的交互模型、非 React 前端或 compute surfaces 时才应偏离默认方案,并记录原因。
session-uicreateSessionProxyHandlerts
// Server only: the organization API key never reaches the browser.
import { OpenGeniClient } from "@opengeni/sdk";
import { createSessionProxyRoute } from "@opengeni/sdk/next";
const og = new OpenGeniClient({
baseUrl: process.env.OPENGENI_API_BASE_URL!, // the deployment you target
apiKey: process.env.OPENGENI_API_KEY!, // organization API key
});
const source = "acme-app"; // stable external-identity namespace
// 1. Onboarding, once per tenant and admitted user (persist workspace.id and operationId).
const { workspace } = await og.ensureWorkspace({
accountId: process.env.OPENGENI_ORGANIZATION_ID!, externalSource: source,
externalId: tenant.id, name: tenant.name,
});
await og.addExternalWorkspaceMember(workspace.id, {
identity: { externalId: user.id, source },
permissions: ["workspace:read", "sessions:create", "sessions:read", "sessions:control",
"files:upload", "files:read", "mcp_servers:attach"], // attach: per-session mcpServers
operationId,
});
// 2. The proxy, as a Next.js App Router catch-all: app/api/opengeni/[...path]/route.ts.
// Express: toNodeMiddleware(createSessionProxyHandler(og, options)) from
// "@opengeni/sdk/express"; Hono: toHonoHandler(...) from "@opengeni/sdk/hono".
const acme = (token: string) => ({ id: "acme", headers: { Authorization: `Bearer ${token}` } });
export const dynamic = "force-dynamic";
export const { GET, POST, PUT, PATCH, DELETE } = createSessionProxyRoute(og, {
chats: "private", // the default: each user's chats are theirs; "shared" | "isolated"
resolve: async (request) => {
const me = await authenticate(request); // the product's own session check
return me
? { workspaceId: me.openGeniWorkspaceId, user: me.id, source }
: new Response("Unauthorized", { status: 401 });
},
authorizeMutation: verifyCsrf, // the product's existing CSRF policy
// New chats: the browser sends only the first message; the server picks the rest.
createSession: async ({ initialMessage, idempotencyKey }, { user }) => ({
initialMessage,
idempotencyKey,
agent: {
identity: "You are Acme's support assistant. Friendly and brief.",
capabilities: "none", // Acme's tools, asking questions, reading Skills; nothing else
},
skills: productSkills, // product-owned, inline
mcpServers: [{ ...acme(await mintUserToken(user)), url: ACME_MCP_URL, allowedTools }],
tools: [{ kind: "mcp", id: "acme" }], // a per-session server must also be selected here
sandboxBackend: "none", // pure chat/tool agent: no sandbox to start or shell around tools
}),
// Every forwarded message: fresh per-user token and server-owned page context.
beforeForwardMessage: async (_message, { user }) => ({
mcpCredentialUpdates: [acme(await mintUserToken(user))],
modelContext: `Today ${new Date().toISOString().slice(0, 10)}, time zone ${tz}`,
}),
});tsx
// Browser: the unmodified SDK client, pointed at the mount.
import { OpenGeniClient } from "@opengeni/sdk";
import { OpenGeniChat, OpenGeniProvider } from "@opengeni/react/session-ui";
import "@opengeni/react/compiled.css";
const client = new OpenGeniClient({ baseUrl: "/api/opengeni" });
<OpenGeniProvider client={client} workspaceId={workspaceId}>
<OpenGeniChat /> {/* the user's chats (sidebar/drawer) + conversation */}
</OpenGeniProvider>;agentagentConfig.enabledfirstPartyMcpTools: []对于绑定到单条记录(例如 ticket 或 dashboard)的 Assistant,应在服务端以用户身份创建 session,使用 并提供稳定的 ,然后渲染 。Proxy 会在每次请求时调用 ,只通过 执行操作,固定 workspace,并且只提供 provider 和 conversation routes;chat 列表仅显示用户创建的 chats,使用 可扩大范围。绝不能用 organization key 下任意路径的原始直通来替换 proxy。用户或 tenant 发生变化时,重置 UI 状态。
og.asUser(user.id, { source }).createSession(...)idempotencyKey<SessionConversation sessionId>resolveasUsersessionList: "visible"Migrating from embedded OpenGeni
从嵌入式 OpenGeni 迁移
When moving old in-process sessions to a standalone deployment, read
Archived session history import.
Use server-only functions from , with the
existing tenant mappings and verified creator/owner. Preserve timestamps
and visibility, re-upload files and replace references before import, and retain
exact import/batch requests for idempotent retries. This is a read-only event
archive, never model-facing history or resumable execution. Keep
behind the existing proxy; imported archives never offer
Send or Steer, and continuation is unsupported in v1. Do not add import routes
to the browser proxy or attach this implementation Skill to end-user agents.
@opengeni/sdk/session-history-importasUserSessionConversation将旧的进程内 sessions 迁移到独立 deployment 时,阅读 Archived session history import。使用从 导入的仅限服务端函数,并沿用现有的 tenant mappings 以及经过验证的 creator/owner。保留时间戳和可见性,在导入前重新上传文件并替换引用,同时保留完全相同的 import/batch requests,以便进行幂等重试。这是一种只读 event archive,绝不能作为面向模型的历史记录或可恢复的执行环境。保持 位于现有 proxy 之后;导入的 archives 永远不提供 Send 或 Steer,且 v1 不支持继续执行。不要向浏览器 proxy 添加 import routes,也不要将此 implementation Skill 附加到面向最终用户的 Agent。
@opengeni/sdk/session-history-importasUserSessionConversationDeliberate deviations
有意采用的偏离方案
Choose one only for its stated reason; read
Product shapes and UI first.
- Headless React hooks (): the product needs a materially different interaction model but still wants canonical event, queue, composer, approval, and human-input behavior.
@opengeni/react/session - SDK only: a non-React frontend (Svelte, Vue, native mobile), a CLI, or
backend automation. Keep the SDK on a product backend route. For a runnable
native Vue host, start with the
Vue conversation recipe.
Run its consumer commands from .
examples/vue-conversation/app - A non-JavaScript backend (Django, Rails, Go, PHP, Java): keep the React conversation and implement the proxy's small HTTP contract in that backend instead of adding a Node sidecar. See Proxy from any backend.
- Workbench: the product genuinely exposes agent compute (changes, files, terminal, desktop). It has optional heavy peers.
- Chat facade fallback (): the product already has a chat UI speaking Vercel
@opengeni/sdk/chator an OpenAI-shaped protocol, or a server-side bot needsuseChat. It is a text-only projection: tool outputs are dropped, with no files, artifacts, images, goals, queue, or steer UI, and reopening restores only text. See Chat facade fallback.og.chat(...).send() - In-process embedding of the OpenGeni runtime is infrastructure work; see
the repo-maintainer skill and
opengeni.docs/embedding.md
Verify delivery with representative product questions, checking useful answers
and actual tool execution, not just connectivity: see
Integration configuration and verification.
Read selectively: Product integration shapes,
API workflows,
Isolation and authorization,
Data tools and credentials, and
External users and embedded connection setup.
仅基于明确理由选择其中一种;先阅读 Product shapes and UI。
- Headless React hooks():产品需要实质上不同的交互模型,但仍希望使用标准的事件、队列、输入框、审批和人工输入行为。
@opengeni/react/session - 仅使用 SDK:使用非 React 前端,例如 Svelte、Vue 或原生移动端,或者用于 CLI 和后端自动化。将 SDK 放在产品后端 route 上。对于可运行的原生 Vue host,请从 Vue conversation recipe 开始。从 运行其 consumer commands。
examples/vue-conversation/app - 非 JavaScript 后端,例如 Django、Rails、Go、PHP 或 Java:保留 React conversation,并在该后端中实现 proxy 的小型 HTTP contract,而不是增加 Node sidecar。参阅 Proxy from any backend。
- Workbench:产品确实需要公开 Agent compute,包括更改、文件、terminal 和 desktop。它包含可选的重型 peer dependencies。
- Chat facade fallback():产品已有使用 Vercel
@opengeni/sdk/chat或 OpenAI 风格协议的 chat UI,或者服务端 bot 需要使用useChat。它仅是纯文本投影:会丢弃 tool outputs,不支持 files、artifacts、images、goals、queue 或 steer UI,重新打开时也只恢复文本。参阅 Chat facade fallback。og.chat(...).send() - OpenGeni runtime 的进程内嵌入属于基础设施工作;参阅 repo maintainer 的 skill 和
opengeni。docs/embedding.md
通过有代表性的产品问题验证交付情况,检查有用的答案和实际工具执行情况,而不只是验证连通性:参阅 Integration configuration and verification。选择性阅读:Product integration shapes、API workflows、Isolation and authorization、Data tools and credentials 和 External users and embedded connection setup。
Configure The Agent
配置 Agent
Every surface takes one object: (start from or
, then switch , , , ,
, , , , , ,
, , ), (who the
agent is), and ( for OpenGeni's React
components, for your own UI). Pick capabilities from the product's
intent, not from tool names: a customer-facing assistant usually starts from
plus what it needs; an internal operator agent from minus what
it must not do. Set workspace defaults with , schedules
with , and change a running session with
(from its next turn). Check the result on and
. Read Configure the agent
before choosing; it also covers , the admission switch and error codes.
agentcapabilities"all""none"webSearchhumanInputskillsgoalssubagentsknowledgeschedulesartifactsbrowsermediaworkspaceFilesworkspaceConnectorsworkspaceAdminidentityinstructionsrenderer"opengeni""markdown""none""all"sessionAgentDefaultsagentConfig.agentupdateSessionAgentsession.agentsession.effectiveToolschatsFor per-seat included usage, administrator splits, top-ups, team budgets, or
browser progress meters, read Usage allowances.
Keep organization-budget writes on the backend; the conversation proxy exposes
only own usage. These are post-call ceilings, not prepaid reservations.
每种 surface 都接收一个 对象:(从 或 开始,然后按需切换 、、、、、、、、、、、、)、(Agent 是谁)、 以及 ( 表示使用 OpenGeni 的 React components, 表示使用自己的 UI)。应根据产品意图而不是 tool 名称来选择 capabilities:面向客户的 Assistant 通常从 开始,再添加所需能力;内部 operator Agent 则从 开始,再移除不允许的能力。使用 设置 workspace 默认值,使用 设置 schedules,并通过 更改正在运行的 session,改动从其下一轮开始生效。检查 和 中的结果。选择之前请阅读 Configure the agent;该文档还涵盖 、准入开关和错误码。
agentcapabilities"all""none"webSearchhumanInputskillsgoalssubagentsknowledgeschedulesartifactsbrowsermediaworkspaceFilesworkspaceConnectorsworkspaceAdminidentityinstructionsrenderer"opengeni""markdown""none""all"sessionAgentDefaultsagentConfig.agentupdateSessionAgentsession.agentsession.effectiveToolschats对于按席位计算包含用量、管理员分摊、充值、团队预算或浏览器进度计量,阅读 Usage allowances。organization budget 的写入操作必须保留在后端;conversation proxy 仅公开用户自己的用量。这些限制是调用后的上限,而不是预付预留。
Build Gotchas
构建时的常见问题
- Always pass (
baseUrl); the chat facade otherwise targets productionprocess.env.OPENGENI_API_BASE_URL. The SDK is ESM-only.app.opengeni.ai - A per-session entry is usable only when also selected in
mcpServers, and attaching it needstools: [{ kind: "mcp", id, eager? }]for the acting user. MCP and OpenAPI spec URLs must be public HTTPS the deployment can reach; tunnel local servers (for examplemcp_servers:attach).cloudflared - Install and
@opengeni/sdkfrom the same release. If the repository enforces a release-age policy (for example pnpm@opengeni/react), a just-published version may be refused: pin an older matching pair or ask before adding an exclusion; never bypass it silently.minimumReleaseAge - External member permissions cannot yet be edited in place (a re-grant with a
new conflicts, and the organization key cannot update the member). Grant the final set at onboarding; to change it, revoke (
operationId, which cancels that user's running turns) and re-add with a newcancelExternalWorkspaceMemberGrant.operationId - suits pure chat/tool agents: turns start in seconds instead of minutes, and there is no shell to route around the product's tools.
sandboxBackend: "none" - For the smallest agent and prompt, see Agent recipes.
- Stop in a chat UI is : resumable, and messages sent while paused queue until
pauseSession.resumeSessionis terminal for the session and its children; never wire it to Stop.cancelSession - Background agents: use a scheduled task (, with an explicit schedule and time zone), or an inbound automation webhook for events. Their agents reference a workspace OpenAPI Integration or MCP connection by id in
createScheduledTask(scheduled tasks take no inlinetools) and write results back through the product's own tools. On deployments with workspace integrations (checkmcpServersand the SDK exports), a signed workspace webhook (/v1/config/client, verify withcreateWorkspaceWebhook) tells the product when turns finish or need a person; treat it as an at-least-once, unordered signal and read the session (seeverifyWebhookEvent).docs/workspace-integrations.md - Advanced, not the default path: products that need background work with
host-owned access can add a workspace credential provider (short-lived
sandbox credentials, including Git) and recognize the calling turn from the
informational on MCP calls. See
_meta.opengeni.docs/workspace-integrations.md - Organization integration administration, webhook reads and signing-secret
rotation use functions imported from , with
@opengeni/sdk/workspace-integrationsas the first argument. They are not eager client methods; see Data tools and credentials.client
- 始终传入 (
baseUrl);否则 chat facade 会指向生产环境process.env.OPENGENI_API_BASE_URL。SDK 仅支持 ESM。app.opengeni.ai - 每 session 的 条目只有在
mcpServers中同时被选中后才可使用;附加它还需要 acting user 拥有tools: [{ kind: "mcp", id, eager? }]。MCP 和 OpenAPI spec URL 必须是 deployment 可访问的公共 HTTPS;请为本地 server 建立隧道,例如mcp_servers:attach。cloudflared - 从同一 release 安装 和
@opengeni/sdk。如果仓库要求遵守 release-age policy,例如 pnpm@opengeni/react,刚发布的版本可能会被拒绝:固定到较旧且彼此匹配的版本对,或在添加 exclusion 前先询问;绝不能静默绕过。minimumReleaseAge - 外部成员权限目前无法原地修改。使用新的 重新授权会产生冲突,而且 organization key 无法更新成员。在 onboarding 时授予最终权限集;如需更改,先撤销(
operationId,这会取消该用户正在运行的 turns),再使用新的cancelExternalWorkspaceMemberGrant重新添加。operationId - 适合纯 chat/tool Agent:turn 会在数秒而非数分钟内启动,并且不存在可绕开产品 tools 的 shell。
sandboxBackend: "none" - 如需最小的 Agent 和 prompt,请参阅 Agent recipes。
- Chat UI 中的 Stop 是 :可以恢复,且暂停期间发送的消息会排队,直至
pauseSession。resumeSession是 session 及其子项的终止操作;绝不能将其连接到 Stop。cancelSession - 后台 Agent:使用 scheduled task(,明确指定 schedule 和 time zone),或使用面向事件的入站 automation webhook。它们的 Agent 通过 id 引用 workspace OpenAPI Integration 或 MCP connection,并将其放入
createScheduledTask(scheduled task 不接受内联tools),再通过产品自己的 tools 写回结果。在支持 workspace integrations 的 deployment 上,检查mcpServers和 SDK exports;已签名的 workspace webhook(/v1/config/client,使用createWorkspaceWebhook验证)可在 turn 完成或需要人工处理时通知产品。将其视为至少一次投递且无序的信号,并读取 session;参阅verifyWebhookEvent。docs/workspace-integrations.md - 这是一条高级且非默认路径:需要使用 host-owned access 执行后台工作的产品,可以添加 workspace credential provider,包括短期 sandbox credentials 和 Git,并通过 MCP calls 上 informational 的 识别调用方 turn。参阅
_meta.opengeni。docs/workspace-integrations.md - Organization integration 管理、webhook 读取和 signing-secret 轮换使用从 导入的函数,并以
@opengeni/sdk/workspace-integrations作为第一个参数。它们不是 eager client methods;参阅 Data tools and credentials。client
Choose The Credential
选择凭据
- Use an organization API key when one server-side product integration provisions or manages many organization workspaces in one OpenGeni organization.
- Use a workspace API key when the integration is deliberately constrained to one organization workspace and should not provision others.
- Use a delegated token when the host acts with short-lived, explicit user/workspace authority rather than one standing product credential.
- A deployment access key is a coarse deployment perimeter. Never use it as tenant identity or infer organization/workspace authority from it.
- 当一个服务端产品集成需要在同一个 OpenGeni organization 中配置或管理许多 organization workspaces 时,使用 organization API key。
- 当集成被明确限制在一个 organization workspace,且不应配置其他 workspace 时,使用 workspace API key。
- 当 host 以短期且明确授予的 user/workspace authority 行事,而不是依赖一个长期有效的产品凭据时,使用 delegated token。
- Deployment access key 是粗粒度的 deployment 边界。绝不能将其用作 tenant identity,也绝不能从中推断 organization/workspace authority。
Default Trust Boundary
默认信任边界
- Keep the organization API key and operator credentials on the product server.
- Authenticate the product's user first, resolve their allowed OpenGeni workspace/session server-side, and expose only the routes that product needs.
- Use for the React conversation, or
createSessionProxyHandlerinside a custom same-origin SSE route.proxySessionEventStream - Direct browser access is valid only when the deployment's normal browser auth or an explicitly accepted bearer/CORS design makes it safe. Never ship a privileged shared API key in a browser bundle.
The product owns external identity, tenant-to-workspace mapping, business
entities, navigation, presentation, and product-specific admission. OpenGeni
owns sessions, turns, durable event history, approvals, agent execution,
selected tools/resources, files, realtime session state, and compute lifecycle.
Link records by opaque IDs; do not copy one system's whole data model into the
other.
- 将 organization API key 和 operator credentials 保留在产品服务端。
- 首先认证产品用户,在服务端解析其获准访问的 OpenGeni workspace/session,并且只暴露产品需要的 routes。
- React conversation 使用 ,或在自定义同源 SSE route 内使用
createSessionProxyHandler。proxySessionEventStream - 只有当 deployment 的常规 browser auth,或明确接受且安全的 bearer/CORS 设计能够保障安全时,才允许浏览器直接访问。绝不能把特权 shared API key 放入 browser bundle。
产品负责 external identity、tenant-to-workspace mapping、business entities、navigation、presentation 和 product-specific admission。OpenGeni 负责 sessions、turns、durable event history、approvals、agent execution、所选 tools/resources、files、realtime session state 和 compute lifecycle。通过 opaque IDs 关联记录;不要将一个系统的完整数据 model 复制到另一个系统。
Organization And Workspace Bootstrap
Organization 和 Workspace Bootstrap
Use one organization API key for the external backend (,
, ); the token is shown once,
so store it in the product's secret manager.
createOrganizationApiKeylistOrganizationApiKeysdeleteOrganizationApiKeyA full-access organization API key is all the integration needs. It creates
workspaces (, ), adds external members, and
creates and controls sessions as those users (). Do not judge it by
's (, ,
) or its empty : those list account-level
grants, not what the key may do inside shared workspaces. Check
and
instead; older deployments omit , so if it is missing, try the call
( is idempotent) rather than concluding the key is too weak.
Only an key is limited, to reading.
ensureWorkspaceworkspaceIdForasUser/v1/access/meaccountGrantsaccount:readworkspace:createapi_keys:manageworkspaceGrantscredential.access === "full"credential.effectiveWorkspacePermissionscredentialensureWorkspaceaccess: "read"For each chosen product sharing boundary, call /
with a stable external mapping identity and persist
the returned ; distinguishes the first
insert from an idempotent replay. Call it an organization workspace in
customer guidance; its exact wire kind is . Personal workspaces are
excluded and must never be selected through a default-workspace fallback.
ensureWorkspacePUT /v1/workspaces/externalresult.workspace.idresult.created"shared"Choose the workspace from who shares documents, workspace instructions,
Connections, and integrations: normally one per customer, and a separate one
when groups need different Connections, integrations, or instructions. When
each end user is their own boundary, a workspace per user (the user id as
) called with the organization key alone is a valid, simpler
option; provisions exactly that per tenant user. Otherwise
use for the authenticated product user; the server derives
the canonical user, so never supply an label as authority.
externalIdchats: "isolated"asUser(externalId)endUserChoose chat privacy with on the proxy or facade: (the
default: only the user sees their chats, the agent reaches only its own session,
Knowledge goes to the user's personal Knowledge), (the workspace sees
and shares them), or (private, in a workspace per tenant user).
Private chats need the organization's private-session setting; without it the
SDK throws naming who can enable it. sets
, and , which stay available as explicit
create fields; private sessions do not make workspace Files or Sites private,
and removing tools is not a substitute for private visibility. Unscoped
organization-key-created top-level sessions are workspace-visible. See
.
chats"private""shared""isolated"OpenGeniSetupErrorchatsvisibilityagentAccessmemoryScopereferences/external-users-and-connect.mdThe external backend owns product Skills. Store and version them outside
OpenGeni, then pass the selected definitions inline in
for each product-created session. There is no
organization-wide Skill registry or Skill inheritance in this integration
contract.
CreateSessionRequest.skillsCreateSessionRequest.bundledSkillIds[]New Skill inputs require valid frontmatter, which owns the name and
description. Do not replay old headerless Skills as new session input.
SKILL.md对外部 backend 使用一个 organization API key(、、);token 只显示一次,因此应将其存储在产品的 secret manager 中。
createOrganizationApiKeylistOrganizationApiKeysdeleteOrganizationApiKey一个全访问 organization API key 就足以满足集成需要。 它可以创建 workspaces(、)、添加 external members,以及以这些用户的身份创建和控制 sessions()。不要根据 中的 (、、)或空的 来判断其能力;这些字段列出的是 account-level grants,而不是 key 在 shared workspaces 内可以执行的操作。检查 和 ;较旧的 deployment 不会返回 ,因此如果缺少该字段,应尝试调用( 是幂等的),而不是直接判断 key 权限不足。只有 的 key 被限制为只读。
ensureWorkspaceworkspaceIdForasUser/v1/access/meaccountGrantsaccount:readworkspace:createapi_keys:manageworkspaceGrantscredential.access === "full"credential.effectiveWorkspacePermissionscredentialensureWorkspaceaccess: "read"对于每个选定的产品共享边界,使用稳定的 external mapping identity 调用 或 ,并持久化返回的 ; 可用于区分首次插入和幂等重放。在面向客户的指导中称其为 organization workspace;其准确的 wire kind 是 。Personal workspaces 不在此范围内,绝不能通过 default-workspace fallback 选中。
ensureWorkspacePUT /v1/workspaces/externalresult.workspace.idresult.created"shared"根据谁共享 documents、workspace instructions、Connections 和 integrations 来选择 workspace:通常每个 customer 使用一个;当 groups 需要不同的 Connections、integrations 或 instructions 时,应单独创建一个。当每个 end user 自身就是边界时,可以为每个用户创建一个 workspace,以 user id 作为 ,仅使用 organization key 调用也是有效且更简单的选项; 正是按 tenant user 配置这一方式。否则,使用 表示已认证的产品用户;server 会派生 canonical user,因此绝不能将 标签作为 authority 提供。
externalIdchats: "isolated"asUser(externalId)endUser通过 proxy 或 facade 上的 选择 chat privacy:(默认:只有用户能看到自己的 chats,Agent 只能访问自己的 session,Knowledge 进入用户的个人 Knowledge)、(workspace 可见并共享)或 (私有,每个 tenant user 使用一个 workspace)。Private chats 需要 organization 的 private-session setting;如果未启用,SDK 会抛出 ,并指出应由谁启用。 会设置 、 和 ,这些字段也可作为显式 create fields 提供。Private sessions 不会让 workspace Files 或 Sites 变为私有,移除 tools 也不能替代 private visibility。未限定 scope 的 organization-key 所创建的顶层 sessions 对 workspace 可见。参阅 。
chats"private""shared""isolated"OpenGeniSetupErrorchatsvisibilityagentAccessmemoryScopereferences/external-users-and-connect.md外部 backend 负责产品 Skills。将它们存储并版本化在 OpenGeni 之外,然后为每个产品创建的 session 在 中内联传入所选定义。该 integration contract 不提供 organization-wide Skill registry 或 Skill inheritance。
CreateSessionRequest.skillsCreateSessionRequest.bundledSkillIds[]新的 Skill input 需要有效的 frontmatter,其中定义 name 和 description。不要将旧的、没有 header 的 Skills 作为新的 session input 重放。
SKILL.mdPrompt And Context Contract
Prompt 和 Context 契约
Use each prompt surface for its exact authority and lifetime:
- (or the workspace's
agent.identity): who the agent is. It replaces only OpenGeni's introduction; older workspaces may still carry this insessionAgentDefaults.identity.agentInstructions - Workspace instructions (Knowledge > Instructions in the web app): stable workspace-wide rules.
- Session (the same field as
instructions): durable refinement for one session. Instructions take priority over OpenGeni's default working style, never over its safety rules or how it runs tools.agent.instructions - : ordinary model-visible content attached to one exact user message as a separate history part; standard timeline rendering omits it.
modelContext - and later message text: the visible part of that user message.
initialMessage
modelContext针对每种 prompt surface 的确切 authority 和 lifetime 使用它:
- (或 workspace 的
agent.identity)定义 Agent 是谁。它只替换 OpenGeni 的 introduction;较旧的 workspaces 可能仍将其放在sessionAgentDefaults.identity中。agentInstructions - Workspace instructions(Web app 中的 Knowledge > Instructions)是稳定的 workspace-wide rules。
- Session (与
instructions是同一字段)是单个 session 的持久化 refinement。Instructions 的优先级高于 OpenGeni 的默认 working style,但绝不高于其 safety rules 或 tools 的运行方式。agent.instructions - 是附加到一条确切用户消息上的普通 model-visible 内容,作为独立 history part;标准 timeline rendering 会将其省略。
modelContext - 和后续 message text 是该用户消息中可见的部分。
initialMessage
modelContextClient Workflow
Client Workflow
- Load the server-held organization API key; resolve the authenticated product
tenant, call , and persist the opaque workspace mapping.
ensureWorkspace - Read client config and access context without a Personal-workspace fallback.
- Create sessions with an explicit (capabilities and identity chosen for the product), the product-selected inline Skills, a stable idempotency key (optionally a preallocated ID), canonical resources, and the product's own tools. Omitted
agentinherits the workspace defaults, which are normally everything the workspace offers.agent - Serve the browser through the packaged proxy, or stream/replay through the SDK in a custom route; tolerate unknown additive event types.
- Send visible text separately from ; upload through the SDK helper, which owns begin, signed storage PUT, and completion.
modelContext - Surface approvals, human-input requests, queue state, errors, credit limits, and reconnect state as product state rather than generic chat text.
- Add realtime, Connected Machines, schedules, or the workbench only when the product use case needs them.
- 加载由服务端持有的 organization API key;解析已认证的产品 tenant,调用 ,并持久化 opaque workspace mapping。
ensureWorkspace - 读取 client config 和 access context,不使用 Personal-workspace fallback。
- 创建 session 时明确提供 (根据产品选择 capabilities 和 identity)、产品选择的 inline Skills、稳定的 idempotency key(可选用预先分配的 ID)、canonical resources 以及产品自己的 tools。省略
agent会继承 workspace defaults,而后者通常包含 workspace 提供的一切能力。agent - 通过打包的 proxy 为浏览器提供服务,或在自定义 route 中通过 SDK 进行 streaming/replay;容忍未知的 additive event types。
- 将 visible text 与 分开发送;通过 SDK helper 上传文件,该 helper 负责 begin、signed storage PUT 和 completion。
modelContext - 将 approvals、human-input requests、queue state、errors、credit limits 和 reconnect state 呈现为产品状态,而不是普通 chat 文本。
- 仅在产品用例需要时添加 realtime、Connected Machines、schedules 或 workbench。
Guardrails
Guardrails
- Workspace-scoped routes are canonical; resource IDs never authorize by themselves.
- Organization workspaces have wire ; Personal workspaces are outside the external product mapping.
kind: "shared" - Knowledge settings and prompt instructions never create a tenant boundary; tool removal is defense in depth, not authorization.
- The SDK cannot accept arbitrary customer backend functions as remote tools. Expose an existing API through a reviewed OpenAPI/GraphQL Integration or an MCP server.
- OpenGeni's credential broker encrypts secrets and keeps them out of model context, but the trusted control plane can decrypt them for the authorized provider request. Do not describe it as zero knowledge.
- Do not call Temporal, NATS, Postgres, workers, sandbox providers, object storage APIs, or MCP transports as substitutes for the public SDK/API.
- Do not claim auth, model, tool, billing, CORS, storage, or compute behavior until the live deployment or current source proves it. Credentials come from a secret manager or environment, never from examples or Skills.
- Generate a customer-specific skill only for stable facts their coding agents
repeatedly need. Keep it beside their integration code, point it at the SDK,
include a config/access smoke probe, and never paste secrets into it.
Start from when the OpenGeni skill package is available.
references/customer-skill-template.md
- Workspace-scoped routes 是标准入口;resource IDs 本身绝不能用于授权。
- Organization workspaces 的 wire 为
kind;Personal workspaces 不属于外部产品 mapping。"shared" - Knowledge settings 和 prompt instructions 永远不会创建 tenant boundary;移除 tools 是纵深防御,而不是授权机制。
- SDK 无法将任意客户 backend functions 作为 remote tools 接收。通过经过审查的 OpenAPI/GraphQL Integration 或 MCP server 公开现有 API。
- OpenGeni 的 credential broker 会加密 secrets,并使其不进入 model context,但受信任的 control plane 可以为已授权的 provider request 解密。绝不能将其描述为 zero knowledge。
- 不要直接调用 Temporal、NATS、Postgres、workers、sandbox providers、object storage APIs 或 MCP transports 来替代公共 SDK/API。
- 在 live deployment 或当前源码证明实际行为之前,不要声称 auth、model、tool、billing、CORS、storage 或 compute 行为已经成立。Credentials 只能来自 secret manager 或 environment,绝不能来自 examples 或 Skills。
- 仅当客户编码 Agent 反复需要某些稳定事实时,才生成 customer-specific skill。将其放在客户的集成代码旁边,指向 SDK,包含 config/access smoke probe,并且绝不能将 secrets 粘贴到其中。如果可以使用 OpenGeni skill package,请从 开始。
references/customer-skill-template.md