@opengeni/runtime 3.0.1 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/codemode-client.json +1 -0
- package/dist/chunk-4A4XTKKX.js +1 -0
- package/dist/{chunk-RIJ6DCYS.js → chunk-5HJEVOMJ.js} +9817 -9494
- package/dist/chunk-5HJEVOMJ.js.map +1 -0
- package/dist/{chunk-FHGLYLBL.js → chunk-SPT3PLMX.js} +1 -87
- package/dist/chunk-SPT3PLMX.js.map +1 -0
- package/dist/{chunk-GB763TSV.js → chunk-TE27J65Q.js} +1 -1
- package/dist/chunk-TE27J65Q.js.map +1 -0
- package/dist/{chunk-46BFUGFL.js → chunk-WIHICNWS.js} +1660 -388
- package/dist/chunk-WIHICNWS.js.map +1 -0
- package/dist/{chunk-UU6EJR52.js → chunk-YU4VRTR4.js} +2 -2
- package/dist/chunk-YU4VRTR4.js.map +1 -0
- package/dist/chunk-ZG2YH25H.js +94 -0
- package/dist/chunk-ZG2YH25H.js.map +1 -0
- package/dist/codex-tool-search.d.ts +5 -4
- package/dist/context-compaction.d.ts +19 -0
- package/dist/gmail-rest-mcp.js +1 -1
- package/dist/index.d.ts +30 -22
- package/dist/index.js +25 -5
- package/dist/lazy-manifest-OEYEHNVY.js +45 -0
- package/dist/lazy-manifest-OEYEHNVY.js.map +1 -0
- package/dist/lazy-manifest.d.ts +6 -0
- package/dist/lazy-tool-transport.d.ts +3 -2
- package/dist/{localSources-PVFCAPN2.js → localSources-TWHTEKGO.js} +3 -2
- package/dist/localSources-TWHTEKGO.js.map +1 -0
- package/dist/metrics.d.ts +6 -0
- package/dist/operational-instructions.d.ts +1 -1
- package/dist/prepared-compaction-request.d.ts +8 -0
- package/dist/provider-history-adapter.d.ts +2 -2
- package/dist/runtime-skills.d.ts +3 -10
- package/dist/sandbox/codemode-client.d.ts +17 -0
- package/dist/sandbox/codemode-token.d.ts +3 -3
- package/dist/sandbox/index.d.ts +2 -1
- package/dist/sandbox/index.js +8 -2
- package/dist/sandbox/materialization-verification-error.d.ts +27 -0
- package/dist/sandbox/provider-command-session.d.ts +44 -2
- package/dist/sandbox/providers/modal-command-control.d.ts +32 -29
- package/dist/sandbox/providers/modal-command-router-wire.d.ts +49 -0
- package/dist/sandbox/providers/modal-command-session.d.ts +2 -1
- package/dist/sandbox/providers/modal-legacy-command-control.d.ts +50 -0
- package/dist/sandbox/providers/modal-materialization-verification.d.ts +7 -0
- package/dist/sandbox/providers/modal.d.ts +0 -8
- package/dist/sandbox/routing/routing-session.d.ts +21 -0
- package/dist/sandbox/turn-tool-cancellation.d.ts +1 -0
- package/dist/skill-library.d.ts +0 -6
- package/dist/skill-library.js +1 -1
- package/dist/workspace-tool-gateway.js +7 -5
- package/package.json +9 -7
- package/src/bundled_artifact_skills/opengeni-documents/SKILL.md +19 -0
- package/src/bundled_artifact_skills/opengeni-documents/references/api.md +22 -0
- package/src/bundled_default_skills/opengeni-client/SKILL.md +349 -0
- package/src/bundled_default_skills/opengeni-client/agents/openai.yaml +4 -0
- package/src/bundled_default_skills/opengeni-client/references/api-workflows.md +256 -0
- package/src/bundled_default_skills/opengeni-client/references/compatibility-and-troubleshooting.md +84 -0
- package/src/bundled_default_skills/opengeni-client/references/customer-skill-template.md +96 -0
- package/src/bundled_default_skills/opengeni-client/references/data-tools-and-credentials.md +99 -0
- package/src/bundled_default_skills/opengeni-client/references/discovery-and-autonomy.md +81 -0
- package/src/bundled_default_skills/opengeni-client/references/external-users-and-connect.md +457 -0
- package/src/bundled_default_skills/opengeni-client/references/isolation-and-authorization.md +77 -0
- package/src/bundled_default_skills/opengeni-client/references/product-integration-shapes.md +232 -0
- package/src/bundled_default_skills/opengeni-client/references/product-shapes-and-ui.md +116 -0
- package/src/bundled_default_skills/opengeni-client/references/runtime-profile-and-verification.md +157 -0
- package/src/bundled_default_skills/opengeni-help/SKILL.md +101 -0
- package/src/bundled_management_skills/opengeni-skills/SKILL.md +33 -3
- package/src/codex-tool-search.ts +13 -5
- package/src/context-compaction.ts +87 -4
- package/src/gmail-rest-mcp.ts +1 -2
- package/src/index.ts +363 -131
- package/src/lazy-manifest.ts +55 -0
- package/src/lazy-tool-transport.ts +15 -2
- package/src/metrics.ts +6 -0
- package/src/model-request-capture.ts +3 -0
- package/src/operational-instructions.ts +11 -2
- package/src/prepared-compaction-request.ts +51 -0
- package/src/provider-history-adapter.ts +12 -3
- package/src/runtime-skills.ts +3 -17
- package/src/sandbox/codemode-client.ts +204 -0
- package/src/sandbox/codemode-token.ts +7 -2
- package/src/sandbox/index.ts +7 -0
- package/src/sandbox/materialization-verification-error.ts +65 -0
- package/src/sandbox/provider-command-session.ts +70 -2
- package/src/sandbox/providers/modal-command-control.ts +386 -242
- package/src/sandbox/providers/modal-command-router-wire.ts +248 -0
- package/src/sandbox/providers/modal-command-session.ts +177 -4
- package/src/sandbox/providers/modal-legacy-command-control.ts +351 -0
- package/src/sandbox/providers/modal-materialization-verification.ts +122 -0
- package/src/sandbox/providers/modal.ts +1 -9
- package/src/sandbox/routing/routing-session.ts +417 -79
- package/src/sandbox/turn-tool-cancellation.ts +38 -2
- package/src/skill-catalog.ts +1 -0
- package/src/skill-library.ts +0 -6
- package/src/workspace-governance.ts +0 -1
- package/src/workspace-skills.ts +114 -74
- package/dist/chunk-46BFUGFL.js.map +0 -1
- package/dist/chunk-FHGLYLBL.js.map +0 -1
- package/dist/chunk-GB763TSV.js.map +0 -1
- package/dist/chunk-RIJ6DCYS.js.map +0 -1
- package/dist/chunk-UU6EJR52.js.map +0 -1
- /package/dist/{localSources-PVFCAPN2.js.map → chunk-4A4XTKKX.js.map} +0 -0
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: opengeni-client
|
|
3
|
+
audience: integration-agent
|
|
4
|
+
description: >-
|
|
5
|
+
Integrate OpenGeni capabilities into an external product, website, backend,
|
|
6
|
+
CLI, or automation. Use for discovery, connecting repositories and resources,
|
|
7
|
+
SDK/API and React choices, implementation, verification, and handoff against
|
|
8
|
+
a managed, self-hosted, or local OpenGeni deployment. Not for changing
|
|
9
|
+
OpenGeni internals or mounting its runtime inside the customer's process.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# OpenGeni Client
|
|
13
|
+
|
|
14
|
+
Use this skill when a customer's product and OpenGeni remain separate systems.
|
|
15
|
+
That is the normal integration shape: the product owns its users and business
|
|
16
|
+
UI, while a standalone OpenGeni deployment owns agent sessions and execution.
|
|
17
|
+
|
|
18
|
+
Do not interpret "embed" as "move OpenGeni into the product process." Advanced
|
|
19
|
+
in-process router/core embedding is a separate infrastructure choice. Route that
|
|
20
|
+
work to the repo-maintainer `opengeni` skill and `docs/embedding.md`.
|
|
21
|
+
|
|
22
|
+
Do not confuse two meanings of "skill": this file teaches a customer's coding
|
|
23
|
+
agent how to integrate OpenGeni; session `skills` are runtime capabilities or
|
|
24
|
+
instructions attached to an OpenGeni agent. The former designs the integration.
|
|
25
|
+
The latter is product data sent through the installed SDK contract.
|
|
26
|
+
|
|
27
|
+
Code and the live service are authoritative. Prefer `/v1/config/client`,
|
|
28
|
+
`/v1/access/me`, the installed package types, and live probes over memorized
|
|
29
|
+
route, model, tool, or backend lists. When source is available, verify exact
|
|
30
|
+
behavior in `packages/sdk`, `packages/react`, contracts, and API routes.
|
|
31
|
+
Read `docs/product-integration.md` when the repository is available; it is the
|
|
32
|
+
canonical product boundary for organization keys, workspace mapping, and Skill
|
|
33
|
+
ownership.
|
|
34
|
+
|
|
35
|
+
Without repository access, start at https://docs.opengeni.ai/llms.txt and fetch
|
|
36
|
+
the relevant Markdown pages. Before replacing an AI provider, answering a cost
|
|
37
|
+
question, or reporting a setup blocker, read
|
|
38
|
+
[Compatibility and troubleshooting](references/compatibility-and-troubleshooting.md).
|
|
39
|
+
|
|
40
|
+
## Work Adaptively
|
|
41
|
+
|
|
42
|
+
This same guide is bundled as `builtin:opengeni-client` in ordinary OpenGeni
|
|
43
|
+
sessions and lives in `.agents/skills/opengeni-client` for external coding agents.
|
|
44
|
+
No Pack, installation, repository clone, or sandbox is needed to read the bundled
|
|
45
|
+
copy. It is guidance, not authority to access a repository, secret, or deployment.
|
|
46
|
+
Embedded products may narrow bundled guidance with `bundledSkillIds`.
|
|
47
|
+
|
|
48
|
+
- Inspect the customer's repository, authentication, tenancy, data routes,
|
|
49
|
+
frontend conventions, installed packages, tests, CI, and deployment guidance
|
|
50
|
+
before asking questions or choosing an integration shape.
|
|
51
|
+
- If the target repository or resources are missing, first inspect available
|
|
52
|
+
authorized resources and connection/setup tools. Help the user connect or
|
|
53
|
+
attach the specific missing source; explain the next action in product terms.
|
|
54
|
+
Continue useful discovery without requesting broad credentials or pretending
|
|
55
|
+
missing access is configured. Read
|
|
56
|
+
[Discovery and autonomy](references/discovery-and-autonomy.md) for that workflow.
|
|
57
|
+
- Ask only for consequential product choices or external authority that cannot
|
|
58
|
+
be inferred. Do not ask the customer to restate facts the system proves.
|
|
59
|
+
- Use a reversible, clearly stated default when an unresolved choice is
|
|
60
|
+
low-risk. Resolve privacy, tenant authority, data writes, cost exposure, and
|
|
61
|
+
ambiguous external mutations before crossing those boundaries.
|
|
62
|
+
- Match the requested delivery autonomy. Repository or cloud access is
|
|
63
|
+
technical capability, not permission to push, deploy, merge, or change
|
|
64
|
+
production.
|
|
65
|
+
- This Skill guides an implementation agent. Never copy it into the runtime
|
|
66
|
+
Skills of the customer-facing agent.
|
|
67
|
+
|
|
68
|
+
## Choose the product experience before the transport
|
|
69
|
+
|
|
70
|
+
Read [Product shapes and UI](references/product-shapes-and-ui.md) when adding
|
|
71
|
+
or changing a user-facing surface. Preserve a suitable existing interface;
|
|
72
|
+
for new React chat, evaluate the packaged components and headless hooks before
|
|
73
|
+
writing replacements. The chat facade below serves compatible/custom clients;
|
|
74
|
+
packaged React conversation components use the normal session SDK and authenticated
|
|
75
|
+
proxy routes. Choose the combination that fits the product, not the shortest snippet.
|
|
76
|
+
|
|
77
|
+
Read [Integration configuration and verification](references/runtime-profile-and-verification.md)
|
|
78
|
+
when defining agent behavior or verifying delivery. Use representative product
|
|
79
|
+
questions to check useful answers and actual tool execution, not just connectivity.
|
|
80
|
+
|
|
81
|
+
## Chat facade: `@opengeni/sdk/chat`
|
|
82
|
+
|
|
83
|
+
When using `user`, first provision that user's approved workspace membership
|
|
84
|
+
through the explicit onboarding flow in `references/external-users-and-connect.md`.
|
|
85
|
+
The facade uses `asUser()` and never grants or restores membership on a chat
|
|
86
|
+
request. An existing tenant is not proof that this user belongs to it. For shared
|
|
87
|
+
conversations use the same OpenGeni session ID; identity changes authority, not
|
|
88
|
+
the conversation address. Use `chatBySessionId` to reopen historical sessions
|
|
89
|
+
whose IDs were derived with the old user-namespaced helper.
|
|
90
|
+
|
|
91
|
+
Use this when the chosen frontend speaks one of the supported chat protocols
|
|
92
|
+
and OpenGeni should sit behind it. Install, keep the organization API key on the
|
|
93
|
+
server, and put one handler behind the chat endpoint:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
bun add @opengeni/sdk
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
import { OpenGeni, createChatHandler } from "@opengeni/sdk/chat";
|
|
101
|
+
|
|
102
|
+
const og = new OpenGeni({
|
|
103
|
+
apiKey: process.env.OPENGENI_API_KEY!,
|
|
104
|
+
organizationId: process.env.OPENGENI_ORGANIZATION_ID!,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
export const POST = createChatHandler(og, {
|
|
108
|
+
// Your auth hook. Tenant and user come from the authenticated request, never the body.
|
|
109
|
+
resolve: async (request) => {
|
|
110
|
+
const me = await authenticate(request);
|
|
111
|
+
return me ? { tenant: me.accountId, user: me.userId } : new Response("Unauthorized", { status: 401 });
|
|
112
|
+
},
|
|
113
|
+
// format: "vercel" keeps an existing useChat client; "openai-chat" / "openai-responses"
|
|
114
|
+
// keep an OpenAI-shaped client. The default streams native chunks for custom clients.
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Server-side use without an endpoint:
|
|
118
|
+
const chat = await og.chat({ tenant: "acme", user: "u_42", conversation: "c_9" });
|
|
119
|
+
const reply = await chat.send("hello"); // reply.text; chat.stream(...) yields chunks
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Browser: use a custom or compatible frontend for the backend chat handler.
|
|
123
|
+
For native OpenGeni React UI, install `@opengeni/react` and use
|
|
124
|
+
`SessionConversation` or compose `MessageTimeline` and `ChatComposer` with
|
|
125
|
+
the normal SDK and authenticated session routes. Reset private UI state and cancel old
|
|
126
|
+
requests when the authenticated user or tenant changes. Every customer gets one workspace (`tenant`), every
|
|
127
|
+
conversation one deterministic session, and each session picks its own
|
|
128
|
+
isolation. Conversation IDs are independent of the acting user; ordinary API
|
|
129
|
+
authorization decides who can use the same shared conversation. Without a `user`,
|
|
130
|
+
`resolve` must return the `conversation` itself. The Vercel and OpenAI adapters
|
|
131
|
+
send only the latest user message and import earlier messages once as context
|
|
132
|
+
on the first message; afterwards OpenGeni owns the history.
|
|
133
|
+
|
|
134
|
+
| Scenario | `agentAccess` | `memory` |
|
|
135
|
+
| --- | --- | --- |
|
|
136
|
+
| Support desk: agent confined to its chat tree | `"session"` (default) | `false` (default) |
|
|
137
|
+
| Agents restricted to their canonical user's chats | `"user"` with `asUser()` | `"user"` |
|
|
138
|
+
| A team collaborating across chats | `"workspace"` | `"workspace"` |
|
|
139
|
+
| Any of the above with Knowledge authoring initially Off | any | `false` |
|
|
140
|
+
|
|
141
|
+
`agentAccess` is enforced in the server-side session-authorization seam for
|
|
142
|
+
agents as outbound task scope: own tree, same canonical user, or workspace.
|
|
143
|
+
A narrow target remains reachable by an authorized broad coordinator; target
|
|
144
|
+
private visibility and normal permissions still apply. `asUser()` establishes
|
|
145
|
+
canonical authority, not a second end-user label. Graduate to `og.client`
|
|
146
|
+
(`OpenGeniClient`) on the same `chat.sessionId` when the product needs files,
|
|
147
|
+
tools, approval policies, forks, or realtime voice. The
|
|
148
|
+
`examples/chat-quickstart` directory provides a backend-only server example.
|
|
149
|
+
|
|
150
|
+
## Choose The Integration Shape First
|
|
151
|
+
|
|
152
|
+
Pick the smallest surface that satisfies the product:
|
|
153
|
+
|
|
154
|
+
1. **Stock OpenGeni handoff** — link or deep-link into the OpenGeni web app.
|
|
155
|
+
The product keeps no agent UI.
|
|
156
|
+
2. **Headless product integration** — the product backend uses
|
|
157
|
+
`@opengeni/sdk`; the product renders its own UI and exposes tenant-scoped,
|
|
158
|
+
same-origin routes to its browser or mobile client.
|
|
159
|
+
3. **React session integration** — compose `@opengeni/react/session` hooks and
|
|
160
|
+
pure projections into the product's UI. Add styled subpaths only for the
|
|
161
|
+
surfaces the product wants.
|
|
162
|
+
4. **OpenGeni-rendered React experience** — mount the packaged composer,
|
|
163
|
+
timeline, realtime, or session chrome and import
|
|
164
|
+
`@opengeni/react/compiled.css` once. No Tailwind setup or source scan is
|
|
165
|
+
required. Override `--og-*` tokens only when branding is wanted.
|
|
166
|
+
5. **Workbench integration** — mount the optional Changes/Files/Terminal/Desktop
|
|
167
|
+
workspace when the product genuinely exposes agent compute. It has optional
|
|
168
|
+
heavy peers and is not required for ordinary chat/session integration.
|
|
169
|
+
|
|
170
|
+
Read `references/product-integration-shapes.md` before designing the boundary.
|
|
171
|
+
Read `references/api-workflows.md` for session, upload, retry, repository,
|
|
172
|
+
machine, and schedule patterns.
|
|
173
|
+
|
|
174
|
+
For deeper implementation decisions, read selectively:
|
|
175
|
+
|
|
176
|
+
- [Discovery and autonomy](references/discovery-and-autonomy.md)
|
|
177
|
+
- [Isolation and authorization](references/isolation-and-authorization.md)
|
|
178
|
+
- [Product shapes and UI](references/product-shapes-and-ui.md)
|
|
179
|
+
- [Data tools and credentials](references/data-tools-and-credentials.md)
|
|
180
|
+
- [Integration configuration and verification](references/runtime-profile-and-verification.md)
|
|
181
|
+
- [External users and embedded connection setup](references/external-users-and-connect.md)
|
|
182
|
+
|
|
183
|
+
This tree is the canonical developer guide for product integration. It does not define a runtime
|
|
184
|
+
profile API, schedule Skill fields, or a new registry. Any references to an
|
|
185
|
+
integration's "runtime profile" mean configuration owned by the customer's code,
|
|
186
|
+
not a new OpenGeni resource. Use this Skill for a coding session, not an end-user
|
|
187
|
+
runtime session.
|
|
188
|
+
|
|
189
|
+
## Choose The Credential
|
|
190
|
+
|
|
191
|
+
- Use an **organization API key** when one server-side product integration
|
|
192
|
+
provisions or manages many organization workspaces in one OpenGeni
|
|
193
|
+
organization.
|
|
194
|
+
- Use a **workspace API key** when the integration is deliberately constrained
|
|
195
|
+
to one organization workspace and should not provision others.
|
|
196
|
+
- Use a **delegated token** when the host acts with short-lived, explicit
|
|
197
|
+
user/workspace authority rather than one standing product credential.
|
|
198
|
+
- A **deployment access key** is a coarse deployment perimeter. Never use it as
|
|
199
|
+
tenant identity or infer organization/workspace authority from it.
|
|
200
|
+
|
|
201
|
+
## Default Trust Boundary
|
|
202
|
+
|
|
203
|
+
- Keep the organization API key and operator credentials on the product server.
|
|
204
|
+
- Authenticate the product's user first, resolve their allowed OpenGeni
|
|
205
|
+
workspace/session server-side, and expose only the routes that product needs.
|
|
206
|
+
- Use `@opengeni/sdk` instead of reconstructing event streaming, upload signing,
|
|
207
|
+
retries, or wire types by hand.
|
|
208
|
+
- Use `proxySessionEventStream` for a same-origin browser SSE route. Structural
|
|
209
|
+
React client types let a host implement only the methods its mounted hooks use.
|
|
210
|
+
- Direct browser access is valid only when the deployment's normal browser auth
|
|
211
|
+
or an explicitly accepted bearer/CORS design makes it safe. Never ship a
|
|
212
|
+
privileged shared API key in a browser bundle.
|
|
213
|
+
|
|
214
|
+
The product owns external identity, tenant-to-workspace mapping, business
|
|
215
|
+
entities, navigation, presentation, and product-specific admission. OpenGeni
|
|
216
|
+
owns sessions, turns, durable event history, approvals, agent execution,
|
|
217
|
+
selected tools/resources, files, realtime session state, and compute lifecycle.
|
|
218
|
+
Link records by opaque IDs; do not copy one system's whole data model into the
|
|
219
|
+
other.
|
|
220
|
+
|
|
221
|
+
## Organization And Workspace Bootstrap
|
|
222
|
+
|
|
223
|
+
Use one organization API key for the external backend. Organization key
|
|
224
|
+
administration is exposed through `listOrganizationApiKeys`,
|
|
225
|
+
`createOrganizationApiKey`, and `deleteOrganizationApiKey`, corresponding to
|
|
226
|
+
the organization-scoped `/v1/organizations/:organizationId/api-keys` routes.
|
|
227
|
+
The create response shows the token once; store it only in the product's secret
|
|
228
|
+
manager.
|
|
229
|
+
|
|
230
|
+
For each chosen product sharing boundary, call `ensureWorkspace` /
|
|
231
|
+
`PUT /v1/workspaces/external` with a stable external mapping identity and persist
|
|
232
|
+
the returned `result.workspace.id`; `result.created` distinguishes the first
|
|
233
|
+
insert from an idempotent replay. Call it an **organization workspace** in
|
|
234
|
+
customer guidance; its exact wire kind is `"shared"`. Personal workspaces are
|
|
235
|
+
excluded and must never be selected through a default-workspace fallback.
|
|
236
|
+
|
|
237
|
+
Choose the workspace from who shares documents, workspace instructions,
|
|
238
|
+
Connections, and integrations: normally one workspace per customer. Chat
|
|
239
|
+
human visibility is controlled by `visibility`, not by `agentAccess` or Knowledge.
|
|
240
|
+
Use `asUser(externalId)` for the authenticated product user. The server derives
|
|
241
|
+
the canonical user; never supply an `endUser` label as authority. Separately,
|
|
242
|
+
`agentAccess: "session" | "user" | "workspace"` controls cross-session agent
|
|
243
|
+
reach. Compatibility `memoryScope: "workspace" | "user" | "off"` selects Knowledge
|
|
244
|
+
authoring scope, not transcript visibility. Off initializes authoring to Off;
|
|
245
|
+
existing authorized Knowledge remains retrievable. Personal Knowledge belongs
|
|
246
|
+
to the verified user of the active
|
|
247
|
+
turn, including when different users collaborate in one shared session. Use
|
|
248
|
+
existing task notes for temporary session-tree coordination; there is no active
|
|
249
|
+
session Memory scope. Use a separate workspace when groups need different
|
|
250
|
+
Connections, integrations, or instructions.
|
|
251
|
+
|
|
252
|
+
Unscoped organization-key-created top-level sessions are workspace-visible.
|
|
253
|
+
For product-user ownership, use the server-side `asUser(externalId)` client and
|
|
254
|
+
explicit workspace membership described in `references/external-users-and-connect.md`;
|
|
255
|
+
verified external owners can create private sessions when the organization enables
|
|
256
|
+
that feature. Private sessions do not make workspace Files or Sites private.
|
|
257
|
+
Managed-human Only-me sessions are not a backend impersonation mechanism. A live
|
|
258
|
+
agent with cross-session tools can reach unrelated sessions only when its
|
|
259
|
+
outbound `agentAccess` scope and ordinary resource authorization allow it.
|
|
260
|
+
The target's `agentAccess` never restricts inbound access; private-session
|
|
261
|
+
ownership and ordinary permissions still apply.
|
|
262
|
+
Removing tools is not a substitute for private human visibility.
|
|
263
|
+
|
|
264
|
+
The external backend owns product Skills. Store and version them outside
|
|
265
|
+
OpenGeni, then pass the selected definitions inline in
|
|
266
|
+
`CreateSessionRequest.skills` for each product-created session. There is no
|
|
267
|
+
organization-wide Skill registry or Skill inheritance in this integration
|
|
268
|
+
contract.
|
|
269
|
+
|
|
270
|
+
Use `CreateSessionRequest.bundledSkillIds` to narrow OpenGeni's bundled guidance
|
|
271
|
+
independently: omitted means defaults, `[]` means none, and explicit IDs such as
|
|
272
|
+
`builtin:opengeni-documents` allow only those whose normal inclusion rules hold.
|
|
273
|
+
Children inherit and can only narrow; scheduled-task `agentConfig` and automation
|
|
274
|
+
`sessionTemplate` accept the same field. This does not hide workspace or inline
|
|
275
|
+
Skills, grant tools, or disable eager `skill_read`. Keep the selection stable on
|
|
276
|
+
keyed-create retries. Never try to control it through arbitrary session metadata.
|
|
277
|
+
|
|
278
|
+
New Skill inputs require valid `SKILL.md` frontmatter, which owns the name and
|
|
279
|
+
description. Do not replay old headerless Skills as new session input.
|
|
280
|
+
|
|
281
|
+
## Prompt And Context Contract
|
|
282
|
+
|
|
283
|
+
Use each prompt surface for its exact authority and lifetime:
|
|
284
|
+
|
|
285
|
+
- Workspace `agentInstructions`: stable workspace-wide system persona and behavior.
|
|
286
|
+
- Session `instructions`: durable system-level agent refinement for one session.
|
|
287
|
+
- `modelContext`: ordinary model-visible content attached to one exact user
|
|
288
|
+
message as a separate history part; standard timeline rendering omits it.
|
|
289
|
+
- `initialMessage` and later message text: the visible part of that user message.
|
|
290
|
+
|
|
291
|
+
`modelContext` is not secret, private, or privileged; full event/audit reads may
|
|
292
|
+
return it. Do not hide business facts in a snapshot when the agent should inspect
|
|
293
|
+
them with an authorized product MCP tool. Prefer concise message context plus
|
|
294
|
+
canonical tool access. Changing `modelContext` must not change the persistent
|
|
295
|
+
agent instruction prefix.
|
|
296
|
+
|
|
297
|
+
## Client Workflow
|
|
298
|
+
|
|
299
|
+
1. Resolve the API base URL and load the server-held organization API key.
|
|
300
|
+
2. Resolve the authenticated product tenant, call `ensureWorkspace` with its
|
|
301
|
+
stable external identity, and persist or verify the opaque workspace mapping.
|
|
302
|
+
3. Read client config and access context without falling back to a Personal
|
|
303
|
+
workspace.
|
|
304
|
+
4. Load the exact Skills selected by the external product and pass them inline.
|
|
305
|
+
5. Create a session with a stable idempotency key; optionally preallocate its ID
|
|
306
|
+
when the product must persist a link before the first turn can run.
|
|
307
|
+
6. Attach only canonical resources and an explicit minimal tool selection the
|
|
308
|
+
user may use. Omitting tool selections inherits workspace/deployment
|
|
309
|
+
defaults, including first-party workspace and cross-session capabilities.
|
|
310
|
+
7. Stream/replay session events through the SDK; tolerate unknown additive event
|
|
311
|
+
types.
|
|
312
|
+
8. Send visible text separately from `modelContext`.
|
|
313
|
+
9. Use the SDK upload helper; it owns begin, signed storage PUT, and completion.
|
|
314
|
+
10. Surface approvals, human-input requests, queue state, errors, credit limits,
|
|
315
|
+
and reconnect state as product state rather than generic chat text.
|
|
316
|
+
11. Add realtime, Connected Machines, schedules, or the workbench only when the
|
|
317
|
+
product use case needs them.
|
|
318
|
+
|
|
319
|
+
## Guardrails
|
|
320
|
+
|
|
321
|
+
- Workspace-scoped routes are canonical; resource IDs never authorize by
|
|
322
|
+
themselves.
|
|
323
|
+
- Organization workspaces have wire `kind: "shared"`; Personal workspaces are
|
|
324
|
+
outside the external product mapping.
|
|
325
|
+
- Use one workspace per customer and private/shared visibility for human
|
|
326
|
+
access. Knowledge settings and prompt instructions do not create a tenant boundary.
|
|
327
|
+
`agentAccess` optionally restricts agent reach further; tool removal is
|
|
328
|
+
defense in depth, not a replacement for authorization.
|
|
329
|
+
- Use separate workspaces only when groups must not share documents,
|
|
330
|
+
Connections, integrations, or workspace instructions.
|
|
331
|
+
- Do not invent an organization-wide Skill registry or rely on Skill
|
|
332
|
+
inheritance. The external backend passes selected Skills inline per session.
|
|
333
|
+
- The SDK cannot accept arbitrary customer backend functions as remote tools.
|
|
334
|
+
Expose an existing API through a reviewed OpenAPI/GraphQL Integration or an
|
|
335
|
+
MCP server.
|
|
336
|
+
- OpenGeni's credential broker encrypts secrets and keeps them out of model
|
|
337
|
+
context, but the trusted control plane can decrypt them for the authorized
|
|
338
|
+
provider request. Do not describe it as zero knowledge.
|
|
339
|
+
- Do not call Temporal, NATS, Postgres, workers, sandbox providers, object
|
|
340
|
+
storage APIs, or MCP transports as substitutes for the public SDK/API.
|
|
341
|
+
- Do not claim auth, model, tool, billing, CORS, storage, or compute behavior
|
|
342
|
+
until the live deployment or current source proves it.
|
|
343
|
+
- Keep examples generic and parameterized. Skills may name non-secret origins
|
|
344
|
+
and conventions, but credentials come from a secret manager or environment.
|
|
345
|
+
- Generate a customer-specific skill only for stable facts their coding agents
|
|
346
|
+
repeatedly need. Keep it beside their integration code, point it at the SDK,
|
|
347
|
+
include a config/access smoke probe, and never paste secrets into it.
|
|
348
|
+
Start from `references/customer-skill-template.md` when the OpenGeni skill
|
|
349
|
+
package is available.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "OpenGeni Client"
|
|
3
|
+
short_description: "Developer guide for tenant-safe OpenGeni SDK and UI integration; not runtime instructions."
|
|
4
|
+
default_prompt: "Integrate my product with OpenGeni using the smallest safe surface. Keep standing credentials server-side, choose organization vs workspace key vs delegated token explicitly, map each external tenant to an organization workspace without Personal-workspace fallback, and pass product-owned Skills inline per session."
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# OpenGeni API Workflows
|
|
2
|
+
|
|
3
|
+
This reference is intentionally pattern-level. Check the live service or source
|
|
4
|
+
contracts for exact schemas before generating SDK code. When the repository is
|
|
5
|
+
available, `docs/product-integration.md` is the canonical organization-key,
|
|
6
|
+
workspace-mapping, and Skill-ownership guide.
|
|
7
|
+
|
|
8
|
+
## Access Setup
|
|
9
|
+
|
|
10
|
+
Choose one credential deliberately:
|
|
11
|
+
|
|
12
|
+
- Managed SaaS product integration: create an organization API key through
|
|
13
|
+
`POST /v1/organizations/:organizationId/api-keys` /
|
|
14
|
+
`createOrganizationApiKey`, store the one-time token on the product server,
|
|
15
|
+
and send `Authorization: Bearer <api-key>`.
|
|
16
|
+
- One-workspace automation: use a workspace API key and do not call
|
|
17
|
+
organization provisioning routes.
|
|
18
|
+
- User/workspace delegation: use a short-lived delegated token with explicit
|
|
19
|
+
authority rather than a standing organization key.
|
|
20
|
+
- Configured/self-hosted perimeter: a deployment access key may gate the
|
|
21
|
+
deployment, but it is not tenant identity.
|
|
22
|
+
- Local development: the service may resolve a default dev subject/workspace without external auth.
|
|
23
|
+
|
|
24
|
+
Only add `x-opengeni-access-key` when the operator says the deployment
|
|
25
|
+
shared-key boundary is enabled. It is not a replacement for organization API
|
|
26
|
+
keys in managed SaaS.
|
|
27
|
+
|
|
28
|
+
## Minimal Server-Side Session Client
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { OpenGeniClient } from "@opengeni/sdk";
|
|
32
|
+
|
|
33
|
+
const client = new OpenGeniClient({
|
|
34
|
+
baseUrl: process.env.OPENGENI_API_BASE_URL!,
|
|
35
|
+
apiKey: process.env.OPENGENI_ORGANIZATION_API_KEY!,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const organizationId = process.env.OPENGENI_ORGANIZATION_ID!;
|
|
39
|
+
const { workspace } = await client.ensureWorkspace({
|
|
40
|
+
accountId: organizationId,
|
|
41
|
+
externalSource: "acme-product",
|
|
42
|
+
externalId: productTenant.id,
|
|
43
|
+
name: productTenant.displayName,
|
|
44
|
+
});
|
|
45
|
+
if (workspace.kind !== "shared") {
|
|
46
|
+
throw new Error("Product integrations require an organization workspace");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const skills = await productSkillStore.resolveForSession(productTenant.id);
|
|
50
|
+
const created = await client.createSession(workspace.id, {
|
|
51
|
+
initialMessage: "Inspect the uploaded logs and summarize the failing deploy step.",
|
|
52
|
+
idempotencyKey: crypto.randomUUID(),
|
|
53
|
+
skills,
|
|
54
|
+
firstPartyMcpTools: selectedFirstPartyTools,
|
|
55
|
+
tools: selectedIntegrationServers,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
for await (const event of client.streamEvents(workspace.id, created.id)) {
|
|
59
|
+
if (event.type === "agent.message.delta") {
|
|
60
|
+
process.stdout.write((event.payload as { text?: string }).text ?? "");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
This code belongs on the product server, not in a browser bundle. For a browser
|
|
66
|
+
timeline, expose a tenant-scoped same-origin route and use the SDK's
|
|
67
|
+
`proxySessionEventStream` helper. Authenticate the product user and resolve the
|
|
68
|
+
allowed workspace/session before opening the upstream stream.
|
|
69
|
+
|
|
70
|
+
`ensureWorkspace` maps through `PUT /v1/workspaces/external`. Use a stable
|
|
71
|
+
external source/id pair and persist the returned opaque id. The returned
|
|
72
|
+
organization workspace has wire `kind: "shared"`. Personal workspaces are
|
|
73
|
+
excluded; do not fall back to `/v1/access/me`'s default/personal workspace.
|
|
74
|
+
The method returns `{ workspace, created }`; use `workspace.id`, and treat
|
|
75
|
+
`created: false` as the normal idempotent replay result.
|
|
76
|
+
|
|
77
|
+
The product backend stores and versions Skills outside OpenGeni and passes the
|
|
78
|
+
selected definitions inline in `CreateSessionRequest.skills`. There is no
|
|
79
|
+
organization-wide Skill registry or Skill inheritance in this integration
|
|
80
|
+
contract.
|
|
81
|
+
|
|
82
|
+
The product must choose the workspace mapping from its sharing rule before
|
|
83
|
+
running this flow. A tenant-shared workspace is suitable only when that tenant
|
|
84
|
+
may share workspace-scoped agent authority and resources. Use a per-user
|
|
85
|
+
workspace for cross-user chat privacy and a per-chat workspace for hard
|
|
86
|
+
same-user chat isolation. Knowledge authoring Off does not create either
|
|
87
|
+
boundary.
|
|
88
|
+
|
|
89
|
+
For a headless product, send an explicit minimal `firstPartyMcpTools` and
|
|
90
|
+
`tools` selection. Omission inherits deployment/workspace defaults. Removing
|
|
91
|
+
cross-session tools from a shared workspace is defense in depth, not a hard
|
|
92
|
+
tenant boundary.
|
|
93
|
+
|
|
94
|
+
## Existing APIs As Agent Tools
|
|
95
|
+
|
|
96
|
+
The SDK cannot serialize ordinary customer backend functions into tools. Use
|
|
97
|
+
one of the supported network boundaries:
|
|
98
|
+
|
|
99
|
+
- For an existing HTTP API, host a focused OpenAPI 3.0/3.1 document and call
|
|
100
|
+
`previewApiIntegration`, then `installApiIntegration` with the exact revision,
|
|
101
|
+
digest, Connection, stable instance key, and selected operations.
|
|
102
|
+
- For GraphQL, use the same preview/install lifecycle with the GraphQL source.
|
|
103
|
+
- For MCP, install a workspace capability or pass a session-specific
|
|
104
|
+
`mcpServers` definition with an HTTPS URL, allowed tools, approval policy, and
|
|
105
|
+
write-only headers or a `connectionRef`.
|
|
106
|
+
|
|
107
|
+
Preview/install is deterministic backend work and can be reconciled across many
|
|
108
|
+
workspaces; a model does not need to read and approve the same API description
|
|
109
|
+
for every workspace. Persist the returned Integration instance/server IDs and
|
|
110
|
+
skip unchanged desired versions rather than reinstalling on every chat.
|
|
111
|
+
|
|
112
|
+
Create API-key credentials with `createConnection`. Rotate ordinary credentials
|
|
113
|
+
through `updateConnection` with `expectedVersion`; OAuth providers use their
|
|
114
|
+
dedicated reconnect flow. For session-specific MCP headers, later message
|
|
115
|
+
requests may carry the supported MCP credential update. Responses expose
|
|
116
|
+
metadata and credential versions, never the values.
|
|
117
|
+
|
|
118
|
+
OpenGeni encrypts brokered credentials at rest and keeps them out of model
|
|
119
|
+
context. The trusted control plane can decrypt them to call the exact provider;
|
|
120
|
+
the model and sandbox receive only schemas and bounded results. The provider API
|
|
121
|
+
must still enforce tenant/user scope on every operation and must not trust a
|
|
122
|
+
model-supplied tenant ID.
|
|
123
|
+
|
|
124
|
+
## Runtime Profile And Models
|
|
125
|
+
|
|
126
|
+
Use workspace `agentInstructions` for stable workspace behavior, session
|
|
127
|
+
`instructions` for one role/conversation, Skills for conditional procedures,
|
|
128
|
+
and `modelContext` for current dashboard or route state. Avoid duplicating one
|
|
129
|
+
policy across all four surfaces.
|
|
130
|
+
|
|
131
|
+
Inline Skills are transmitted once in `createSession` and fixed onto that
|
|
132
|
+
session, not sent on each turn. Version the customer-owned runtime profile and
|
|
133
|
+
apply new Skill content to new sessions unless the product deliberately
|
|
134
|
+
migrates old ones.
|
|
135
|
+
|
|
136
|
+
Workspace `sessionDefaults` set the default model and reasoning for new
|
|
137
|
+
sessions. A session or message may override them subject to the workspace model
|
|
138
|
+
access policy. Resolve model IDs from the live client configuration rather than
|
|
139
|
+
hard-coding a remembered list.
|
|
140
|
+
|
|
141
|
+
OpenGeni-credit models in every organization workspace draw from the same
|
|
142
|
+
organization account balance; workspace creation does not create separate
|
|
143
|
+
wallets. Connected subscriptions and workspace-owned provider credentials may
|
|
144
|
+
instead use an externally billed path. Preserve the workspace and product
|
|
145
|
+
boundary in usage attribution when the customer needs a per-user or per-tenant
|
|
146
|
+
view over the shared organization balance.
|
|
147
|
+
|
|
148
|
+
Reconcile stable workspace settings, Connections, Integrations, and runtime
|
|
149
|
+
profile versions during provisioning, startup, deployment, or a controlled
|
|
150
|
+
migration. Do not PATCH the same settings or reinstall the same Integration on
|
|
151
|
+
every chat request when no desired version changed.
|
|
152
|
+
|
|
153
|
+
## Session Creation Options
|
|
154
|
+
|
|
155
|
+
Beyond `initialMessage`/`tools`/`resources`, the create body (`POST /v1/workspaces/:workspaceId/sessions`, the SDK's `createSession(workspaceId, request)`) chooses where the session runs:
|
|
156
|
+
|
|
157
|
+
- `sandboxBackend` — pick the managed sandbox execution backend; omit for the deployment default.
|
|
158
|
+
- `targetSandboxId` (uuid) — run the session on an enrolled **Connected Machine** (a user-owned machine) instead of a managed sandbox. It seeds the session's active-sandbox pointer at creation so the first turn routes to that machine; an invalid/unowned/offline target fails the create.
|
|
159
|
+
- `workingDir` — the host path the machine runs the session under (the base for its agent cwd, terminal, and file dock). **Only valid together with `targetSandboxId`** — sending `workingDir` alone is a 422. Omit it to use the machine's default working directory.
|
|
160
|
+
- `sandbox` — shared-sandbox placement for managed sandboxes, a three-way union: `"shared"` (join the creating session's box; a top-level `"shared"` is a 422), `"new"` (mint a fresh box), or `{ groupId }` (join a specific sibling group in the same workspace). Omitted resolves a context-dependent default server-side.
|
|
161
|
+
- `idempotencyKey` (1–200 chars) — a workspace-scoped CREATE idempotency key (see below).
|
|
162
|
+
|
|
163
|
+
`targetSandboxId`/`workingDir` are the managed-sandbox-vs-Connected-Machine choice; `sandboxBackend` and the `sandbox` placement union only apply to managed sandboxes. To move a session onto a different machine *after* creation, use the active-sandbox swap (below) — not `updateSession`, whose only field is the session `title`.
|
|
164
|
+
|
|
165
|
+
## Replay And Retry
|
|
166
|
+
|
|
167
|
+
- Persist the latest event sequence seen by the client.
|
|
168
|
+
- On reconnect, list events after the last known sequence before reopening the stream.
|
|
169
|
+
- Retry idempotent reads and stream reconnects with bounded backoff.
|
|
170
|
+
- Session creation exposes a workspace-scoped `idempotencyKey` (distinct from the per-call `clientEventId`): forward a stable value so concurrent/retried creates of the same logical session collapse to a single session. Without it every create is independent, so a blind retry can double-create — keep sending a stable key when you retry.
|
|
171
|
+
- Treat unknown event types as extensible timeline entries, not client crashes.
|
|
172
|
+
|
|
173
|
+
## Files
|
|
174
|
+
|
|
175
|
+
The usual flow is:
|
|
176
|
+
|
|
177
|
+
1. `POST /v1/workspaces/:workspaceId/files/uploads`
|
|
178
|
+
2. `PUT` bytes to the returned signed object-storage URL with the required headers.
|
|
179
|
+
3. Complete the upload through the returned workspace upload endpoint.
|
|
180
|
+
4. Attach the file resource to a session, follow-up turn, or scheduled task only after it is ready.
|
|
181
|
+
|
|
182
|
+
Never attach a file id from another workspace. Correct behavior is no data leak: 403 when the credential has no workspace grant, 404 when the resource is not in the granted workspace.
|
|
183
|
+
|
|
184
|
+
## Knowledge And Search
|
|
185
|
+
|
|
186
|
+
Uploaded originals remain Files. Attaching a ready file in a normal chat lets the
|
|
187
|
+
accepted agent turn prepare its searchable source content when Knowledge
|
|
188
|
+
authoring is enabled; users do not need a separate document-base upload flow.
|
|
189
|
+
The attempt-bound `knowledge_retain_file` tool provides explicit preparation.
|
|
190
|
+
Retained sources, findings and collections share the canonical Knowledge entries
|
|
191
|
+
API. Use `listKnowledgeEntries` and `getKnowledgeEntry` for retrieval, or the
|
|
192
|
+
first-party `knowledge_*` tools for agents. A finding cites a specific source
|
|
193
|
+
revision; a collection relates existing entries across sources without copying.
|
|
194
|
+
|
|
195
|
+
Default retrieval returns published content. Explicit `view: "needs_review"`
|
|
196
|
+
returns accessible pending proposals as unapproved context, so an agent can
|
|
197
|
+
improve an existing entry instead of creating duplicates. Agent learning resolves
|
|
198
|
+
workspace/personal defaults plus chat or scheduled-task overrides: Automatic
|
|
199
|
+
publishes, Review first stages without pausing work, and Off disables agent
|
|
200
|
+
authoring while retaining authorized retrieval. Conversation history and
|
|
201
|
+
temporary task notes remain separate. Inspect the installed SDK and live schema
|
|
202
|
+
for exact request shapes rather than using the retired Memory writers.
|
|
203
|
+
|
|
204
|
+
## GitHub Repositories
|
|
205
|
+
|
|
206
|
+
For private repos, use the workspace GitHub repository list before attaching a resource. A valid repository resource normally includes clone URL, ref, mount path, GitHub installation id, and GitHub repository id from OpenGeni's listing response. The worker mints short-lived GitHub App tokens for selected repositories and should not persist clone credentials in session manifests.
|
|
207
|
+
|
|
208
|
+
Do not ask customers to paste GitHub App private keys into their client integration. Managed SaaS uses the OpenGeni-owned app; self-hosted operators configure their own app server-side.
|
|
209
|
+
|
|
210
|
+
## Connected Machines And Enrollment
|
|
211
|
+
|
|
212
|
+
A Connected Machine is a user-owned machine enrolled into a workspace and used as first-class primary compute (no cloud box behind it; it uses its own git auth; repos are not cloned onto it). `selfhosted` is the internal `sandboxBackend` enum value for such a machine.
|
|
213
|
+
|
|
214
|
+
Discover and target machines:
|
|
215
|
+
|
|
216
|
+
- `GET /v1/workspaces/:workspaceId/machines` — list the workspace's machines (each with its derived state, latest metrics, and shared-session count) plus the active-sandbox pointer. Pass `?sessionId=` for an in-session view that also includes the session's own group box. SDK: `listMachines(workspaceId, { sessionId })`.
|
|
217
|
+
- `GET /v1/workspaces/:workspaceId/machines/:enrollmentId/metrics/series?window=15m|1h|6h|24h` — the downsampled (~1/min) metrics history. SDK: `machineMetricsSeries(workspaceId, enrollmentId, { window })`.
|
|
218
|
+
- Create a session with `targetSandboxId` (a machine's `sandboxId` from the list) plus an optional `workingDir` to run on it.
|
|
219
|
+
- `POST /v1/workspaces/:workspaceId/sessions/:sessionId/active-sandbox` with `{ target }` — swap the session's active sandbox mid-conversation; `target` is a machine's `sandboxId`, or `"session"`/`"default"` to return to the session's own group box. The response echoes `swapped`, `activeSandboxId`, `activeEpoch`, and a `reason` when a target is refused. SDK: `swapActiveSandbox(workspaceId, sessionId, { target })`.
|
|
220
|
+
|
|
221
|
+
Enroll a machine (the client-driven parts):
|
|
222
|
+
|
|
223
|
+
- Interactive device flow: the machine's own agent starts and polls the flow agent-side (unauthenticated). A workspace operator resolves the pending request by user code with `POST /v1/enrollments/device/lookup` (no workspace in the path — the server resolves it from the code, then authorizes `enrollments:read`), then `POST /v1/workspaces/:workspaceId/enrollments/device/approve` (the loud consent step; `allowScreenControl` opts into screen control) or `.../device/deny`. SDK: `lookupDeviceEnrollment(userCode)`, `approveDeviceEnrollment(workspaceId, { userCode, allowScreenControl })`, `denyDeviceEnrollment(workspaceId, { userCode })`.
|
|
224
|
+
- Headless / fleet: `POST /v1/workspaces/:workspaceId/enrollments/token` mints a short-TTL SECRET enroll token (surface it once with a copy-now warning); the machine's agent redeems it agent-side at `POST /v1/enrollments/token/exchange`. SDK: `mintEnrollToken(workspaceId, { allowScreenControl })`.
|
|
225
|
+
- `POST /v1/workspaces/:workspaceId/enrollments/:enrollmentId/revoke` removes a machine. Approving, minting, and revoking all require `enrollments:manage`; listing needs `enrollments:read`.
|
|
226
|
+
|
|
227
|
+
Never distribute an OpenGeni credential to a Connected Machine or try to inject git tokens into it — the machine authenticates to git with its own credentials. Device start/poll and token exchange are agent-side calls, not client SDK methods.
|
|
228
|
+
|
|
229
|
+
## Billing And Limits
|
|
230
|
+
|
|
231
|
+
Managed SaaS uses prepaid Stripe credits and local usage/cost accounting. Client behavior should be simple:
|
|
232
|
+
|
|
233
|
+
- Show billing/credit status from `/v1/billing` when the user has billing permission.
|
|
234
|
+
- Stop costly writes/runs when the API returns a credit/limit denial.
|
|
235
|
+
- Preserve read/export paths when writes are blocked.
|
|
236
|
+
- Surface top-up links from OpenGeni; do not call Stripe directly from a customer agent unless OpenGeni explicitly returns a Stripe URL.
|
|
237
|
+
|
|
238
|
+
## Generated Customer Skills
|
|
239
|
+
|
|
240
|
+
When generating a customer-specific agent skill that teaches their coding agents how to call OpenGeni:
|
|
241
|
+
|
|
242
|
+
- Include only their non-secret base URL, organization-workspace mapping
|
|
243
|
+
convention, and safe API examples.
|
|
244
|
+
- Tell the agent to read API keys from the customer's secret manager or environment, never from the skill.
|
|
245
|
+
- State that the backend uses an organization API key, organization workspaces
|
|
246
|
+
have wire `kind: "shared"`, and Personal workspaces are excluded.
|
|
247
|
+
- State where the external product stores Skills and that it passes selected
|
|
248
|
+
definitions inline per session; never invent an organization-wide Skill
|
|
249
|
+
registry or inheritance layer.
|
|
250
|
+
- Keep the skill versioned with their integration code and add a quick smoke command that calls `/v1/config/client` and `/v1/access/me`.
|
|
251
|
+
- State which integration shape the product chose and where its tenant-safe
|
|
252
|
+
proxy/client lives; do not teach every possible shape in every customer skill.
|
|
253
|
+
- Describe only primitives proven by the installed SDK and live deployment; do
|
|
254
|
+
not turn roadmap assumptions into customer instructions.
|
|
255
|
+
- Start from `customer-skill-template.md` in this directory so the generated
|
|
256
|
+
skill records the chosen shape and smoke probes without copying credentials.
|