mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:40:44 +00:00
fix: align SDK wait and protocol contracts
This commit is contained in:
@@ -1851,11 +1851,11 @@ public struct SessionsMessagesUnsubscribeParams: Codable, Sendable {
|
||||
}
|
||||
|
||||
public struct SessionsAbortParams: Codable, Sendable {
|
||||
public let key: String
|
||||
public let key: String?
|
||||
public let runid: String?
|
||||
|
||||
public init(
|
||||
key: String,
|
||||
key: String?,
|
||||
runid: String?)
|
||||
{
|
||||
self.key = key
|
||||
|
||||
@@ -1851,11 +1851,11 @@ public struct SessionsMessagesUnsubscribeParams: Codable, Sendable {
|
||||
}
|
||||
|
||||
public struct SessionsAbortParams: Codable, Sendable {
|
||||
public let key: String
|
||||
public let key: String?
|
||||
public let runid: String?
|
||||
|
||||
public init(
|
||||
key: String,
|
||||
key: String?,
|
||||
runid: String?)
|
||||
{
|
||||
self.key = key
|
||||
|
||||
@@ -146,7 +146,7 @@ have to parse `raw` for normal UI.
|
||||
```typescript
|
||||
type RunResult = {
|
||||
runId: string;
|
||||
status: "completed" | "failed" | "cancelled" | "timed_out";
|
||||
status: "accepted" | "completed" | "failed" | "cancelled" | "timed_out";
|
||||
sessionId?: string;
|
||||
sessionKey?: string;
|
||||
taskId?: string;
|
||||
@@ -172,6 +172,11 @@ shape, so current lifecycle-backed runs usually report epoch millisecond
|
||||
numbers while adapters may still surface ISO strings. Rich UI, tool traces, and
|
||||
runtime-native details belong in events and artifacts.
|
||||
|
||||
`accepted` is a non-terminal wait result: it means the Gateway wait deadline
|
||||
expired before the run produced a lifecycle end/error. It must not be treated as
|
||||
`timed_out`; `timed_out` is reserved for a run that exceeded its own runtime
|
||||
timeout.
|
||||
|
||||
## Approvals and questions
|
||||
|
||||
Approvals must be first-class because coding agents constantly cross safety
|
||||
|
||||
@@ -64,7 +64,13 @@ function runStatusFromWaitPayload(payload: unknown): RunResult["status"] {
|
||||
if (status === "ok" || status === "completed" || status === "succeeded") {
|
||||
return "completed";
|
||||
}
|
||||
if (status === "timeout" || status === "timed_out") {
|
||||
if (status === "timeout") {
|
||||
if (stopReason === "timeout" || stopReason === "timed_out" || record.aborted === true) {
|
||||
return "timed_out";
|
||||
}
|
||||
return "accepted";
|
||||
}
|
||||
if (status === "timed_out") {
|
||||
return "timed_out";
|
||||
}
|
||||
if (status === "accepted") {
|
||||
|
||||
@@ -136,6 +136,41 @@ describe("OpenClaw SDK", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps wait-only deadlines non-terminal", async () => {
|
||||
const transport = new FakeTransport({
|
||||
"agent.wait": { status: "timeout", runId: "run_still_active" },
|
||||
});
|
||||
const oc = new OpenClaw({ transport });
|
||||
|
||||
const result = await oc.runs.wait("run_still_active");
|
||||
|
||||
expect(result).toMatchObject({
|
||||
runId: "run_still_active",
|
||||
status: "accepted",
|
||||
});
|
||||
expect(result.error).toBeUndefined();
|
||||
});
|
||||
|
||||
it("maps terminal runtime timeout snapshots to timed_out", async () => {
|
||||
const transport = new FakeTransport({
|
||||
"agent.wait": {
|
||||
status: "timeout",
|
||||
runId: "run_timed_out",
|
||||
stopReason: "timeout",
|
||||
error: "agent runtime timeout",
|
||||
},
|
||||
});
|
||||
const oc = new OpenClaw({ transport });
|
||||
|
||||
const result = await oc.runs.wait("run_timed_out");
|
||||
|
||||
expect(result).toMatchObject({
|
||||
runId: "run_timed_out",
|
||||
status: "timed_out",
|
||||
error: { message: "agent runtime timeout" },
|
||||
});
|
||||
});
|
||||
|
||||
it("splits provider-qualified model refs and rejects unsupported run options", async () => {
|
||||
const transport = new FakeTransport({
|
||||
agent: { status: "accepted", runId: "run_openrouter" },
|
||||
|
||||
Reference in New Issue
Block a user