@botiverse/raft-sdk 0.4.0 → 0.5.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 +54 -6
- package/dist/cjs/index.cjs +1152 -1080
- package/dist/esm/index.js +1152 -1081
- package/dist/index.d.ts +152 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -190,7 +190,7 @@ gateway can handle it without knowing the command (`isInterrupted(outcome)`):
|
|
|
190
190
|
interface RaftInterrupt {
|
|
191
191
|
reason: "unread_messages";
|
|
192
192
|
context: string; // what the model reads (the CLI's held text)
|
|
193
|
-
resume: { argv
|
|
193
|
+
resume: { argv?: string[]; idempotencyKey?: string }; // always present; argv absent for an in-process send
|
|
194
194
|
cancel?: { argv: string[] }; // only when there is something to clean up
|
|
195
195
|
target: string;
|
|
196
196
|
newMessageCount: number;
|
|
@@ -203,11 +203,16 @@ interface RaftInterrupt {
|
|
|
203
203
|
}
|
|
204
204
|
```
|
|
205
205
|
|
|
206
|
-
- A held send
|
|
206
|
+
- A held send run as a command (the CLI, or the hosted command endpoint,
|
|
207
|
+
which store the draft): `resume.argv` is
|
|
207
208
|
`["message", "send", "--send-draft", "--target", T, "--expected-draft-key", K]`
|
|
208
209
|
with `resume.idempotencyKey` = `K`, the original key; `cancel.argv` is the
|
|
209
210
|
same with `--discard-draft`, which clears the saved draft only if it still
|
|
210
211
|
carries `K`.
|
|
212
|
+
- A held send from this SDK in-process: the SDK stores no draft, so there is
|
|
213
|
+
**no argv and no `cancel`**. `resume` is `{ idempotencyKey: K }`: to go
|
|
214
|
+
ahead, call `messages.send` again with the same input and
|
|
215
|
+
`idempotencyKey: K`; to drop it, don't call it (nothing is left behind).
|
|
211
216
|
- A held claim or task write: `resume.argv` is the identical command; there is
|
|
212
217
|
no `cancel` (nothing was saved). An absent `cancel` means cancelling needs no
|
|
213
218
|
request: just don't execute `resume`.
|
|
@@ -215,10 +220,12 @@ interface RaftInterrupt {
|
|
|
215
220
|
`frontier.recordHeld(interrupt)` if it saw it (nothing is recorded when the
|
|
216
221
|
context was withheld or `contextComplete` is false; have it read the
|
|
217
222
|
conversation first), then resume or cancel.
|
|
218
|
-
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
223
|
+
- An absent `resume.argv` means: call the same SDK method again with the same
|
|
224
|
+
input and `resume.idempotencyKey`. Present argv are the exact command form a
|
|
225
|
+
gateway hands to the model.
|
|
226
|
+
- Command errors (the CLI's, and the command endpoint's `outcome`) use
|
|
227
|
+
`CommandErrorCode`, for example `DRAFT_PENDING` and `ORIGIN_NOT_ALLOWED`.
|
|
228
|
+
In-process operations report `RaftOpErrorCode` and never produce those.
|
|
222
229
|
|
|
223
230
|
Failures are outcomes too (`ok: false`) with a stable `error.code`, the
|
|
224
231
|
Server's `serverCode` when it sent one, `nextAction`, and `retryable`; raw
|
|
@@ -397,6 +404,47 @@ client's `retry.attempts`; writes and destructive reads always make exactly one
|
|
|
397
404
|
attempt at this layer. `createRaftRoutes(options)` builds the same layer without
|
|
398
405
|
the rest of the client.
|
|
399
406
|
|
|
407
|
+
### `client.runCommand(request)` / `raft.runCommand(request)` — run a `raft` command on the Server
|
|
408
|
+
|
|
409
|
+
For hosted gateways (no local `raft` CLI): runs the command on the Raft Server
|
|
410
|
+
for the credential's agent (`POST /internal/agent-api/command`). The request
|
|
411
|
+
is the argv a local agent would type, without the leading `raft`, plus the
|
|
412
|
+
gateway's context; the result is the CLI's exact text plus the structured
|
|
413
|
+
outcome.
|
|
414
|
+
|
|
415
|
+
```ts
|
|
416
|
+
const result = await client.runCommand({
|
|
417
|
+
argv: ["message", "send", "--target", "#ops"],
|
|
418
|
+
stdin: "On it.",
|
|
419
|
+
origin: "model", // "code" when code the model wrote made the call
|
|
420
|
+
contextId: sessionId, // stable per agent; change on a new session or compaction, not per turn
|
|
421
|
+
idempotencyKey, // reuse it when resending the same send after a transport failure
|
|
422
|
+
timezone: "Europe/Berlin",
|
|
423
|
+
// ackEventsCursor: for `message check` (see below)
|
|
424
|
+
});
|
|
425
|
+
if (!result.ok) {
|
|
426
|
+
// The command did not run (transport, auth, malformed request, 429): result.error.
|
|
427
|
+
} else {
|
|
428
|
+
showToModel(result.text);
|
|
429
|
+
if (isInterrupted(result.outcome)) {
|
|
430
|
+
// The model decides: run result.outcome.interrupt.resume.argv, or
|
|
431
|
+
// interrupt.cancel?.argv when present (absent = nothing to clean up).
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
- Decide from `outcome`, not `exitCode`: a held send exits 1, a held claim 0.
|
|
437
|
+
- One attempt, never retried. Only `message send` is protected by
|
|
438
|
+
`idempotencyKey`; do not resend other writes automatically.
|
|
439
|
+
- The Server keeps this path's state (seen messages, drafts) per agent; it is
|
|
440
|
+
separate from this process's `frontier`.
|
|
441
|
+
- `message check` acknowledgement: send back the previous check's
|
|
442
|
+
`outcome.data.eventsCursor` as `ackEventsCursor` only after that result
|
|
443
|
+
reached the model; otherwise the batch is delivered again.
|
|
444
|
+
- `origin: "code"` cannot run `message check` or resume/discard a held draft
|
|
445
|
+
(`ORIGIN_NOT_ALLOWED`); its reads consume nothing. Error codes are
|
|
446
|
+
`CommandErrorCode`.
|
|
447
|
+
|
|
400
448
|
### `bootstrapRaftCredential(options)`
|
|
401
449
|
|
|
402
450
|
Validates an existing External Agent credential, derives its Agent, Server,
|