@runmark/sdk 0.1.0 → 0.1.2
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/CHANGELOG.md +9 -0
- package/README.md +348 -124
- package/dist/client.d.ts +11 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +38 -4
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +2 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +2 -0
- package/dist/errors.js.map +1 -1
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +67 -5
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/routes.d.ts +5 -1
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +14 -2
- package/dist/routes.js.map +1 -1
- package/dist/sse.d.ts.map +1 -1
- package/dist/sse.js +10 -1
- package/dist/sse.js.map +1 -1
- package/dist/types.d.ts +85 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +11 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.2
|
|
4
|
+
|
|
5
|
+
- Add request-ID submission and lookup, durable cancellation, HITL request
|
|
6
|
+
correlation, active-organization forwarding, and replay-cursor contracts.
|
|
7
|
+
- Add durable response/error types and preserve typed API error codes.
|
|
8
|
+
- Validate and bound JSON/SSE responses, including fragmented CRLF events,
|
|
9
|
+
malformed envelopes, oversized bodies/events, and reader cancellation.
|
package/README.md
CHANGED
|
@@ -1,81 +1,257 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @runmark/sdk
|
|
2
2
|
|
|
3
|
-
Server-side TypeScript SDK for Skyforge agent chat
|
|
3
|
+
Server-side TypeScript SDK for calling Skyforge agent chat APIs from trusted
|
|
4
|
+
backend code.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
publishing policy are approved.
|
|
6
|
+
Use this package from Express apps, Next.js route handlers, serverless
|
|
7
|
+
functions, jobs, and backend proxies. Do not use it in browser code.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
```text
|
|
10
|
+
Browser
|
|
11
|
+
-> your backend
|
|
12
|
+
-> @runmark/sdk
|
|
13
|
+
-> Skyforge API
|
|
14
|
+
```
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Use `@runmark/agent-chat` when you need the browser or React chat UI.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
## When To Use It
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
- Send messages to a configured Skyforge agent branch from your backend.
|
|
21
|
+
- Build an app proxy for `@runmark/agent-chat`.
|
|
22
|
+
- Resume a known Skyforge chat by `chatId`.
|
|
23
|
+
- Attach optional host-app mapping metadata with `externalId`.
|
|
24
|
+
- Build server-side chat recovery, search, or history using agent-scoped chat
|
|
25
|
+
lookup.
|
|
26
|
+
- Upload, list, and delete files attached to a chat.
|
|
27
|
+
- Stream durable run events and submit human actions.
|
|
23
28
|
|
|
24
|
-
|
|
25
|
-
`/api/auth/csrf`.
|
|
29
|
+
## Installation
|
|
26
30
|
|
|
27
|
-
|
|
31
|
+
```bash
|
|
32
|
+
npm install @runmark/sdk
|
|
33
|
+
```
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
backend field names.
|
|
35
|
+
## Requirements
|
|
31
36
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
- Node.js `24.17.0` or newer
|
|
38
|
+
- A server-side Skyforge API token
|
|
39
|
+
- Native `fetch`, `FormData`, `ReadableStream`, and `AbortSignal`
|
|
35
40
|
|
|
36
|
-
##
|
|
41
|
+
## Client Setup
|
|
37
42
|
|
|
38
43
|
```ts
|
|
39
|
-
import { SkyforgeClient } from "@
|
|
44
|
+
import { SkyforgeClient } from "@runmark/sdk";
|
|
40
45
|
|
|
41
46
|
const skyforge = new SkyforgeClient({
|
|
42
47
|
apiKey: process.env.SKYFORGE_API_TOKEN!,
|
|
43
|
-
baseUrl: "https://api.skyforge.ai",
|
|
48
|
+
baseUrl: process.env.SKYFORGE_API_BASE_URL ?? "https://api.skyforge.ai",
|
|
44
49
|
});
|
|
45
50
|
```
|
|
46
51
|
|
|
47
|
-
|
|
52
|
+
Common server-side environment variables:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
SKYFORGE_API_BASE_URL=https://api.skyforge.ai
|
|
56
|
+
SKYFORGE_API_TOKEN=
|
|
57
|
+
SKYFORGE_AGENT_ID=
|
|
58
|
+
SKYFORGE_AGENT_BRANCH_ID=
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`SKYFORGE_API_TOKEN` must stay on the server. Never bundle it into frontend
|
|
62
|
+
code.
|
|
63
|
+
|
|
64
|
+
## Auth And Security Model
|
|
65
|
+
|
|
66
|
+
The SDK sends:
|
|
67
|
+
|
|
68
|
+
```http
|
|
69
|
+
Authorization: Bearer <SKYFORGE_API_TOKEN>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
It does not require browser cookies, CSRF tokens, browser credentials, or
|
|
73
|
+
frontend auth routes.
|
|
74
|
+
|
|
75
|
+
Use your own app authentication and tenancy checks before deciding which
|
|
76
|
+
Skyforge agent, branch, chat, or `externalId` a request may use. `externalId`
|
|
77
|
+
is metadata for mapping chats back to your app; it is not authentication and it
|
|
78
|
+
does not bypass Skyforge API-token authorization.
|
|
79
|
+
|
|
80
|
+
## Send a Message
|
|
48
81
|
|
|
49
82
|
```ts
|
|
50
|
-
const
|
|
51
|
-
agentBranchId:
|
|
52
|
-
|
|
83
|
+
const response = await skyforge.agentBranches.sendMessage({
|
|
84
|
+
agentBranchId: process.env.SKYFORGE_AGENT_BRANCH_ID!,
|
|
85
|
+
message: "Help me plan this outdoor event.",
|
|
86
|
+
externalId: "event_123",
|
|
87
|
+
requestId: crypto.randomUUID(),
|
|
53
88
|
});
|
|
54
89
|
|
|
55
|
-
console.log(
|
|
90
|
+
console.log(response.request_id, response.agent_run_id, response.chat_id, response.terminal);
|
|
56
91
|
```
|
|
57
92
|
|
|
58
|
-
|
|
93
|
+
`externalId` is optional host-app mapping metadata. Use it for values your app
|
|
94
|
+
already understands, such as an event ID, support ticket ID, session ID,
|
|
95
|
+
project ID, or case ID.
|
|
96
|
+
|
|
97
|
+
When continuing an existing Skyforge chat, pass `chatId`:
|
|
59
98
|
|
|
60
99
|
```ts
|
|
61
|
-
|
|
62
|
-
agentBranchId:
|
|
63
|
-
chatId: "
|
|
64
|
-
|
|
100
|
+
await skyforge.agentBranches.sendMessage({
|
|
101
|
+
agentBranchId: process.env.SKYFORGE_AGENT_BRANCH_ID!,
|
|
102
|
+
chatId: "skyforge-chat-id",
|
|
103
|
+
externalId: "event_123",
|
|
104
|
+
message: "Summarize the current event status.",
|
|
65
105
|
structuredContext: {
|
|
66
|
-
|
|
106
|
+
weather: "windy",
|
|
67
107
|
},
|
|
68
108
|
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Skyforge may reject a request that tries to continue an existing `chatId` with a
|
|
112
|
+
different `externalId` than the chat already has.
|
|
113
|
+
|
|
114
|
+
Response fields mirror the Skyforge API payloads and use API field names such
|
|
115
|
+
as `chat_id`, `external_id`, `agent_branch_id`, and `pending_human_actions`.
|
|
116
|
+
|
|
117
|
+
Every turn is a durable worker-owned run, regardless of the branch's legacy
|
|
118
|
+
runtime mode. `terminal=false` means the HTTP delivery returned before
|
|
119
|
+
execution resolved; preserve `request_id`, `agent_run_id`, and `chat_id` for
|
|
120
|
+
lookup, event replay, and explicit cancellation. Delivery timeout or abort does
|
|
121
|
+
not fail or cancel the run.
|
|
122
|
+
|
|
123
|
+
## Request Recovery And Cancellation
|
|
124
|
+
|
|
125
|
+
Use one request ID for one immutable submission contract. An exact retry can
|
|
126
|
+
resolve to the existing run; changing delivery mode or semantic inputs returns
|
|
127
|
+
generic `409 request_id_conflict`.
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
const lookup = await skyforge.agentBranches.lookupRequest({
|
|
131
|
+
agentBranchId: process.env.SKYFORGE_AGENT_BRANCH_ID!,
|
|
132
|
+
requestId,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
if (!lookup.terminal) {
|
|
136
|
+
await skyforge.agentRuns.cancel({
|
|
137
|
+
agentRunId: lookup.agent_run_id,
|
|
138
|
+
reason: "User requested cancellation",
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Cancellation is cooperative. It prevents new provider/tool calls after the
|
|
144
|
+
worker observes the request, but cannot undo an already transmitted external
|
|
145
|
+
side effect. Do not translate client disconnect or an SDK `AbortSignal` into a
|
|
146
|
+
cancellation request.
|
|
147
|
+
|
|
148
|
+
## Recover Chats By External ID
|
|
149
|
+
|
|
150
|
+
Use `skyforge.chats.list(...)` from your backend to recover chats for an agent.
|
|
151
|
+
The lookup is agent-scoped and can be narrowed to one branch.
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
const { chats, nextCursor } = await skyforge.chats.list({
|
|
155
|
+
agentId: process.env.SKYFORGE_AGENT_ID!,
|
|
156
|
+
externalId: "event_123",
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
for (const chat of chats) {
|
|
160
|
+
console.log(chat.chat_id, chat.external_id, chat.agent_branch_name);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
console.log(nextCursor);
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
The SDK calls:
|
|
167
|
+
|
|
168
|
+
```text
|
|
169
|
+
GET /api/skyforge-chat/agents/{agent_id}/chats
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Supported query params are `agent_branch_id`, `chat_id`, `external_id`,
|
|
173
|
+
`limit`, and `cursor`. The raw API response field is `next_cursor`; the SDK
|
|
174
|
+
normalizes it to `nextCursor`.
|
|
175
|
+
|
|
176
|
+
List items include:
|
|
177
|
+
|
|
178
|
+
- `agent_id`
|
|
179
|
+
- `agent_branch_id`
|
|
180
|
+
- `agent_branch_name`
|
|
181
|
+
- `chat_id`
|
|
182
|
+
- `external_id`
|
|
183
|
+
- `chat_title`
|
|
184
|
+
- `created_at`
|
|
185
|
+
- `updated_at`
|
|
186
|
+
|
|
187
|
+
## Chat Lookup Examples
|
|
188
|
+
|
|
189
|
+
Find one known chat:
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
const { chats } = await skyforge.chats.list({
|
|
193
|
+
agentId: process.env.SKYFORGE_AGENT_ID!,
|
|
194
|
+
chatId: "skyforge-chat-id",
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const chat = chats[0];
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Narrow lookup to one branch:
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
const page = await skyforge.chats.list({
|
|
204
|
+
agentId: process.env.SKYFORGE_AGENT_ID!,
|
|
205
|
+
agentBranchId: process.env.SKYFORGE_AGENT_BRANCH_ID!,
|
|
206
|
+
externalId: "event_123",
|
|
207
|
+
limit: 20,
|
|
208
|
+
});
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Paginate through results:
|
|
69
212
|
|
|
70
|
-
|
|
213
|
+
```ts
|
|
214
|
+
let cursor: string | undefined;
|
|
215
|
+
|
|
216
|
+
do {
|
|
217
|
+
const page = await skyforge.chats.list({
|
|
218
|
+
agentId: process.env.SKYFORGE_AGENT_ID!,
|
|
219
|
+
externalId: "event_123",
|
|
220
|
+
cursor,
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
for (const chat of page.chats) {
|
|
224
|
+
// Render or store the chat mapping in your app.
|
|
225
|
+
console.log(chat.chat_id, chat.updated_at);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
cursor = page.nextCursor ?? undefined;
|
|
229
|
+
} while (cursor);
|
|
71
230
|
```
|
|
72
231
|
|
|
73
|
-
|
|
232
|
+
## Build a SaaS Chat History
|
|
233
|
+
|
|
234
|
+
Use `externalId` when your app already has a record that should own the
|
|
235
|
+
conversation, such as an event, ticket, project, or session. Your backend can
|
|
236
|
+
later call `skyforge.chats.list({ agentId, externalId })` to build a chat
|
|
237
|
+
history or resume-chat experience in your own product.
|
|
238
|
+
|
|
239
|
+
Skyforge provides the lookup primitive. Your SaaS app still owns the end-user
|
|
240
|
+
history UI, app-level permissions, and the decision about which `externalId` is
|
|
241
|
+
valid for the current user. Treat browser-provided external IDs as metadata,
|
|
242
|
+
not trusted identity.
|
|
243
|
+
|
|
244
|
+
The public [`Skyforge-AI/api-starter`](https://github.com/Skyforge-AI/api-starter)
|
|
245
|
+
uses `@runmark/sdk` on the backend and `@runmark/agent-chat` in the browser. To
|
|
246
|
+
add a chat-history UI to your own app, call `skyforge.chats.list(...)` from
|
|
247
|
+
your backend and pass the selected `chatId` to the chat component.
|
|
248
|
+
|
|
249
|
+
## Stream Run Events
|
|
74
250
|
|
|
75
251
|
```ts
|
|
76
252
|
const events = await skyforge.agentRuns.streamEvents({
|
|
77
|
-
agentRunId: "
|
|
78
|
-
afterSequence:
|
|
253
|
+
agentRunId: "agent-run-id",
|
|
254
|
+
afterSequence: 0,
|
|
79
255
|
});
|
|
80
256
|
|
|
81
257
|
for await (const event of events) {
|
|
@@ -83,26 +259,66 @@ for await (const event of events) {
|
|
|
83
259
|
}
|
|
84
260
|
```
|
|
85
261
|
|
|
86
|
-
Breaking out of the loop cancels the underlying
|
|
262
|
+
Breaking out of the loop cancels the underlying stream reader.
|
|
263
|
+
|
|
264
|
+
`afterSequence` is an explicit persisted replay cursor. The low-level SDK does
|
|
265
|
+
not run an infinite reconnect loop or deduplicate events for you; reconnect
|
|
266
|
+
with the last applied sequence and ignore duplicate sequence values in the
|
|
267
|
+
consumer. The parser supports CRLF/chunk boundaries and multiline data, rejects
|
|
268
|
+
malformed or oversized events, and always releases its reader.
|
|
269
|
+
|
|
270
|
+
## Source References
|
|
271
|
+
|
|
272
|
+
When Advanced RAG injects labeled sources into an answer, chat messages may
|
|
273
|
+
include `source_references`. These references are safe public metadata for the
|
|
274
|
+
labels visible in the assistant text, such as `[S1]`; they are not the hidden
|
|
275
|
+
RAG prompt or full source documents.
|
|
276
|
+
|
|
277
|
+
```ts
|
|
278
|
+
const reply = await skyforge.agentBranches.sendMessage({
|
|
279
|
+
agentBranchId: process.env.SKYFORGE_AGENT_BRANCH_ID!,
|
|
280
|
+
message: "What does Advanced RAG change?",
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
for (const message of reply.messages) {
|
|
284
|
+
for (const source of message.source_references ?? []) {
|
|
285
|
+
console.log(source.display_label, source.snippet, source.source_type);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
For run-based integrations, source references can also be loaded after the run
|
|
291
|
+
completes:
|
|
87
292
|
|
|
88
|
-
|
|
293
|
+
```ts
|
|
294
|
+
const { source_references } = await skyforge.agentRuns.getSourceReferences({
|
|
295
|
+
agentRunId: "agent-run-id",
|
|
296
|
+
});
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Match references by exact `source_label` or `display_label`, never by array
|
|
300
|
+
position. Source links are not part of the MVP source-reference contract.
|
|
301
|
+
|
|
302
|
+
## Submit a Human Action
|
|
89
303
|
|
|
90
304
|
```ts
|
|
91
305
|
await skyforge.humanActions.submit({
|
|
92
|
-
humanActionRequestId: "
|
|
306
|
+
humanActionRequestId: "human-action-request-id",
|
|
307
|
+
requestId: crypto.randomUUID(),
|
|
308
|
+
activeOrganizationId: "organization-id",
|
|
93
309
|
values: {
|
|
94
310
|
approved: true,
|
|
95
311
|
},
|
|
96
312
|
});
|
|
97
313
|
```
|
|
98
314
|
|
|
99
|
-
|
|
315
|
+
## Upload a Chat File
|
|
100
316
|
|
|
101
317
|
```ts
|
|
102
318
|
const upload = await skyforge.uploadedFiles.upload({
|
|
103
|
-
agentBranchId:
|
|
104
|
-
chatId: "
|
|
105
|
-
file: new
|
|
319
|
+
agentBranchId: process.env.SKYFORGE_AGENT_BRANCH_ID!,
|
|
320
|
+
chatId: "chat-id",
|
|
321
|
+
file: new Uint8Array([104, 101, 108, 108, 111]),
|
|
106
322
|
filename: "notes.txt",
|
|
107
323
|
contentType: "text/plain",
|
|
108
324
|
});
|
|
@@ -121,99 +337,107 @@ await skyforge.uploadedFiles.delete({
|
|
|
121
337
|
|
|
122
338
|
`filename` is required and must not be blank.
|
|
123
339
|
|
|
124
|
-
##
|
|
340
|
+
## Using With Express
|
|
125
341
|
|
|
126
|
-
|
|
342
|
+
Use your backend as the app proxy for browser chat requests. The browser calls
|
|
343
|
+
your server; your server calls Skyforge with the API token.
|
|
127
344
|
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
```
|
|
345
|
+
```ts
|
|
346
|
+
import express from "express";
|
|
347
|
+
import { SkyforgeClient } from "@runmark/sdk";
|
|
132
348
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
`Authorization: Bearer <skyforge_api_token>` through the existing
|
|
136
|
-
`/api/skyforge-chat/...` routes.
|
|
349
|
+
const app = express();
|
|
350
|
+
app.use(express.json());
|
|
137
351
|
|
|
138
|
-
|
|
139
|
-
|
|
352
|
+
const skyforge = new SkyforgeClient({
|
|
353
|
+
apiKey: process.env.SKYFORGE_API_TOKEN!,
|
|
354
|
+
baseUrl: process.env.SKYFORGE_API_BASE_URL ?? "https://api.skyforge.ai",
|
|
355
|
+
});
|
|
140
356
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
357
|
+
app.post("/api/skyforge-chat/agent_branches/:agentBranchId/messages", async (req, res, next) => {
|
|
358
|
+
try {
|
|
359
|
+
if (req.params.agentBranchId !== process.env.SKYFORGE_AGENT_BRANCH_ID) {
|
|
360
|
+
res.status(403).json({ error: { message: "Agent branch is not allowed." } });
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const data = await skyforge.agentBranches.sendMessage({
|
|
365
|
+
agentBranchId: req.params.agentBranchId,
|
|
366
|
+
chatId: req.body.chat_id,
|
|
367
|
+
externalId: req.session?.ticketId ?? req.body.external_id,
|
|
368
|
+
message: req.body.message,
|
|
369
|
+
structuredContext: req.body.structured_context,
|
|
370
|
+
retrievalScope: req.body.retrieval_scope,
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
res.json({ message: "ok", data });
|
|
374
|
+
} catch (error) {
|
|
375
|
+
next(error);
|
|
376
|
+
}
|
|
377
|
+
});
|
|
144
378
|
```
|
|
145
379
|
|
|
146
|
-
|
|
147
|
-
|
|
380
|
+
Backend proxies can supply or override `externalId` from trusted app context,
|
|
381
|
+
such as a signed-in user session, event, ticket, project, or case ID. Do not
|
|
382
|
+
treat browser-provided `external_id` as identity.
|
|
148
383
|
|
|
149
|
-
|
|
150
|
-
cd packages/skyforge-sdk
|
|
151
|
-
|
|
152
|
-
SKYFORGE_SDK_LIVE=1 \
|
|
153
|
-
SKYFORGE_API_BASE_URL=http://localhost:3000 \
|
|
154
|
-
SKYFORGE_API_TOKEN=... \
|
|
155
|
-
SKYFORGE_AGENT_BRANCH_ID=... \
|
|
156
|
-
npm run test:live
|
|
157
|
-
```
|
|
384
|
+
## Using With Next.js Route Handlers
|
|
158
385
|
|
|
159
|
-
|
|
386
|
+
```ts
|
|
387
|
+
import { NextResponse } from "next/server";
|
|
388
|
+
import { SkyforgeClient } from "@runmark/sdk";
|
|
160
389
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
390
|
+
const skyforge = new SkyforgeClient({
|
|
391
|
+
apiKey: process.env.SKYFORGE_API_TOKEN!,
|
|
392
|
+
baseUrl: process.env.SKYFORGE_API_BASE_URL ?? "https://api.skyforge.ai",
|
|
393
|
+
});
|
|
164
394
|
|
|
165
|
-
|
|
395
|
+
export async function POST(request: Request) {
|
|
396
|
+
const body = await request.json();
|
|
397
|
+
const data = await skyforge.agentBranches.sendMessage({
|
|
398
|
+
agentBranchId: process.env.SKYFORGE_AGENT_BRANCH_ID!,
|
|
399
|
+
chatId: body.chat_id,
|
|
400
|
+
externalId: body.external_id,
|
|
401
|
+
message: body.message,
|
|
402
|
+
});
|
|
166
403
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
SKYFORGE_SDK_LIVE_HITL_REQUEST_ID=...
|
|
170
|
-
SKYFORGE_SDK_LIVE_EXISTING_CHAT_ID=...
|
|
171
|
-
SKYFORGE_SDK_LIVE_TIMEOUT_MS=60000
|
|
172
|
-
SKYFORGE_SDK_LIVE_HITL_TIMEOUT_MS=120000
|
|
173
|
-
SKYFORGE_SDK_LIVE_EVENT_TIMEOUT_MS=15000
|
|
174
|
-
SKYFORGE_SDK_LIVE_MESSAGE="SDK live smoke test. Reply with a short confirmation."
|
|
175
|
-
SKYFORGE_SDK_LIVE_EXPECT_PENDING_HITL=1
|
|
176
|
-
SKYFORGE_SDK_LIVE_EXPECT_BUBBLED_HITL=1
|
|
177
|
-
SKYFORGE_SDK_LIVE_SUBMIT_PENDING_HITL=1
|
|
178
|
-
SKYFORGE_SDK_LIVE_HITL_VALUES='{"decision":"approve","notes":"Approved by SDK live test."}'
|
|
404
|
+
return NextResponse.json({ message: "ok", data });
|
|
405
|
+
}
|
|
179
406
|
```
|
|
180
407
|
|
|
181
|
-
|
|
408
|
+
## Error Handling
|
|
182
409
|
|
|
183
|
-
|
|
184
|
-
SDK package has a convenience live command for that seeded local fixture:
|
|
410
|
+
Non-2xx Skyforge API responses throw `SkyforgeApiError`.
|
|
185
411
|
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
412
|
+
```ts
|
|
413
|
+
import { SkyforgeApiError } from "@runmark/sdk";
|
|
414
|
+
|
|
415
|
+
try {
|
|
416
|
+
await skyforge.agentBranches.getState({
|
|
417
|
+
agentBranchId: process.env.SKYFORGE_AGENT_BRANCH_ID!,
|
|
418
|
+
});
|
|
419
|
+
} catch (error) {
|
|
420
|
+
if (error instanceof SkyforgeApiError) {
|
|
421
|
+
console.error(error.status, error.code, error.requestId);
|
|
422
|
+
}
|
|
423
|
+
throw error;
|
|
424
|
+
}
|
|
191
425
|
```
|
|
192
426
|
|
|
193
|
-
|
|
427
|
+
Avoid logging API tokens, authorization headers, or full request payloads.
|
|
194
428
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
429
|
+
Successful responses must be JSON envelopes with non-null `data`; malformed,
|
|
430
|
+
empty, wrong-content-type, or oversized responses are rejected rather than
|
|
431
|
+
cast to the requested type. Error bodies are bounded before parsing.
|
|
198
432
|
|
|
199
|
-
|
|
433
|
+
## Compatibility
|
|
200
434
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
SKYFORGE_SDK_LIVE_EXPECT_BUBBLED_HITL=1
|
|
211
|
-
SKYFORGE_SDK_LIVE_SUBMIT_PENDING_HITL=1
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
`SKYFORGE_API_TOKEN` is still required and is not set by the script. Use a valid
|
|
215
|
-
local API token with access to the seeded TailYew repository/branch. You can
|
|
216
|
-
override the base URL, branch ID, message, HITL values, or timeout by setting
|
|
217
|
-
the same environment variables before running the command.
|
|
218
|
-
|
|
219
|
-
Do not expose Skyforge API tokens in browser code. This SDK is server-side only.
|
|
435
|
+
The durable request-ID, lookup, cancellation, and HITL correlation APIs are
|
|
436
|
+
additive in `0.1.2`. Existing callers may omit request IDs, but embedded and
|
|
437
|
+
retry-sensitive integrations should supply them. The SDK remains server-only
|
|
438
|
+
and throws if constructed in a browser environment.
|
|
439
|
+
|
|
440
|
+
## Related Package
|
|
441
|
+
|
|
442
|
+
Use `@runmark/agent-chat` for the browser and React chat UI. Keep this SDK on
|
|
443
|
+
the backend and expose only the app-specific proxy routes your frontend needs.
|
package/dist/client.d.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import type { DeleteUploadedFileParams, GetAgentBranchStateParams, SendMessageParams, SkyforgeAgentRunEventEnvelope, SkyforgeChatMessageResponse, SkyforgeChatStateResponse, SkyforgeChatUploadedFileListResponse, SkyforgeChatUploadedFileUploadResponse, SkyforgeClientOptions, StreamAgentRunEventsParams, SubmitHumanActionParams, UploadFileParams
|
|
1
|
+
import type { CancelAgentRunParams, CancelAgentRunResponse, DeleteUploadedFileParams, GetAgentRunSourceReferencesParams, GetAgentBranchStateParams, ListChatsParams, ListUploadedFilesParams, LookupAgentRunRequestParams, SendMessageParams, SkyforgeAgentRunEventEnvelope, SkyforgeAgentRunRequestLookupResponse, SkyforgeChatSourceReferencesResponse, SkyforgeChatListResponse, SkyforgeChatMessageResponse, SkyforgeChatStateResponse, SkyforgeChatUploadedFileListResponse, SkyforgeChatUploadedFileUploadResponse, SkyforgeClientOptions, StreamAgentRunEventsParams, SubmitHumanActionParams, UploadFileParams } from "./types.js";
|
|
2
2
|
export declare class SkyforgeClient {
|
|
3
3
|
readonly agentBranches: {
|
|
4
4
|
getState: (params: GetAgentBranchStateParams) => Promise<SkyforgeChatStateResponse>;
|
|
5
5
|
sendMessage: (params: SendMessageParams) => Promise<SkyforgeChatMessageResponse>;
|
|
6
|
+
lookupRequest: (params: LookupAgentRunRequestParams) => Promise<SkyforgeAgentRunRequestLookupResponse>;
|
|
7
|
+
};
|
|
8
|
+
readonly chats: {
|
|
9
|
+
list: (params: ListChatsParams) => Promise<SkyforgeChatListResponse>;
|
|
6
10
|
};
|
|
7
11
|
readonly agentRuns: {
|
|
8
12
|
streamEvents: (params: StreamAgentRunEventsParams) => Promise<AsyncIterable<SkyforgeAgentRunEventEnvelope>>;
|
|
13
|
+
getSourceReferences: (params: GetAgentRunSourceReferencesParams) => Promise<SkyforgeChatSourceReferencesResponse>;
|
|
14
|
+
cancel: (params: CancelAgentRunParams) => Promise<CancelAgentRunResponse>;
|
|
9
15
|
};
|
|
10
16
|
readonly humanActions: {
|
|
11
17
|
submit: (params: SubmitHumanActionParams) => Promise<SkyforgeChatMessageResponse>;
|
|
@@ -19,8 +25,12 @@ export declare class SkyforgeClient {
|
|
|
19
25
|
private readonly http;
|
|
20
26
|
constructor(options: SkyforgeClientOptions);
|
|
21
27
|
private getAgentBranchState;
|
|
28
|
+
private listChats;
|
|
22
29
|
private sendMessage;
|
|
30
|
+
private lookupRequest;
|
|
23
31
|
private streamEvents;
|
|
32
|
+
private getSourceReferences;
|
|
33
|
+
private cancelAgentRun;
|
|
24
34
|
private submitHumanAction;
|
|
25
35
|
private listUploadedFiles;
|
|
26
36
|
private uploadFile;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACxB,iCAAiC,EACjC,yBAAyB,EACzB,eAAe,EACf,uBAAuB,EACvB,2BAA2B,EAC3B,iBAAiB,EACjB,6BAA6B,EAC7B,qCAAqC,EACrC,oCAAoC,EACpC,wBAAwB,EACxB,2BAA2B,EAC3B,yBAAyB,EACzB,oCAAoC,EACpC,sCAAsC,EACtC,qBAAqB,EAErB,0BAA0B,EAC1B,uBAAuB,EAEvB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AASpB,qBAAa,cAAc;IACzB,QAAQ,CAAC,aAAa,EAAE;QACtB,QAAQ,EAAE,CAAC,MAAM,EAAE,yBAAyB,KAAK,OAAO,CAAC,yBAAyB,CAAC,CAAC;QACpF,WAAW,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,OAAO,CAAC,2BAA2B,CAAC,CAAC;QACjF,aAAa,EAAE,CACb,MAAM,EAAE,2BAA2B,KAChC,OAAO,CAAC,qCAAqC,CAAC,CAAC;KACrD,CAAC;IACF,QAAQ,CAAC,KAAK,EAAE;QACd,IAAI,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAC,wBAAwB,CAAC,CAAC;KACtE,CAAC;IACF,QAAQ,CAAC,SAAS,EAAE;QAClB,YAAY,EAAE,CACZ,MAAM,EAAE,0BAA0B,KAC/B,OAAO,CAAC,aAAa,CAAC,6BAA6B,CAAC,CAAC,CAAC;QAC3D,mBAAmB,EAAE,CACnB,MAAM,EAAE,iCAAiC,KACtC,OAAO,CAAC,oCAAoC,CAAC,CAAC;QACnD,MAAM,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;KAC3E,CAAC;IACF,QAAQ,CAAC,YAAY,EAAE;QACrB,MAAM,EAAE,CAAC,MAAM,EAAE,uBAAuB,KAAK,OAAO,CAAC,2BAA2B,CAAC,CAAC;KACnF,CAAC;IACF,QAAQ,CAAC,aAAa,EAAE;QACtB,IAAI,EAAE,CAAC,MAAM,EAAE,uBAAuB,KAAK,OAAO,CAAC,oCAAoC,CAAC,CAAC;QACzF,MAAM,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,OAAO,CAAC,sCAAsC,CAAC,CAAC;QACtF,MAAM,EAAE,CAAC,MAAM,EAAE,wBAAwB,KAAK,OAAO,CAAC,oCAAoC,CAAC,CAAC;KAC7F,CAAC;IAEF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;gBAEtB,OAAO,EAAE,qBAAqB;IAyC1C,OAAO,CAAC,mBAAmB;YASb,SAAS;IAgBvB,OAAO,CAAC,WAAW;IAkBnB,OAAO,CAAC,aAAa;YASP,YAAY;IAU1B,OAAO,CAAC,mBAAmB;IAM3B,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,UAAU;IAmBlB,OAAO,CAAC,kBAAkB;CAa3B"}
|