@openhex-ai/agent-sdk 0.0.1 → 0.1.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/README.md +123 -25
- package/dist/client-1lMkhPMb.d.ts +1066 -0
- package/dist/index.d.ts +5 -1066
- package/dist/react/index.d.ts +277 -0
- package/dist/react/index.js +1529 -0
- package/dist/react/index.js.map +1 -0
- package/dist/tools/index.d.ts +41 -2
- package/dist/{index-DOE19uln.d.ts → tools-DWFaPtFE.d.ts} +1 -38
- package/package.json +28 -3
|
@@ -0,0 +1,1066 @@
|
|
|
1
|
+
import { T as ToolName, S as SdkMcpServer } from './tools-DWFaPtFE.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Permission model for the Openhex Agent SDK.
|
|
5
|
+
*
|
|
6
|
+
* Controls which tools an agent may invoke and how approvals are
|
|
7
|
+
* resolved. Mirrors the Claude Agent SDK permission surface so existing
|
|
8
|
+
* mental models transfer directly.
|
|
9
|
+
*
|
|
10
|
+
* NOTE: scaffold only — types are stable, runtime enforcement is wired
|
|
11
|
+
* up in a follow-up MR.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* How the agent loop treats tool calls that are not pre-approved.
|
|
15
|
+
*
|
|
16
|
+
* - `default` — prompt (via {@link CanUseTool}) for anything not allowlisted.
|
|
17
|
+
* - `acceptEdits` — auto-approve file-editing tools (Write/Edit), prompt for the rest.
|
|
18
|
+
* - `bypassPermissions` — run every tool without prompting. Use only in trusted automation.
|
|
19
|
+
* - `plan` — read-only: the agent may plan but not mutate anything.
|
|
20
|
+
*/
|
|
21
|
+
type PermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan';
|
|
22
|
+
/** The result of a permission decision for a single tool call. */
|
|
23
|
+
type PermissionResult = {
|
|
24
|
+
behavior: 'allow';
|
|
25
|
+
/** Optionally override the arguments the tool is invoked with. */
|
|
26
|
+
updatedInput?: Record<string, unknown>;
|
|
27
|
+
} | {
|
|
28
|
+
behavior: 'deny';
|
|
29
|
+
/** Human-readable reason surfaced back to the agent. */
|
|
30
|
+
message?: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Callback invoked when a tool call needs an approval decision.
|
|
34
|
+
* Return an allow/deny result. When omitted, {@link PermissionMode}
|
|
35
|
+
* governs the outcome.
|
|
36
|
+
*/
|
|
37
|
+
type CanUseTool = (toolName: string, input: Record<string, unknown>, options: {
|
|
38
|
+
signal?: AbortSignal;
|
|
39
|
+
}) => Promise<PermissionResult> | PermissionResult;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Lifecycle hooks for the Openhex Agent SDK.
|
|
43
|
+
*
|
|
44
|
+
* Hooks run custom code at key points in the agent loop to validate,
|
|
45
|
+
* log, block, or transform behavior. Mirrors the Claude Agent SDK hook
|
|
46
|
+
* surface (PreToolUse, PostToolUse, Stop, ...).
|
|
47
|
+
*
|
|
48
|
+
* NOTE: scaffold only — hook dispatch is wired up in a follow-up MR.
|
|
49
|
+
*/
|
|
50
|
+
/** The lifecycle events a hook can subscribe to. */
|
|
51
|
+
type HookEvent = 'PreToolUse' | 'PostToolUse' | 'UserPromptSubmit' | 'Stop' | 'SubagentStop' | 'SessionStart' | 'SessionEnd';
|
|
52
|
+
/** Input payload passed to a hook callback. Shape varies by event. */
|
|
53
|
+
interface HookInput {
|
|
54
|
+
event: HookEvent;
|
|
55
|
+
sessionId: string;
|
|
56
|
+
/** Present for tool-related events. */
|
|
57
|
+
toolName?: string;
|
|
58
|
+
toolInput?: Record<string, unknown>;
|
|
59
|
+
toolResponse?: unknown;
|
|
60
|
+
[key: string]: unknown;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Value a hook may return to influence the loop.
|
|
64
|
+
* An empty object is a no-op. `decision: 'block'` stops the pending
|
|
65
|
+
* action and surfaces `reason` back to the agent.
|
|
66
|
+
*/
|
|
67
|
+
interface HookOutput {
|
|
68
|
+
decision?: 'block';
|
|
69
|
+
reason?: string;
|
|
70
|
+
/** Optionally rewrite the tool input before it executes (PreToolUse). */
|
|
71
|
+
updatedInput?: Record<string, unknown>;
|
|
72
|
+
}
|
|
73
|
+
/** A single hook callback. */
|
|
74
|
+
type HookCallback = (input: HookInput, toolUseId: string | undefined, context: {
|
|
75
|
+
signal?: AbortSignal;
|
|
76
|
+
}) => Promise<HookOutput> | HookOutput;
|
|
77
|
+
/**
|
|
78
|
+
* Binds one or more callbacks to a tool-name matcher (a regex string,
|
|
79
|
+
* e.g. `"Edit|Write"`). Omit `matcher` to match every tool.
|
|
80
|
+
*/
|
|
81
|
+
interface HookMatcher {
|
|
82
|
+
matcher?: string;
|
|
83
|
+
hooks: HookCallback[];
|
|
84
|
+
}
|
|
85
|
+
/** Map of event → matchers. Passed via {@link AgentOptions.hooks}. */
|
|
86
|
+
type HookRegistry = Partial<Record<HookEvent, HookMatcher[]>>;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Subagent definitions.
|
|
90
|
+
*
|
|
91
|
+
* A subagent is a specialized agent the main agent can delegate focused
|
|
92
|
+
* subtasks to (invoked via the built-in `Agent` tool). Mirrors the
|
|
93
|
+
* Claude Agent SDK `AgentDefinition`.
|
|
94
|
+
*
|
|
95
|
+
* NOTE: scaffold only.
|
|
96
|
+
*/
|
|
97
|
+
|
|
98
|
+
interface AgentDefinition {
|
|
99
|
+
/** When the main agent should reach for this subagent. */
|
|
100
|
+
description: string;
|
|
101
|
+
/** System prompt that specializes the subagent. */
|
|
102
|
+
prompt: string;
|
|
103
|
+
/** Tools this subagent may use. Defaults to the parent's allowlist. */
|
|
104
|
+
tools?: ToolName[];
|
|
105
|
+
/** Optional per-subagent model override (e.g. a cheaper/faster model). */
|
|
106
|
+
model?: string;
|
|
107
|
+
}
|
|
108
|
+
/** Map of subagent name → definition. Passed via {@link AgentOptions.agents}. */
|
|
109
|
+
type AgentRegistry = Record<string, AgentDefinition>;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* MCP (Model Context Protocol) server configuration.
|
|
113
|
+
*
|
|
114
|
+
* Connect agents to external systems — databases, browsers, APIs — over
|
|
115
|
+
* MCP. Three transports are supported, mirroring the Claude Agent SDK:
|
|
116
|
+
* - `stdio` : spawn a local process and talk over stdio
|
|
117
|
+
* - `http` : a remote streamable-HTTP MCP server
|
|
118
|
+
* - `sdk` : an in-process server defined with {@link createSdkMcpServer}
|
|
119
|
+
*
|
|
120
|
+
* NOTE: scaffold only — connection management lands in a follow-up MR.
|
|
121
|
+
*/
|
|
122
|
+
|
|
123
|
+
interface StdioMcpServerConfig {
|
|
124
|
+
type?: 'stdio';
|
|
125
|
+
command: string;
|
|
126
|
+
args?: string[];
|
|
127
|
+
env?: Record<string, string>;
|
|
128
|
+
}
|
|
129
|
+
interface HttpMcpServerConfig {
|
|
130
|
+
type: 'http';
|
|
131
|
+
url: string;
|
|
132
|
+
headers?: Record<string, string>;
|
|
133
|
+
}
|
|
134
|
+
/** Any MCP server config accepted by {@link AgentOptions.mcpServers}. */
|
|
135
|
+
type McpServerConfig = StdioMcpServerConfig | HttpMcpServerConfig | SdkMcpServer;
|
|
136
|
+
/** Map of server name → config. */
|
|
137
|
+
type McpServerRegistry = Record<string, McpServerConfig>;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* The options object accepted by {@link query} and {@link OpenhexClient}.
|
|
141
|
+
*
|
|
142
|
+
* Mirrors the Claude Agent SDK `ClaudeAgentOptions` so the surface is
|
|
143
|
+
* familiar, with Openhex-specific connection fields added on top.
|
|
144
|
+
*
|
|
145
|
+
* NOTE: scaffold only — every field is typed; runtime wiring follows.
|
|
146
|
+
*/
|
|
147
|
+
|
|
148
|
+
/** Where filesystem-based config (skills, commands, CLAUDE.md) is loaded from. */
|
|
149
|
+
type SettingSource = 'user' | 'project' | 'local';
|
|
150
|
+
/** Connection details for reaching the Openhex platform. */
|
|
151
|
+
interface OpenhexConnection {
|
|
152
|
+
/**
|
|
153
|
+
* API key for the Openhex platform. Falls back to the
|
|
154
|
+
* `OPENHEX_API_KEY` environment variable when omitted.
|
|
155
|
+
*/
|
|
156
|
+
apiKey?: string;
|
|
157
|
+
/**
|
|
158
|
+
* Base URL of the Openhex API. Defaults to the production endpoint;
|
|
159
|
+
* override for self-hosted or staging.
|
|
160
|
+
*/
|
|
161
|
+
baseUrl?: string;
|
|
162
|
+
/**
|
|
163
|
+
* ID of a published platform agent to run against. When set, the
|
|
164
|
+
* agent's persona, skills, and knowledge base are used as the base.
|
|
165
|
+
*/
|
|
166
|
+
agentId?: string;
|
|
167
|
+
}
|
|
168
|
+
interface AgentOptions extends OpenhexConnection {
|
|
169
|
+
/** Model id to run with (e.g. a platform model alias). */
|
|
170
|
+
model?: string;
|
|
171
|
+
/** System prompt — a string, or a preset reference with an append. */
|
|
172
|
+
systemPrompt?: string | {
|
|
173
|
+
preset: string;
|
|
174
|
+
append?: string;
|
|
175
|
+
};
|
|
176
|
+
/** Tools the agent is allowed to use without prompting. */
|
|
177
|
+
allowedTools?: ToolName[];
|
|
178
|
+
/** Tools the agent may never use, even if otherwise allowed. */
|
|
179
|
+
disallowedTools?: ToolName[];
|
|
180
|
+
/** How unapproved tool calls are handled. @see PermissionMode */
|
|
181
|
+
permissionMode?: PermissionMode;
|
|
182
|
+
/** Programmatic per-call approval callback. */
|
|
183
|
+
canUseTool?: CanUseTool;
|
|
184
|
+
/** Lifecycle hooks. @see HookRegistry */
|
|
185
|
+
hooks?: HookRegistry;
|
|
186
|
+
/** Named subagents the main agent can delegate to. @see AgentRegistry */
|
|
187
|
+
agents?: AgentRegistry;
|
|
188
|
+
/** External + in-process MCP servers. @see McpServerRegistry */
|
|
189
|
+
mcpServers?: McpServerRegistry;
|
|
190
|
+
/** Working directory the agent operates in. Defaults to `process.cwd()`. */
|
|
191
|
+
cwd?: string;
|
|
192
|
+
/** Hard cap on agent loop turns before forcing a result. */
|
|
193
|
+
maxTurns?: number;
|
|
194
|
+
/** Resume a prior run by session id (continues with full context). */
|
|
195
|
+
resume?: string;
|
|
196
|
+
/** Fork from a prior session instead of mutating it. */
|
|
197
|
+
forkSession?: boolean;
|
|
198
|
+
/**
|
|
199
|
+
* Which on-disk config sources to load. Defaults to none (no implicit
|
|
200
|
+
* filesystem reads) — opt in explicitly for skills/commands/memory.
|
|
201
|
+
*/
|
|
202
|
+
settingSources?: SettingSource[];
|
|
203
|
+
/** Stream incremental assistant deltas as `stream_event` messages. */
|
|
204
|
+
includePartialMessages?: boolean;
|
|
205
|
+
/** Abort the run cooperatively. */
|
|
206
|
+
signal?: AbortSignal;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Session types.
|
|
211
|
+
*
|
|
212
|
+
* Sessions carry context across exchanges (files read, prior turns).
|
|
213
|
+
* They can be resumed or forked via {@link AgentOptions.resume} /
|
|
214
|
+
* {@link AgentOptions.forkSession}.
|
|
215
|
+
*
|
|
216
|
+
* NOTE: scaffold only — persistence backend wired up in a follow-up MR.
|
|
217
|
+
*/
|
|
218
|
+
interface SessionInfo {
|
|
219
|
+
sessionId: string;
|
|
220
|
+
/** ISO-8601 creation timestamp. */
|
|
221
|
+
createdAt: string;
|
|
222
|
+
/** ISO-8601 timestamp of the last turn. */
|
|
223
|
+
updatedAt: string;
|
|
224
|
+
/** Number of turns recorded so far. */
|
|
225
|
+
numTurns: number;
|
|
226
|
+
/** The model the session is bound to. */
|
|
227
|
+
model: string;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Message types streamed out of an agent run.
|
|
232
|
+
*
|
|
233
|
+
* The {@link query} async iterator yields a stream of {@link SDKMessage}
|
|
234
|
+
* values. Consumers narrow on the `type` discriminant. Mirrors the
|
|
235
|
+
* Claude Agent SDK message surface.
|
|
236
|
+
*
|
|
237
|
+
* NOTE: scaffold only — shapes are intentionally close to the platform
|
|
238
|
+
* wire format but may gain fields as the runtime is wired up.
|
|
239
|
+
*/
|
|
240
|
+
/** A single block of assistant or user content. */
|
|
241
|
+
type ContentBlock = {
|
|
242
|
+
type: 'text';
|
|
243
|
+
text: string;
|
|
244
|
+
} | {
|
|
245
|
+
type: 'tool_use';
|
|
246
|
+
id: string;
|
|
247
|
+
name: string;
|
|
248
|
+
input: Record<string, unknown>;
|
|
249
|
+
} | {
|
|
250
|
+
type: 'tool_result';
|
|
251
|
+
tool_use_id: string;
|
|
252
|
+
content: unknown;
|
|
253
|
+
is_error?: boolean;
|
|
254
|
+
} | {
|
|
255
|
+
type: 'image';
|
|
256
|
+
source: {
|
|
257
|
+
url: string;
|
|
258
|
+
} | {
|
|
259
|
+
data: string;
|
|
260
|
+
media_type: string;
|
|
261
|
+
};
|
|
262
|
+
};
|
|
263
|
+
/** Roll-up of tokens / cost for a run. */
|
|
264
|
+
interface UsageInfo {
|
|
265
|
+
inputTokens: number;
|
|
266
|
+
outputTokens: number;
|
|
267
|
+
cacheReadTokens?: number;
|
|
268
|
+
cacheCreationTokens?: number;
|
|
269
|
+
/** Total cost in USD, when the platform reports it. */
|
|
270
|
+
totalCostUsd?: number;
|
|
271
|
+
}
|
|
272
|
+
/** Emitted once at the start of a run with the resolved session/config. */
|
|
273
|
+
interface SDKSystemMessage {
|
|
274
|
+
type: 'system';
|
|
275
|
+
subtype: 'init';
|
|
276
|
+
sessionId: string;
|
|
277
|
+
model: string;
|
|
278
|
+
tools: string[];
|
|
279
|
+
permissionMode: string;
|
|
280
|
+
}
|
|
281
|
+
/** A full assistant turn (may contain text and/or tool_use blocks). */
|
|
282
|
+
interface SDKAssistantMessage {
|
|
283
|
+
type: 'assistant';
|
|
284
|
+
sessionId: string;
|
|
285
|
+
/** Set when this message originates inside a subagent's context. */
|
|
286
|
+
parentToolUseId?: string;
|
|
287
|
+
content: ContentBlock[];
|
|
288
|
+
}
|
|
289
|
+
/** A user turn — usually a tool_result fed back into the loop. */
|
|
290
|
+
interface SDKUserMessage {
|
|
291
|
+
type: 'user';
|
|
292
|
+
sessionId: string;
|
|
293
|
+
parentToolUseId?: string;
|
|
294
|
+
content: ContentBlock[];
|
|
295
|
+
}
|
|
296
|
+
/** Incremental streaming delta of an in-flight assistant turn. */
|
|
297
|
+
interface SDKPartialAssistantMessage {
|
|
298
|
+
type: 'stream_event';
|
|
299
|
+
sessionId: string;
|
|
300
|
+
parentToolUseId?: string;
|
|
301
|
+
/** Raw streaming delta (text chunk or tool-input delta). */
|
|
302
|
+
delta: {
|
|
303
|
+
type: 'text_delta';
|
|
304
|
+
text: string;
|
|
305
|
+
} | {
|
|
306
|
+
type: 'input_json_delta';
|
|
307
|
+
partialJson: string;
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
/** Terminal message of a run — success or error, with final result text. */
|
|
311
|
+
interface SDKResultMessage {
|
|
312
|
+
type: 'result';
|
|
313
|
+
subtype: 'success' | 'error_max_turns' | 'error_during_execution';
|
|
314
|
+
sessionId: string;
|
|
315
|
+
/** Final assistant text, present on success. */
|
|
316
|
+
result?: string;
|
|
317
|
+
isError: boolean;
|
|
318
|
+
numTurns: number;
|
|
319
|
+
durationMs: number;
|
|
320
|
+
usage?: UsageInfo;
|
|
321
|
+
}
|
|
322
|
+
/** Discriminated union of everything the agent run can emit. */
|
|
323
|
+
type SDKMessage = SDKSystemMessage | SDKAssistantMessage | SDKUserMessage | SDKPartialAssistantMessage | SDKResultMessage;
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Wire + high-level types for chatting with a platform agent.
|
|
327
|
+
*
|
|
328
|
+
* These mirror the exact protocol the user-side apps use (the platform's
|
|
329
|
+
* `conversationRoutes`: `POST /conversations/send` +
|
|
330
|
+
* `GET /conversations/:id/stream`), so an SDK conversation is
|
|
331
|
+
* indistinguishable from one started in the app.
|
|
332
|
+
*
|
|
333
|
+
* A conversation is a 12-char chat group. Sending without a
|
|
334
|
+
* `conversationId` creates one and routes the message to the agent(s) in
|
|
335
|
+
* `targetAgentIds`; sending with a `conversationId` continues it.
|
|
336
|
+
*/
|
|
337
|
+
|
|
338
|
+
/** Body for `POST /conversations/send`. */
|
|
339
|
+
interface SendRequest {
|
|
340
|
+
/** The message text. (The platform send endpoint is text-only.) */
|
|
341
|
+
message: string;
|
|
342
|
+
/** Continue an existing conversation. Omit to create a new one. */
|
|
343
|
+
conversationId?: string;
|
|
344
|
+
/**
|
|
345
|
+
* Agents for a NEW conversation:
|
|
346
|
+
* - 1 id → route directly to that agent (no coordinator)
|
|
347
|
+
* - 2+ → provision a coordinator + the selected agents
|
|
348
|
+
* - omitted → coordinator handles agent discovery
|
|
349
|
+
*/
|
|
350
|
+
targetAgentIds?: string[];
|
|
351
|
+
/** Display name to label the user in the conversation log. */
|
|
352
|
+
senderName?: string;
|
|
353
|
+
/** Per-message avatar URL stored alongside the message. */
|
|
354
|
+
senderAvatar?: string;
|
|
355
|
+
/** Free-form metadata forwarded to the agent (e.g. card answers). */
|
|
356
|
+
metadata?: Record<string, unknown>;
|
|
357
|
+
/**
|
|
358
|
+
* Tool-action message from a UI card (confirm/cancel). Routed to the
|
|
359
|
+
* agent but not recorded in the event stream.
|
|
360
|
+
*/
|
|
361
|
+
toolAction?: boolean;
|
|
362
|
+
/** Where the conversation was started (set on creation, immutable). */
|
|
363
|
+
source?: string;
|
|
364
|
+
/** Profile id for service-account connectors (new conversations). */
|
|
365
|
+
profileId?: string;
|
|
366
|
+
}
|
|
367
|
+
/** Per-agent dispatch outcome inside a {@link SendResult}. */
|
|
368
|
+
interface AgentDispatchResult {
|
|
369
|
+
agentId: string;
|
|
370
|
+
/** Correlation id of the published command (not a stream cursor). */
|
|
371
|
+
msgId: string;
|
|
372
|
+
/** Command-stream id for the dispatch. */
|
|
373
|
+
streamId: string;
|
|
374
|
+
}
|
|
375
|
+
/** Response from `POST /conversations/send`. */
|
|
376
|
+
interface SendResult {
|
|
377
|
+
/** The conversation id (created if the request omitted one). */
|
|
378
|
+
conversationId: string;
|
|
379
|
+
/** Echo of the user message text. */
|
|
380
|
+
userMessage?: string;
|
|
381
|
+
/**
|
|
382
|
+
* Event-stream id of the recorded user message. This is the cursor to
|
|
383
|
+
* resume `stream()` from to capture exactly the agent's reply to it.
|
|
384
|
+
*/
|
|
385
|
+
userEventId?: string;
|
|
386
|
+
/** One entry per agent the message was dispatched to. */
|
|
387
|
+
results: AgentDispatchResult[];
|
|
388
|
+
}
|
|
389
|
+
/** Response from `POST /conversations/:id/interrupt`. */
|
|
390
|
+
interface InterruptResult {
|
|
391
|
+
ok: boolean;
|
|
392
|
+
interrupted?: boolean;
|
|
393
|
+
reason?: string;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* The inner agent-runtime event carried inside a stream record's `raw`.
|
|
397
|
+
* The platform forwards the agent SDK's own message shapes here; the
|
|
398
|
+
* common discriminants are modeled, with an index signature for the rest.
|
|
399
|
+
*/
|
|
400
|
+
type ChatRawEvent = {
|
|
401
|
+
type: 'user';
|
|
402
|
+
message: string | {
|
|
403
|
+
content: ContentBlock[];
|
|
404
|
+
};
|
|
405
|
+
[k: string]: unknown;
|
|
406
|
+
} | {
|
|
407
|
+
type: 'assistant';
|
|
408
|
+
message: {
|
|
409
|
+
content: ContentBlock[];
|
|
410
|
+
};
|
|
411
|
+
[k: string]: unknown;
|
|
412
|
+
} | {
|
|
413
|
+
type: 'thinking';
|
|
414
|
+
[k: string]: unknown;
|
|
415
|
+
} | {
|
|
416
|
+
type: 'result';
|
|
417
|
+
subtype?: string;
|
|
418
|
+
[k: string]: unknown;
|
|
419
|
+
} | {
|
|
420
|
+
type: 'system';
|
|
421
|
+
subtype?: string;
|
|
422
|
+
[k: string]: unknown;
|
|
423
|
+
} | {
|
|
424
|
+
type: 'ask_user_question_resolution';
|
|
425
|
+
toolUseId: string;
|
|
426
|
+
answers: Record<string, string>;
|
|
427
|
+
} | {
|
|
428
|
+
type: string;
|
|
429
|
+
[k: string]: unknown;
|
|
430
|
+
};
|
|
431
|
+
/**
|
|
432
|
+
* One SSE record from the conversation stream. `data:` payload from the
|
|
433
|
+
* wire, with `id` populated from the SSE `id:` line (the resumable cursor).
|
|
434
|
+
*/
|
|
435
|
+
interface ChatStreamRecord {
|
|
436
|
+
/** SSE cursor (event-stream id) — pass back as `lastEventId` to resume. */
|
|
437
|
+
id?: string;
|
|
438
|
+
seq: number;
|
|
439
|
+
/** `agent` is used for multi-agent conversations; `assistant` for 1:1. */
|
|
440
|
+
sender: 'user' | 'assistant' | 'agent' | 'system';
|
|
441
|
+
senderId?: string;
|
|
442
|
+
senderType?: 'user' | 'agent' | 'system';
|
|
443
|
+
/** Event channel, e.g. `message` | `attachment` | `ack` | `onboarding_welcome`. */
|
|
444
|
+
event: string;
|
|
445
|
+
timestamp: number;
|
|
446
|
+
sessionId: string | null;
|
|
447
|
+
raw: ChatRawEvent;
|
|
448
|
+
}
|
|
449
|
+
/** Options for opening a raw conversation stream. */
|
|
450
|
+
interface StreamOptions {
|
|
451
|
+
/** Resume strictly after this event-stream cursor (from a record `id`). */
|
|
452
|
+
lastEventId?: string;
|
|
453
|
+
/** Initial-load turn count (ignored when `lastEventId` is set). Default 10. */
|
|
454
|
+
turns?: number;
|
|
455
|
+
/** Hard cap on entries per page. */
|
|
456
|
+
maxEntries?: number;
|
|
457
|
+
/** Auto-reconnect with backoff on drop (default true). The generator
|
|
458
|
+
* still ends when the consumer breaks/returns or `signal` aborts. */
|
|
459
|
+
reconnect?: boolean;
|
|
460
|
+
/** Abort the stream. */
|
|
461
|
+
signal?: AbortSignal;
|
|
462
|
+
}
|
|
463
|
+
/** Options for a single high-level turn. */
|
|
464
|
+
interface TurnOptions {
|
|
465
|
+
signal?: AbortSignal;
|
|
466
|
+
/** Continue this conversation instead of creating a new one. */
|
|
467
|
+
conversationId?: string;
|
|
468
|
+
/** Agents to route a NEW conversation to (defaults to the client's agent). */
|
|
469
|
+
targetAgentIds?: string[];
|
|
470
|
+
/** Abort the turn if no event arrives for this long (ms). Default 180_000
|
|
471
|
+
* — generous to cover cold-start pod provisioning on the first message. */
|
|
472
|
+
idleTimeoutMs?: number;
|
|
473
|
+
}
|
|
474
|
+
/** Aggregated result of a completed turn. */
|
|
475
|
+
interface AgentTurn {
|
|
476
|
+
/** The conversation this turn belongs to (reuse it to continue). */
|
|
477
|
+
conversationId: string;
|
|
478
|
+
/** Concatenated assistant text across the turn. */
|
|
479
|
+
text: string;
|
|
480
|
+
/** Tool calls the agent made during the turn. */
|
|
481
|
+
toolCalls: Array<{
|
|
482
|
+
id?: string;
|
|
483
|
+
name: string;
|
|
484
|
+
input: Record<string, unknown>;
|
|
485
|
+
}>;
|
|
486
|
+
/** Every record observed for the turn (assistant + tool results + system). */
|
|
487
|
+
records: ChatStreamRecord[];
|
|
488
|
+
/** The terminal `result` event, if one was seen. */
|
|
489
|
+
result?: ChatRawEvent;
|
|
490
|
+
/** Session id reported by the stream, if any. */
|
|
491
|
+
sessionId: string | null;
|
|
492
|
+
/** Last SSE cursor seen — pass as `lastEventId` to the next turn. */
|
|
493
|
+
lastEventId?: string;
|
|
494
|
+
}
|
|
495
|
+
/** A page of historical records from `GET /conversations/:id/history`. */
|
|
496
|
+
interface HistoryPage {
|
|
497
|
+
entries: Array<{
|
|
498
|
+
id: string;
|
|
499
|
+
data: ChatStreamRecord;
|
|
500
|
+
}>;
|
|
501
|
+
hasMore: boolean;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* The primary entry point: `query`.
|
|
506
|
+
*
|
|
507
|
+
* Runs an agent against the Openhex platform and streams back the
|
|
508
|
+
* resulting messages. Mirrors the Claude Agent SDK's `query` so the
|
|
509
|
+
* ergonomics are familiar:
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* import { query } from '@openhex-ai/agent-sdk';
|
|
513
|
+
*
|
|
514
|
+
* for await (const message of query({
|
|
515
|
+
* prompt: 'Summarize the latest support tickets',
|
|
516
|
+
* options: { allowedTools: ['WebSearch', 'Read'] },
|
|
517
|
+
* })) {
|
|
518
|
+
* if (message.type === 'result') console.log(message.result);
|
|
519
|
+
* }
|
|
520
|
+
*
|
|
521
|
+
* NOTE: scaffold only — resolves config and constructs the transport,
|
|
522
|
+
* then defers to it. The transport itself is not implemented yet.
|
|
523
|
+
*/
|
|
524
|
+
|
|
525
|
+
interface QueryParams {
|
|
526
|
+
/**
|
|
527
|
+
* The instruction for the agent. A string for a one-shot run, or an
|
|
528
|
+
* async iterable of strings for an interactive/streaming-input session.
|
|
529
|
+
*/
|
|
530
|
+
prompt: string | AsyncIterable<string>;
|
|
531
|
+
options?: AgentOptions;
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* The handle returned by {@link query}: an async iterable of
|
|
535
|
+
* {@link SDKMessage}s plus control methods for an in-flight run.
|
|
536
|
+
*/
|
|
537
|
+
interface Query extends AsyncGenerator<SDKMessage, void, void> {
|
|
538
|
+
/** Cooperatively abort the run. */
|
|
539
|
+
interrupt(): Promise<void>;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Start an agent run. Returns a {@link Query} you iterate to consume the
|
|
543
|
+
* message stream.
|
|
544
|
+
*/
|
|
545
|
+
declare function query(params: QueryParams): Query;
|
|
546
|
+
|
|
547
|
+
/** API version prefix every platform route lives under. */
|
|
548
|
+
declare const API_PREFIX = "/api/v2";
|
|
549
|
+
interface HttpClientConfig {
|
|
550
|
+
/** API key or JWT. Falls back to `OPENHEX_API_KEY` when omitted. */
|
|
551
|
+
apiKey?: string;
|
|
552
|
+
/** Base URL of the platform API. Defaults to {@link DEFAULT_BASE_URL}. */
|
|
553
|
+
baseUrl?: string;
|
|
554
|
+
/**
|
|
555
|
+
* Login type stamped as `X-Login-Type` (matches the web/app clients).
|
|
556
|
+
* Only relevant for JWT auth; harmless to omit for API-key auth.
|
|
557
|
+
*/
|
|
558
|
+
loginType?: string;
|
|
559
|
+
/**
|
|
560
|
+
* Service-account id to impersonate via `X-Act-As`. The caller must own
|
|
561
|
+
* the service account (enforced server-side).
|
|
562
|
+
*/
|
|
563
|
+
actAs?: string;
|
|
564
|
+
/** Extra headers merged into every request. */
|
|
565
|
+
headers?: Record<string, string>;
|
|
566
|
+
/** Per-request timeout for non-streaming calls (ms). Default 30_000. */
|
|
567
|
+
timeoutMs?: number;
|
|
568
|
+
/** Override the global fetch (testing / custom agents). */
|
|
569
|
+
fetch?: typeof fetch;
|
|
570
|
+
}
|
|
571
|
+
interface RequestOptions {
|
|
572
|
+
method?: string;
|
|
573
|
+
/** JSON-serializable request body. */
|
|
574
|
+
body?: unknown;
|
|
575
|
+
/** Extra/override headers for this request. */
|
|
576
|
+
headers?: Record<string, string>;
|
|
577
|
+
/** Caller-supplied abort signal (merged with the timeout signal). */
|
|
578
|
+
signal?: AbortSignal;
|
|
579
|
+
/** Override the default timeout for this request (ms). 0 disables it. */
|
|
580
|
+
timeoutMs?: number;
|
|
581
|
+
}
|
|
582
|
+
declare class HttpClient {
|
|
583
|
+
private readonly apiKey;
|
|
584
|
+
readonly baseUrl: string;
|
|
585
|
+
private readonly loginType?;
|
|
586
|
+
private readonly actAs?;
|
|
587
|
+
private readonly extraHeaders;
|
|
588
|
+
private readonly timeoutMs;
|
|
589
|
+
private readonly fetchImpl;
|
|
590
|
+
constructor(config?: HttpClientConfig);
|
|
591
|
+
/** Build the full URL for an API path (prefixing `/api/v2` if needed). */
|
|
592
|
+
url(path: string): string;
|
|
593
|
+
/** Headers common to every request. `accept` differs for SSE vs JSON. */
|
|
594
|
+
buildHeaders(accept: string, extra?: Record<string, string>): Record<string, string>;
|
|
595
|
+
/** Map a non-2xx response to an {@link ApiError}, extracting `detail`. */
|
|
596
|
+
private toError;
|
|
597
|
+
/** Perform a JSON request and parse the response body. */
|
|
598
|
+
requestJson<T = unknown>(path: string, options?: RequestOptions): Promise<T>;
|
|
599
|
+
/** Perform a request and return the raw {@link Response} (used for SSE). */
|
|
600
|
+
requestRaw(path: string, options?: RequestOptions, accept?: string): Promise<Response>;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* AgentChatClient — chat with a platform agent over the exact protocol
|
|
605
|
+
* the user-side apps use (`conversationRoutes`).
|
|
606
|
+
*
|
|
607
|
+
* Endpoints (all under `/api/v2`):
|
|
608
|
+
* POST /conversations/send — create/continue a conversation, route a message
|
|
609
|
+
* GET /conversations/:id/stream — SSE record stream (resumable)
|
|
610
|
+
* GET /conversations/:id/messages — full history (JSON)
|
|
611
|
+
* GET /conversations/:id/history — paginated older history (JSON)
|
|
612
|
+
* POST /conversations/:id/interrupt — interrupt the running turn
|
|
613
|
+
*
|
|
614
|
+
* Low-level methods (`send`, `stream`, `messages`, `history`, `interrupt`)
|
|
615
|
+
* map 1:1 to the wire. High-level helpers (`runTurn`, `sendMessage`) add
|
|
616
|
+
* turn isolation (resume the stream from the user message's event id),
|
|
617
|
+
* reconnection, and an idle-timeout for cold-start pod provisioning.
|
|
618
|
+
*/
|
|
619
|
+
|
|
620
|
+
declare class AgentChatClient {
|
|
621
|
+
private readonly http;
|
|
622
|
+
constructor(http: HttpClient);
|
|
623
|
+
/**
|
|
624
|
+
* Create or continue a conversation and route a message to its agent(s).
|
|
625
|
+
* Returns immediately (non-blocking); consume {@link stream} for the reply.
|
|
626
|
+
*/
|
|
627
|
+
send(req: SendRequest, opts?: {
|
|
628
|
+
signal?: AbortSignal;
|
|
629
|
+
}): Promise<SendResult>;
|
|
630
|
+
/** Interrupt the conversation's currently-running turn. */
|
|
631
|
+
interrupt(conversationId: string, opts?: {
|
|
632
|
+
signal?: AbortSignal;
|
|
633
|
+
}): Promise<InterruptResult>;
|
|
634
|
+
/** Full conversation history (all messages as JSON). */
|
|
635
|
+
messages(conversationId: string, opts?: {
|
|
636
|
+
signal?: AbortSignal;
|
|
637
|
+
}): Promise<{
|
|
638
|
+
entries: Array<{
|
|
639
|
+
id: string;
|
|
640
|
+
data: ChatStreamRecord;
|
|
641
|
+
}>;
|
|
642
|
+
}>;
|
|
643
|
+
/** A page of older history, before a cursor. */
|
|
644
|
+
history(conversationId: string, params: {
|
|
645
|
+
before: string;
|
|
646
|
+
turns?: number;
|
|
647
|
+
maxEntries?: number;
|
|
648
|
+
}, opts?: {
|
|
649
|
+
signal?: AbortSignal;
|
|
650
|
+
}): Promise<HistoryPage>;
|
|
651
|
+
/**
|
|
652
|
+
* Open the conversation's SSE record stream. Yields every record
|
|
653
|
+
* (replayed history then live tail), auto-reconnecting with capped
|
|
654
|
+
* backoff on drop. The generator ends when the consumer breaks/returns
|
|
655
|
+
* or `signal` aborts.
|
|
656
|
+
*/
|
|
657
|
+
stream(conversationId: string, opts?: StreamOptions): AsyncGenerator<ChatStreamRecord, void, void>;
|
|
658
|
+
/**
|
|
659
|
+
* Stream a single turn over an existing conversation: resume the event
|
|
660
|
+
* stream strictly after `opts.lastEventId` (the user message's event id)
|
|
661
|
+
* and stop at the agent's terminal `result`. Reconnects on drop; an
|
|
662
|
+
* `idleTimeoutMs` gap with no events aborts (covers cold-start pod
|
|
663
|
+
* provisioning). Use when you sent the message yourself via {@link send}.
|
|
664
|
+
*/
|
|
665
|
+
resumeTurn(conversationId: string, opts?: TurnOptions & {
|
|
666
|
+
lastEventId?: string;
|
|
667
|
+
}): AsyncGenerator<ChatStreamRecord, void, void>;
|
|
668
|
+
/**
|
|
669
|
+
* Send a message and stream just this turn's records, ending when the
|
|
670
|
+
* agent's `result` event arrives.
|
|
671
|
+
*
|
|
672
|
+
* The message is sent first; the stream then resumes precisely from the
|
|
673
|
+
* user message's event id, so only the agent's reply is surfaced — no
|
|
674
|
+
* history, no heuristics. To learn the (possibly new) conversation id
|
|
675
|
+
* while streaming, use {@link sendMessage} or the stateful
|
|
676
|
+
* {@link Conversation}.
|
|
677
|
+
*
|
|
678
|
+
* The first message in a new conversation auto-provisions the agent's
|
|
679
|
+
* pod, so the first turn can take tens of seconds before any record
|
|
680
|
+
* arrives; `idleTimeoutMs` (default 180s) bounds the wait.
|
|
681
|
+
*/
|
|
682
|
+
runTurn(req: SendRequest, opts?: TurnOptions): AsyncGenerator<ChatStreamRecord, void, void>;
|
|
683
|
+
/**
|
|
684
|
+
* Send a message and resolve with the aggregated turn (assistant text,
|
|
685
|
+
* tool calls, all records, conversation id, and a resume cursor).
|
|
686
|
+
*/
|
|
687
|
+
sendMessage(req: SendRequest, opts?: TurnOptions): Promise<AgentTurn>;
|
|
688
|
+
/**
|
|
689
|
+
* Start a stateful conversation handle that remembers its id across
|
|
690
|
+
* turns. The first {@link Conversation.send} creates the conversation
|
|
691
|
+
* (routed to `targetAgentIds`); subsequent sends continue it.
|
|
692
|
+
*/
|
|
693
|
+
conversation(opts?: {
|
|
694
|
+
conversationId?: string;
|
|
695
|
+
targetAgentIds?: string[];
|
|
696
|
+
}): Conversation;
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* A stateful 1:1 (or multi-agent) conversation. Tracks the conversation
|
|
700
|
+
* id so you can `send` repeated turns without re-passing it, and continues
|
|
701
|
+
* the same chat-group context each time.
|
|
702
|
+
*/
|
|
703
|
+
declare class Conversation {
|
|
704
|
+
private readonly client;
|
|
705
|
+
private conversationId;
|
|
706
|
+
private readonly targetAgentIds;
|
|
707
|
+
constructor(client: AgentChatClient, conversationId: string | undefined, targetAgentIds: string[] | undefined);
|
|
708
|
+
/** The conversation id, once the first message has been sent. */
|
|
709
|
+
get id(): string | undefined;
|
|
710
|
+
/** Build the send request for the next turn (create vs continue). */
|
|
711
|
+
private buildRequest;
|
|
712
|
+
/** Send a turn and resolve with the aggregated result. */
|
|
713
|
+
send(message: string, opts?: TurnOptions & Partial<SendRequest>): Promise<AgentTurn>;
|
|
714
|
+
/** Send a turn and stream its records as they arrive. */
|
|
715
|
+
stream(message: string, opts?: TurnOptions & Partial<SendRequest>): AsyncGenerator<ChatStreamRecord, void, void>;
|
|
716
|
+
/** Interrupt the running turn in this conversation. */
|
|
717
|
+
interrupt(): Promise<InterruptResult>;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
/**
|
|
721
|
+
* Training-mode chat — talk to an agent AS ITS OWNER over the dev/train
|
|
722
|
+
* protocol (the agent runs in CREATION/TRAINING mode, so it can learn:
|
|
723
|
+
* edit skills/knowledge/persona, accept feedback, etc.). This is distinct
|
|
724
|
+
* from {@link AgentChatClient}, which is the user-side conversations
|
|
725
|
+
* protocol.
|
|
726
|
+
*
|
|
727
|
+
* Wire (all under /api/v2, owner/collaborator auth):
|
|
728
|
+
* POST /agents/:id/dev/send — send a training message → { ok, msgId }
|
|
729
|
+
* GET /agents/:id/messages/stream — SSE record stream (seq-keyed, resumable
|
|
730
|
+
* via lastEventId; `turns=1` = latest turn)
|
|
731
|
+
* GET /agents/:id/messages/history — JSON history
|
|
732
|
+
* POST /agents/:id/dev/interrupt — interrupt the running turn
|
|
733
|
+
*
|
|
734
|
+
* The training thread is agent-scoped (one per owner), so there's no
|
|
735
|
+
* conversationId — the agent id IS the thread.
|
|
736
|
+
*/
|
|
737
|
+
|
|
738
|
+
interface TrainingSendResult {
|
|
739
|
+
ok: boolean;
|
|
740
|
+
msgId?: string;
|
|
741
|
+
}
|
|
742
|
+
interface TrainingStreamOptions extends TurnOptions {
|
|
743
|
+
/** Resume strictly after this record seq (stringified). */
|
|
744
|
+
lastEventId?: string;
|
|
745
|
+
/** Return only the latest N turns (server-side turn paging). */
|
|
746
|
+
turns?: number;
|
|
747
|
+
reconnect?: boolean;
|
|
748
|
+
}
|
|
749
|
+
/** A training (owner-mode) chat bound to one agent. */
|
|
750
|
+
declare class TrainingChat {
|
|
751
|
+
private readonly http;
|
|
752
|
+
private readonly agentId;
|
|
753
|
+
constructor(http: HttpClient, agentId: string);
|
|
754
|
+
/** Send a training message; the reply streams asynchronously (see {@link stream}). */
|
|
755
|
+
send(message: string, opts?: {
|
|
756
|
+
signal?: AbortSignal;
|
|
757
|
+
}): Promise<TrainingSendResult>;
|
|
758
|
+
/** Interrupt the running training turn. */
|
|
759
|
+
interrupt(opts?: {
|
|
760
|
+
signal?: AbortSignal;
|
|
761
|
+
}): Promise<{
|
|
762
|
+
ok: boolean;
|
|
763
|
+
}>;
|
|
764
|
+
/**
|
|
765
|
+
* Training transcript (JSON), paginated backward from `before` (a Redis
|
|
766
|
+
* stream id). The endpoint REQUIRES `before`, so we default to a
|
|
767
|
+
* far-future sentinel to fetch the latest turns; pass a real id to page
|
|
768
|
+
* older history.
|
|
769
|
+
*/
|
|
770
|
+
messages(opts?: {
|
|
771
|
+
before?: string;
|
|
772
|
+
signal?: AbortSignal;
|
|
773
|
+
}): Promise<{
|
|
774
|
+
entries: Array<{
|
|
775
|
+
data?: ChatStreamRecord;
|
|
776
|
+
}>;
|
|
777
|
+
hasMore?: boolean;
|
|
778
|
+
}>;
|
|
779
|
+
/** Raw SSE record stream of the training thread (replayed + live tail). */
|
|
780
|
+
stream(opts?: TrainingStreamOptions): AsyncGenerator<ChatStreamRecord, void, void>;
|
|
781
|
+
/**
|
|
782
|
+
* Send a training message and stream just that turn's records, ending at
|
|
783
|
+
* the agent's terminal `result`. Streams the latest turn (`turns=1`) after
|
|
784
|
+
* the send; an `idleTimeoutMs` gap (default 180s) bounds cold-start waits.
|
|
785
|
+
*/
|
|
786
|
+
runTurn(message: string, opts?: TurnOptions): AsyncGenerator<ChatStreamRecord, void, void>;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
/**
|
|
790
|
+
* Wire types for the Workspace API (`/api/v2/workspaces/*`).
|
|
791
|
+
*
|
|
792
|
+
* These mirror the platform's published OpenAPI surface 1:1 — the same
|
|
793
|
+
* contract documented at `/api/v2/workspaces/openapi.json`. A workspace
|
|
794
|
+
* is a billing + membership boundary an SP (service provider / partner)
|
|
795
|
+
* owns; the API lets a partner backend provision members, mint member
|
|
796
|
+
* sessions, grant credits, and read reporting.
|
|
797
|
+
*
|
|
798
|
+
* Auth is a `Bearer` token in every case (see {@link WorkspaceClient}):
|
|
799
|
+
* - a workspace API key (`sk_ws_…`) for partner-backend operations,
|
|
800
|
+
* - or no token for the public SMS-signup endpoints.
|
|
801
|
+
*
|
|
802
|
+
* The owner-JWT admin surface (workspace ledger, insights, API-key
|
|
803
|
+
* management) is deliberately NOT mirrored in the SDK — those routes
|
|
804
|
+
* power the SP admin UI and aren't in the published partner spec.
|
|
805
|
+
*
|
|
806
|
+
* Date fields cross the wire as ISO-8601 strings (the server serializes
|
|
807
|
+
* its `Date`s to JSON), so they're typed as `string` here.
|
|
808
|
+
*/
|
|
809
|
+
/** Identity of the workspace a key/JWT is acting on. */
|
|
810
|
+
interface WorkspaceWhoami {
|
|
811
|
+
workspace_id: string;
|
|
812
|
+
slug: string;
|
|
813
|
+
display_name: string;
|
|
814
|
+
status: string;
|
|
815
|
+
/** The API key id the request authenticated with. */
|
|
816
|
+
api_key_id: string;
|
|
817
|
+
}
|
|
818
|
+
/** One member row from {@link WorkspaceClient.listMembers}. */
|
|
819
|
+
interface WorkspaceMember {
|
|
820
|
+
user_id: string;
|
|
821
|
+
billing_account_id: string;
|
|
822
|
+
/** The SP's own reference for this user (may be null for legacy rows). */
|
|
823
|
+
sp_user_ref: string | null;
|
|
824
|
+
status: string;
|
|
825
|
+
/** ISO-8601 timestamp. */
|
|
826
|
+
joined_at: string;
|
|
827
|
+
/** Current credit balance on the member's billing account. */
|
|
828
|
+
balance: number;
|
|
829
|
+
}
|
|
830
|
+
interface MembersListResponse {
|
|
831
|
+
members: WorkspaceMember[];
|
|
832
|
+
}
|
|
833
|
+
/** Body for {@link WorkspaceClient.provisionMember}. */
|
|
834
|
+
interface ProvisionMemberRequest {
|
|
835
|
+
/** The SP's stable reference for this user. Idempotency key for the member. */
|
|
836
|
+
sp_user_ref: string;
|
|
837
|
+
/** Optional display name to label the member. */
|
|
838
|
+
display_name?: string;
|
|
839
|
+
}
|
|
840
|
+
interface ProvisionMemberResponse {
|
|
841
|
+
member_id: string;
|
|
842
|
+
billing_account_id: string;
|
|
843
|
+
/** `true` if this call created the member; `false` if it already existed. */
|
|
844
|
+
created: boolean;
|
|
845
|
+
}
|
|
846
|
+
/** Body for {@link WorkspaceClient.grantCredits}. */
|
|
847
|
+
interface GrantCreditsRequest {
|
|
848
|
+
/** Positive credit amount to grant (max 1e9). */
|
|
849
|
+
amount: number;
|
|
850
|
+
/** Caller-supplied idempotency key; replays return the original purchase. */
|
|
851
|
+
idempotency_key: string;
|
|
852
|
+
}
|
|
853
|
+
interface GrantCreditsResponse {
|
|
854
|
+
/** Member's balance after the grant. */
|
|
855
|
+
balance: number;
|
|
856
|
+
purchase_id: string;
|
|
857
|
+
/** `true` when this was a replay of a prior identical grant. */
|
|
858
|
+
idempotent: boolean;
|
|
859
|
+
}
|
|
860
|
+
/** Body for {@link WorkspaceClient.mintSession}. */
|
|
861
|
+
interface MintSessionRequest {
|
|
862
|
+
/** The already-provisioned member's SP reference. */
|
|
863
|
+
sp_user_ref: string;
|
|
864
|
+
/** Token lifetime in seconds (max 86_400). Server picks a default if omitted. */
|
|
865
|
+
ttl_seconds?: number;
|
|
866
|
+
}
|
|
867
|
+
/** A minted member session — returned by mintSession + SMS verify. */
|
|
868
|
+
interface SessionTokenResponse {
|
|
869
|
+
/** JWT the member's client presents to the platform. */
|
|
870
|
+
token: string;
|
|
871
|
+
user_id: string;
|
|
872
|
+
/** ISO-8601 expiry timestamp. */
|
|
873
|
+
expires_at: string;
|
|
874
|
+
}
|
|
875
|
+
/** Body for {@link WorkspaceClient.sendSmsCode}. */
|
|
876
|
+
interface SmsSendRequest {
|
|
877
|
+
phone: string;
|
|
878
|
+
}
|
|
879
|
+
/** Body for {@link WorkspaceClient.verifySmsCode}. */
|
|
880
|
+
interface SmsVerifyRequest {
|
|
881
|
+
phone: string;
|
|
882
|
+
code: string;
|
|
883
|
+
}
|
|
884
|
+
/** Options accepted by every workspace request. */
|
|
885
|
+
interface WorkspaceRequestOptions {
|
|
886
|
+
/** Abort the request. */
|
|
887
|
+
signal?: AbortSignal;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
/**
|
|
891
|
+
* WorkspaceClient — manage a platform workspace over the partner-facing
|
|
892
|
+
* subset of `/api/v2/workspaces/*` (the same surface the published
|
|
893
|
+
* OpenAPI spec exposes).
|
|
894
|
+
*
|
|
895
|
+
* Endpoints (all under `/api/v2`):
|
|
896
|
+
*
|
|
897
|
+
* Workspace API key (`sk_ws_…`) — partner backend:
|
|
898
|
+
* GET /workspaces/whoami
|
|
899
|
+
* POST /workspaces/:slug/members
|
|
900
|
+
* DELETE /workspaces/:slug/members/:memberId
|
|
901
|
+
* POST /workspaces/:slug/sessions
|
|
902
|
+
*
|
|
903
|
+
* Either auth (owner JWT or workspace API key):
|
|
904
|
+
* GET /workspaces/:slug/members
|
|
905
|
+
* POST /workspaces/:slug/members/:memberId/credits
|
|
906
|
+
*
|
|
907
|
+
* Public (no auth):
|
|
908
|
+
* POST /workspaces/:slug/sms/send
|
|
909
|
+
* POST /workspaces/:slug/sms/verify
|
|
910
|
+
*
|
|
911
|
+
* Deliberately omitted: the 6 owner-JWT admin routes (workspace ledger,
|
|
912
|
+
* insights, per-member ledger, API-key CRUD). They power the SP admin
|
|
913
|
+
* UI in `webapp/src/app/[locale]/(app)/settings/*` and don't appear in
|
|
914
|
+
* the published partner OpenAPI spec (hidden in
|
|
915
|
+
* `mysta-server/src/routes/workspacesOwnerRoutes.ts`). Wrapping them in
|
|
916
|
+
* the SDK would invite partners to call routes the docs say don't exist;
|
|
917
|
+
* with a workspace API key they'd just 401.
|
|
918
|
+
*
|
|
919
|
+
* Auth is the `Bearer` token carried by the underlying {@link HttpClient}.
|
|
920
|
+
* Configure the client with the token the operation needs: a workspace
|
|
921
|
+
* API key for partner calls, or skip the header entirely for the public
|
|
922
|
+
* SMS endpoints.
|
|
923
|
+
*
|
|
924
|
+
* Use {@link WorkspaceClient.workspace} for a slug-bound handle so you
|
|
925
|
+
* don't repeat the slug on every call.
|
|
926
|
+
*/
|
|
927
|
+
|
|
928
|
+
declare class WorkspaceClient {
|
|
929
|
+
private readonly http;
|
|
930
|
+
constructor(http: HttpClient);
|
|
931
|
+
/**
|
|
932
|
+
* Identify the workspace the configured API key belongs to. Solves the
|
|
933
|
+
* bootstrap problem for a new partner who holds only the `sk_ws_…` token
|
|
934
|
+
* but every slug-keyed route needs a slug.
|
|
935
|
+
*/
|
|
936
|
+
whoami(opts?: WorkspaceRequestOptions): Promise<WorkspaceWhoami>;
|
|
937
|
+
/**
|
|
938
|
+
* Provision (or look up) a workspace member by SP user reference.
|
|
939
|
+
* Idempotent on `(workspace, sp_user_ref)` — the first call creates the
|
|
940
|
+
* member, later calls return the existing ids (`created: false`).
|
|
941
|
+
*/
|
|
942
|
+
provisionMember(slug: string, body: ProvisionMemberRequest, opts?: WorkspaceRequestOptions): Promise<ProvisionMemberResponse>;
|
|
943
|
+
/** Suspend a member (soft — sets status to `suspended`). */
|
|
944
|
+
suspendMember(slug: string, memberId: string, opts?: WorkspaceRequestOptions): Promise<void>;
|
|
945
|
+
/**
|
|
946
|
+
* Mint a session JWT for an already-provisioned member. The partner
|
|
947
|
+
* authenticates the human on their side, then calls this with the same
|
|
948
|
+
* `sp_user_ref` to get a token the member's client presents to the platform.
|
|
949
|
+
*/
|
|
950
|
+
mintSession(slug: string, body: MintSessionRequest, opts?: WorkspaceRequestOptions): Promise<SessionTokenResponse>;
|
|
951
|
+
/** List workspace members with current balances (capped at 500). */
|
|
952
|
+
listMembers(slug: string, opts?: WorkspaceRequestOptions): Promise<MembersListResponse>;
|
|
953
|
+
/**
|
|
954
|
+
* Grant credits to a member from the workspace pool. Idempotent on
|
|
955
|
+
* `body.idempotency_key` — replays return the original purchase.
|
|
956
|
+
*/
|
|
957
|
+
grantCredits(slug: string, memberId: string, body: GrantCreditsRequest, opts?: WorkspaceRequestOptions): Promise<GrantCreditsResponse>;
|
|
958
|
+
/**
|
|
959
|
+
* Send a one-time SMS verification code for public signup. Requires the
|
|
960
|
+
* workspace to have `public_sms_signup_enabled`.
|
|
961
|
+
*/
|
|
962
|
+
sendSmsCode(slug: string, body: SmsSendRequest, opts?: WorkspaceRequestOptions): Promise<void>;
|
|
963
|
+
/** Verify an SMS code and mint a member session JWT in one shot. */
|
|
964
|
+
verifySmsCode(slug: string, body: SmsVerifyRequest, opts?: WorkspaceRequestOptions): Promise<SessionTokenResponse>;
|
|
965
|
+
/**
|
|
966
|
+
* A slug-bound handle so you don't repeat the slug on every call.
|
|
967
|
+
* `client.workspaces.workspace('acme').listMembers()`.
|
|
968
|
+
*/
|
|
969
|
+
workspace(slug: string): Workspace;
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* A workspace pinned to one slug. Thin sugar over {@link WorkspaceClient}
|
|
973
|
+
* that drops the leading `slug` argument from every method. `whoami` stays
|
|
974
|
+
* on the parent client (it's key-bound, not slug-bound).
|
|
975
|
+
*/
|
|
976
|
+
declare class Workspace {
|
|
977
|
+
private readonly client;
|
|
978
|
+
readonly slug: string;
|
|
979
|
+
constructor(client: WorkspaceClient, slug: string);
|
|
980
|
+
listMembers(opts?: WorkspaceRequestOptions): Promise<MembersListResponse>;
|
|
981
|
+
provisionMember(body: ProvisionMemberRequest, opts?: WorkspaceRequestOptions): Promise<ProvisionMemberResponse>;
|
|
982
|
+
suspendMember(memberId: string, opts?: WorkspaceRequestOptions): Promise<void>;
|
|
983
|
+
grantCredits(memberId: string, body: GrantCreditsRequest, opts?: WorkspaceRequestOptions): Promise<GrantCreditsResponse>;
|
|
984
|
+
mintSession(body: MintSessionRequest, opts?: WorkspaceRequestOptions): Promise<SessionTokenResponse>;
|
|
985
|
+
sendSmsCode(body: SmsSendRequest, opts?: WorkspaceRequestOptions): Promise<void>;
|
|
986
|
+
verifySmsCode(body: SmsVerifyRequest, opts?: WorkspaceRequestOptions): Promise<SessionTokenResponse>;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
/**
|
|
990
|
+
* `OpenhexClient` — a stateful, higher-level wrapper over the SDK.
|
|
991
|
+
*
|
|
992
|
+
* Pin connection + agent config once, then chat with an agent (`chat`,
|
|
993
|
+
* `sendMessage`, `conversation`), run local-style queries (`query`,
|
|
994
|
+
* scaffold), or manage sessions.
|
|
995
|
+
*/
|
|
996
|
+
|
|
997
|
+
interface OpenhexClientConfig extends OpenhexConnection {
|
|
998
|
+
/** `X-Login-Type` header (matches the web/app clients). JWT auth only. */
|
|
999
|
+
loginType?: string;
|
|
1000
|
+
/** Service-account id to impersonate via `X-Act-As` (caller must own it). */
|
|
1001
|
+
actAs?: string;
|
|
1002
|
+
/** Per-request timeout for non-streaming calls (ms). Default 30_000. */
|
|
1003
|
+
timeoutMs?: number;
|
|
1004
|
+
/** Override the global fetch (testing / custom runtimes). */
|
|
1005
|
+
fetch?: typeof fetch;
|
|
1006
|
+
/** Default options merged into every {@link OpenhexClient.query} call. */
|
|
1007
|
+
defaultOptions?: Omit<AgentOptions, keyof OpenhexConnection>;
|
|
1008
|
+
}
|
|
1009
|
+
declare class OpenhexClient {
|
|
1010
|
+
private readonly config;
|
|
1011
|
+
/** Low- and high-level chat API (conversations protocol). */
|
|
1012
|
+
readonly chat: AgentChatClient;
|
|
1013
|
+
/**
|
|
1014
|
+
* Workspace API (`/api/v2/workspaces/*`) — provision members, mint
|
|
1015
|
+
* member sessions, grant credits, read reporting. Auth is whatever
|
|
1016
|
+
* token the client is configured with (a `sk_ws_…` workspace API key
|
|
1017
|
+
* for partner calls, or the owner's JWT for SP-admin calls).
|
|
1018
|
+
*/
|
|
1019
|
+
readonly workspaces: WorkspaceClient;
|
|
1020
|
+
private readonly http;
|
|
1021
|
+
constructor(config?: OpenhexClientConfig);
|
|
1022
|
+
/**
|
|
1023
|
+
* A slug-bound workspace handle so you don't repeat the slug on every
|
|
1024
|
+
* call. Equivalent to `client.workspaces.workspace(slug)`.
|
|
1025
|
+
*/
|
|
1026
|
+
workspace(slug: string): Workspace;
|
|
1027
|
+
/**
|
|
1028
|
+
* Training-mode chat with an agent AS ITS OWNER (the dev/train protocol —
|
|
1029
|
+
* the agent runs in CREATION/TRAINING mode and can learn from feedback).
|
|
1030
|
+
* Defaults to the client's configured `agentId`; pass one to override.
|
|
1031
|
+
*/
|
|
1032
|
+
training(agentId?: string): TrainingChat;
|
|
1033
|
+
/** Default target agents for new conversations (from `config.agentId`). */
|
|
1034
|
+
private defaultTargets;
|
|
1035
|
+
/** Build a {@link SendRequest} from a message + turn options. */
|
|
1036
|
+
private buildRequest;
|
|
1037
|
+
/**
|
|
1038
|
+
* Send a message and resolve with the aggregated turn. Creates a new
|
|
1039
|
+
* conversation routed to the configured agent unless `opts.conversationId`
|
|
1040
|
+
* is given. The returned turn carries `conversationId` to continue.
|
|
1041
|
+
*/
|
|
1042
|
+
sendMessage(message: string, opts?: TurnOptions): Promise<AgentTurn>;
|
|
1043
|
+
/** Stream a single turn's records (see {@link sendMessage}). */
|
|
1044
|
+
runTurn(message: string, opts?: TurnOptions): AsyncGenerator<ChatStreamRecord, void, void>;
|
|
1045
|
+
/**
|
|
1046
|
+
* Start a stateful conversation that remembers its id across turns,
|
|
1047
|
+
* defaulting its target agents to the configured agent.
|
|
1048
|
+
*/
|
|
1049
|
+
conversation(opts?: {
|
|
1050
|
+
conversationId?: string;
|
|
1051
|
+
targetAgentIds?: string[];
|
|
1052
|
+
}): Conversation;
|
|
1053
|
+
/**
|
|
1054
|
+
* Run an agent query using this client's connection + default options.
|
|
1055
|
+
* Per-call `options` are shallow-merged over the client defaults.
|
|
1056
|
+
*/
|
|
1057
|
+
query(params: QueryParams): Query;
|
|
1058
|
+
/** List recent sessions for the configured agent. */
|
|
1059
|
+
listSessions(): Promise<SessionInfo[]>;
|
|
1060
|
+
/** Fetch metadata for a single session. */
|
|
1061
|
+
getSession(_sessionId: string): Promise<SessionInfo>;
|
|
1062
|
+
/** Delete a session and its stored context. */
|
|
1063
|
+
deleteSession(_sessionId: string): Promise<void>;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
export { type StreamOptions as $, type AgentOptions as A, type ProvisionMemberRequest as B, type ChatStreamRecord as C, type ProvisionMemberResponse as D, type QueryParams as E, type SDKAssistantMessage as F, type GrantCreditsRequest as G, type HookCallback as H, type InterruptResult as I, type SDKPartialAssistantMessage as J, type SDKResultMessage as K, type SDKSystemMessage as L, type McpServerConfig as M, type SDKUserMessage as N, OpenhexClient as O, type PermissionMode as P, type Query as Q, type RequestOptions as R, type SDKMessage as S, type SendRequest as T, type SendResult as U, type SessionInfo as V, type SessionTokenResponse as W, type SettingSource as X, type SmsSendRequest as Y, type SmsVerifyRequest as Z, type StdioMcpServerConfig as _, type HookMatcher as a, TrainingChat as a0, type TrainingSendResult as a1, type TurnOptions as a2, type UsageInfo as a3, Workspace as a4, WorkspaceClient as a5, type WorkspaceMember as a6, type WorkspaceRequestOptions as a7, type WorkspaceWhoami as a8, query as a9, API_PREFIX as b, AgentChatClient as c, type AgentDefinition as d, type AgentDispatchResult as e, type AgentRegistry as f, type AgentTurn as g, type CanUseTool as h, type ChatRawEvent as i, type ContentBlock as j, Conversation as k, type GrantCreditsResponse as l, type HistoryPage as m, type HookEvent as n, type HookInput as o, type HookOutput as p, type HookRegistry as q, HttpClient as r, type HttpClientConfig as s, type HttpMcpServerConfig as t, type McpServerRegistry as u, type MembersListResponse as v, type MintSessionRequest as w, type OpenhexClientConfig as x, type OpenhexConnection as y, type PermissionResult as z };
|