@ouispec/agent-realtime 0.4.0 → 0.7.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 CHANGED
@@ -64,6 +64,9 @@ All of them require the `x-api-key` header.
64
64
  | `POST /internal/approvals/redeem` `{ token, userId, conversationId }` | Atomic single use. `200 { call }` returns exactly the stored call. `403` for a token this environment did not sign, another user's or conversation's, or one not for the stored call; `410` for an expired or already used one. |
65
65
  | `GET /internal/approvals/:id?userId=` | Where an approval of this user's stands: `pending`, `approved` or `declined` (remembered for 30 minutes). |
66
66
  | `POST /internal/approvals/:id/settle` `{ userId, conversationId, confirm? }` | Whether an approval a conversation still shows as waiting expired with nobody deciding it. Always `200 { approvalId, outcome, expiresAt? }`: `claimed` (it expired without having run, and this caller holds the claim to store that, for two minutes; `decided: "approved"` when the user had approved it and it was never used), `already` (another turn holds the claim, or it is stored), `open` (pending, or approved and not yet used), `unknown` (declined, used, another user's or conversation's, or not remembered). With `confirm: true`, the caller has stored it and the claim becomes permanent: `confirmed`. |
67
+ | `POST /internal/approvals/:id/settle` `{ userId, conversationId, expire }` | Expires an approval now instead of at its time limit, saying why: `expire` is `superseded` (the user sent a new message while its card waited) or `stopped` (the turn that asked was stopped). `200 { approvalId, outcome }`: `withdrawn` (it was pending, or approved and not yet used, and is now gone: a decision is refused and its token answers `used`), `settled` (it had already ended), `unknown`. A later settle then answers `claimed` with `withdrawn: "superseded" \| "stopped"`. |
68
+ | `POST /internal/turns/:turnId/stop` `{ userId, reason }` | Asks that a turn stop, for its user: `reason` is `superseded` (a newer message runs instead) or `user_stop`. Your API calls it after checking the turn is the user's. `200 { ok, stop: "requested" \| "already", record }`; the first request stands. |
69
+ | `GET /internal/turns/:turnId/stop?userId=&waitMs=` | The stop asked for on a turn by its user, which the turn's worker holds open for as long as the turn runs. `200` carries `{ turnId, by, reason, at }`; `204` means none yet. A wait lasts at most 25 s. The record is kept 30 minutes. |
67
70
  | `GET /internal/events/settlements/:kind/:id?waitMs=` | How a job of a declared kind ended: `{ kind, role, event, id, payload }`, with `role` `completion` or `failure`. `204` means not yet; `400` an undeclared kind; `404` a server without `events`. A wait lasts at most 25 s. |
68
71
  | `GET /health` | Returns `200` with connection and pending-wait counts. No key needed. |
69
72
 
@@ -75,10 +78,22 @@ All of them require the `x-api-key` header.
75
78
 
76
79
  An approval nobody decides sends nothing when it expires, so a later turn settles it. The store remembers, for 30 days, that an approval was asked for and is still undecided; a decline or a redemption removes that memory in the same step. Once the approval's own keys have lapsed in Redis, `POST /internal/approvals/:id/settle` answers that it expired undecided, and gives the claim to store that to one caller at a time. Expiry is Redis's clock: neither this server's nor the caller's is consulted. Approvals stored before this memory existed are answered `unknown`.
77
80
 
81
+ An approval can also be withdrawn before its time is up (`settle` with `expire`): when the user sends a new message while its card waits, or the turn that asked for it is stopped. That is one script with the decision and the redemption, so exactly one of them happens. From then it is an expiry like any other, settled by a later turn, which is told why: it was withdrawn, not left to time out. One the user had approved keeps that they did.
82
+
78
83
  A declined approval is deleted and remembered for the next turn. Every issue, decision and redemption is logged with the approval id, user, tool, effect, channel and args hash. The arguments are logged only when their declaration marks them not sensitive, and a token never is.
79
84
 
80
85
  The token's claims are `aid sub cid tool ah eff ch iat exp jti`. `ah` is `argsHash(args)` from `@ouispec/agent-core`: SHA-256 over the RFC 8785 canonical JSON. The package ships `approval-vectors.json`, which every other implementation must match.
81
86
 
87
+ ## Stopping a turn
88
+
89
+ A person can stop a running turn, and a newer message supersedes one. The worker has no socket, so the server keeps the request and the worker asks for it:
90
+
91
+ 1. The tab sends `agent:turn_stop { turnId, room }` on the user's socket, where `room` is the turn's room. The server takes it only from a socket that is in the room it names, and only when that room is one your policy guards with a token.
92
+ 2. The stop is kept under the socket's verified user, and that is what makes it the owner's. A worker's wait is answered only with the stop of the user it asks for, which is its turn's own. The server keeps no record of who owns a turn and does not know which room is which turn's, so the room check does not prove the turn is the user's: a socket in any token-guarded room can write a stop for any turn id. It writes it under its own user, where no other user's worker reads it, and it cannot block the owner's.
93
+ 3. Your API asks the same way with `POST /internal/turns/:turnId/stop`, after its own check, when a new message arrives for a chat with a turn running.
94
+
95
+ The worker stores what the turn had produced and then emits `agent:turn_complete` with `stopReason`: `user_stop` or `superseded`.
96
+
82
97
  ## Example
83
98
 
84
99
  ```ts
@@ -9,7 +9,9 @@
9
9
  * POST /internal/approvals/redeem atomic single use (worker, engine)
10
10
  * GET /internal/approvals/:id?userId= where an approval stands (worker, for the turn after a decision)
11
11
  * POST /internal/approvals/:id/settle whether it expired undecided, claimed for one turn to store; with
12
- * `confirm`, that it has been stored (worker, at the start of a later turn)
12
+ * `confirm`, that it has been stored (worker, at the start of a later turn);
13
+ * with `expire`, expire it now, saying why (host, when a new message
14
+ * arrives; worker, when the turn that asked is stopped: ADR-0252 §2.6)
13
15
  */
14
16
  import { Router } from 'express';
15
17
  import type { ApprovalStore } from './store.js';
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/approvals/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,MAAM,EAA+B,MAAM,SAAS,CAAC;AAG9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,aAAa,CAAC;IACzB,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC;CAC3D;AAkBD,wBAAgB,cAAc,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CA6F9D"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/approvals/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,MAAM,EAA+B,MAAM,SAAS,CAAC;AAU9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,aAAa,CAAC;IACzB,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC;CAC3D;AAkBD,wBAAgB,cAAc,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAqG9D"}
@@ -9,9 +9,12 @@
9
9
  * POST /internal/approvals/redeem atomic single use (worker, engine)
10
10
  * GET /internal/approvals/:id?userId= where an approval stands (worker, for the turn after a decision)
11
11
  * POST /internal/approvals/:id/settle whether it expired undecided, claimed for one turn to store; with
12
- * `confirm`, that it has been stored (worker, at the start of a later turn)
12
+ * `confirm`, that it has been stored (worker, at the start of a later turn);
13
+ * with `expire`, expire it now, saying why (host, when a new message
14
+ * arrives; worker, when the turn that asked is stopped: ADR-0252 §2.6)
13
15
  */
14
16
  import { Router } from 'express';
17
+ import { APPROVAL_WITHDRAW_REASONS, } from '@ouispec/agent-core';
15
18
  import { internalDecideSchema, pendingApprovalSchema, redeemSchema } from './schemas.js';
16
19
  const DECIDE_STATUS = {
17
20
  unknown: 404,
@@ -97,6 +100,14 @@ export function approvalRouter(deps) {
97
100
  res.json({ approvalId, outcome: (await deps.approvals.confirmExpirySettled(approvalId, owner)) ? 'confirmed' : 'unknown' });
98
101
  return;
99
102
  }
103
+ if (body.expire !== undefined) {
104
+ if (!APPROVAL_WITHDRAW_REASONS.includes(body.expire)) {
105
+ res.status(400).json({ error: `expire must be one of ${APPROVAL_WITHDRAW_REASONS.join(', ')}` });
106
+ return;
107
+ }
108
+ res.json(await deps.approvals.withdraw(approvalId, owner, body.expire));
109
+ return;
110
+ }
100
111
  res.json(await deps.approvals.settleExpired(approvalId, owner));
101
112
  });
102
113
  router.get('/internal/approvals/:id', async (req, res) => {
@@ -1 +1 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/approvals/routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/approvals/routes.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { type ApprovalChannel, type ApprovalDecideResult, type ApprovalDecision, type ApprovalOwner, type ApprovalRedeemResult, type ApprovalRefusal, type ApprovalSettlement, type ApprovalStatus, type PendingApprovalInput } from '@ouispec/agent-core';
1
+ import { type ApprovalChannel, type ApprovalDecideResult, type ApprovalDecision, type ApprovalOwner, type ApprovalRedeemResult, type ApprovalRefusal, type ApprovalSettlement, type ApprovalStatus, type ApprovalWithdrawal, type ApprovalWithdrawReason, type PendingApprovalInput } from '@ouispec/agent-core';
2
2
  import type { RealtimeLogger } from '../logger.js';
3
3
  import type { ApprovalTokenSigner } from './token.js';
4
4
  /** The Redis command the store uses. ioredis satisfies it. */
@@ -36,6 +36,15 @@ export interface ApprovalStore {
36
36
  settleExpired(approvalId: string, owner: ApprovalOwner): Promise<ApprovalSettlement>;
37
37
  /** The claimed expiry is stored: the claim no longer lapses. False when the store does not know the approval as this owner's. */
38
38
  confirmExpirySettled(approvalId: string, owner: ApprovalOwner): Promise<boolean>;
39
+ /**
40
+ * Expire an approval now instead of at its time limit (ADR-0252 §2.6): the
41
+ * person sent a new message while its card waited, or the turn that asked
42
+ * was stopped. One script, with decide and redeem, so it cannot interleave
43
+ * with either: a pending approval, or an approved one not yet used, is gone
44
+ * from that moment, its memory kept with why. A later turn then settles it
45
+ * as any expiry (`settleExpired`), and is told it was withdrawn.
46
+ */
47
+ withdraw(approvalId: string, owner: ApprovalOwner, reason: ApprovalWithdrawReason): Promise<ApprovalWithdrawal>;
39
48
  }
40
49
  /** How long a decline is remembered for the turn that follows it. */
41
50
  export declare const DECLINED_TTL_SEC: number;
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/approvals/store.ts"],"names":[],"mappings":"AA6BA,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EAEpB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EAEnB,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1F;AAED,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,MAAM,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,eAAe,CAAC,CAAC;IACtI,sFAAsF;IACtF,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,gBAAgB,CAAC;QAAC,OAAO,EAAE,eAAe,CAAA;KAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACxI,8GAA8G;IAC9G,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACzG,2FAA2F;IAC3F,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC3E;;;;;;OAMG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACrF,iIAAiI;IACjI,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAClF;AAED,qEAAqE;AACrE,eAAO,MAAM,gBAAgB,QAAU,CAAC;AAoHxC,MAAM,WAAW,oBAAoB;IACnC,iHAAiH;IACjH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE,oBAAyB,GACjC,aAAa,CAwNf"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/approvals/store.ts"],"names":[],"mappings":"AA6BA,OAAO,EAML,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EAEpB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAE3B,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1F;AAED,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,MAAM,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,eAAe,CAAC,CAAC;IACtI,sFAAsF;IACtF,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,gBAAgB,CAAC;QAAC,OAAO,EAAE,eAAe,CAAA;KAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACxI,8GAA8G;IAC9G,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACzG,2FAA2F;IAC3F,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC3E;;;;;;OAMG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACrF,iIAAiI;IACjI,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACjF;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACjH;AAED,qEAAqE;AACrE,eAAO,MAAM,gBAAgB,QAAU,CAAC;AA2IxC,MAAM,WAAW,oBAAoB;IACnC,iHAAiH;IACjH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE,oBAAyB,GACjC,aAAa,CA8Of"}
@@ -27,7 +27,7 @@
27
27
  * exactly the one the user approved.
28
28
  */
29
29
  import crypto from 'node:crypto';
30
- import { argsHash as hashOf, EXPIRED_APPROVAL_MEMORY_MS, EXPIRY_CLAIM_LEASE_MS, MAX_APPROVAL_TTL_MS, } from '@ouispec/agent-core';
30
+ import { APPROVAL_WITHDRAW_REASONS, argsHash as hashOf, EXPIRED_APPROVAL_MEMORY_MS, EXPIRY_CLAIM_LEASE_MS, MAX_APPROVAL_TTL_MS, } from '@ouispec/agent-core';
31
31
  /** How long a decline is remembered for the turn that follows it. */
32
32
  export const DECLINED_TTL_SEC = 30 * 60;
33
33
  const recordKey = (id) => `approval:${id}`;
@@ -35,12 +35,13 @@ const stateKey = (id) => `approval:${id}:state`;
35
35
  const declinedKey = (id) => `approval:declined:${id}`;
36
36
  const seenKey = (id) => `approval:${id}:seen`;
37
37
  const settledKey = (id) => `approval:${id}:settled`;
38
- // KEYS: record, state, declined, seen, settled. ARGV: record JSON, ttl ms, userId, conversationId, tool, argsHash,
39
- // expiresAt, seen JSON, seen ttl ms.
40
- // A new approval supersedes an old decline under the same id, and an old expiry's settlement.
38
+ const withdrawnKey = (id) => `approval:${id}:withdrawn`;
39
+ // KEYS: record, state, declined, seen, settled, withdrawn. ARGV: record JSON, ttl ms, userId, conversationId, tool,
40
+ // argsHash, expiresAt, seen JSON, seen ttl ms.
41
+ // A new approval supersedes an old decline under the same id, an old expiry's settlement, and an old withdrawal.
41
42
  const CREATE = `
42
43
  if redis.call('EXISTS', KEYS[1]) == 1 or redis.call('EXISTS', KEYS[2]) == 1 then return 'exists' end
43
- redis.call('DEL', KEYS[3], KEYS[5])
44
+ redis.call('DEL', KEYS[3], KEYS[5], KEYS[6])
44
45
  redis.call('SET', KEYS[4], ARGV[8], 'PX', ARGV[9])
45
46
  redis.call('SET', KEYS[1], ARGV[1], 'PX', ARGV[2])
46
47
  redis.call('HSET', KEYS[2], 'status', 'pending', 'userId', ARGV[3], 'conversationId', ARGV[4], 'tool', ARGV[5], 'argsHash', ARGV[6], 'expiresAt', ARGV[7])
@@ -76,10 +77,30 @@ end
76
77
  local record = redis.call('GET', KEYS[2])
77
78
  redis.call('DEL', KEYS[1], KEYS[2], KEYS[3])
78
79
  return {'ok', record, s[7]}`;
79
- // KEYS: state, seen, settled. ARGV: userId, conversationId, lease ms.
80
+ // KEYS: state, record, seen, withdrawn. ARGV: userId, conversationId, reason.
81
+ // Expire-now. A pending approval, or an approved one not yet redeemed, loses its state and record,
82
+ // which is exactly what its time running out does: a decision is then refused, a token redeemed
83
+ // after it answers 'used', and SETTLE finds "state gone, seen present". The memory (seen) is left
84
+ // as it is, so one the person had approved still says 'approved'; why it was withdrawn is kept
85
+ // beside it for as long as the memory lasts.
86
+ const WITHDRAW = `
87
+ if redis.call('EXISTS', KEYS[1]) == 0 then
88
+ local seen = redis.call('GET', KEYS[3])
89
+ if not seen then return 'unknown' end
90
+ local m = cjson.decode(seen)
91
+ if m['userId'] ~= ARGV[1] or m['conversationId'] ~= ARGV[2] then return 'unknown' end
92
+ return 'settled'
93
+ end
94
+ local o = redis.call('HMGET', KEYS[1], 'userId', 'conversationId')
95
+ if o[1] ~= ARGV[1] or o[2] ~= ARGV[2] then return 'unknown' end
96
+ redis.call('DEL', KEYS[1], KEYS[2])
97
+ local left = redis.call('PTTL', KEYS[3])
98
+ if left > 0 then redis.call('SET', KEYS[4], ARGV[3], 'PX', left) end
99
+ return 'withdrawn'`;
100
+ // KEYS: state, seen, settled, withdrawn. ARGV: userId, conversationId, lease ms.
80
101
  // The approval's own keys lapse in Redis at its expiry, so "state gone, seen present" is this
81
102
  // server's Redis saying it expired undecided. The claim is one SET NX: exactly one caller gets it,
82
- // and it lapses unless confirmed.
103
+ // and it lapses unless confirmed. An approval that was withdrawn says why.
83
104
  const SETTLE = `
84
105
  if redis.call('EXISTS', KEYS[1]) == 1 then
85
106
  local o = redis.call('HMGET', KEYS[1], 'userId', 'conversationId')
@@ -90,8 +111,9 @@ local seen = redis.call('GET', KEYS[2])
90
111
  if not seen then return {'unknown'} end
91
112
  local m = cjson.decode(seen)
92
113
  if m['userId'] ~= ARGV[1] or m['conversationId'] ~= ARGV[2] then return {'unknown'} end
93
- if redis.call('SET', KEYS[3], 'lease', 'NX', 'PX', ARGV[3]) then return {'claimed', seen} end
94
- return {'already', seen}`;
114
+ local withdrawn = redis.call('GET', KEYS[4]) or ''
115
+ if redis.call('SET', KEYS[3], 'lease', 'NX', 'PX', ARGV[3]) then return {'claimed', seen, withdrawn} end
116
+ return {'already', seen, withdrawn}`;
95
117
  // KEYS: state, seen, settled. ARGV: userId, conversationId, memory ms.
96
118
  // The expiry is stored in the conversation: the claim stays for as long as the memory of the approval does.
97
119
  // A confirmation with no live claim (the lease lapsed while the host was storing) is still kept, and said.
@@ -168,7 +190,7 @@ export function createApprovalStore(redis, signer, logger, options = {}) {
168
190
  if (computed !== input.argsHash)
169
191
  return refusal('invalid', 'argsHash does not match the arguments');
170
192
  const seen = { userId: input.userId, conversationId: input.conversationId, expiresAt: input.expiresAt };
171
- const result = await redis.eval(CREATE, 5, recordKey(input.approvalId), stateKey(input.approvalId), declinedKey(input.approvalId), seenKey(input.approvalId), settledKey(input.approvalId), JSON.stringify(input), input.expiresAt - now, input.userId, input.conversationId, input.tool, input.argsHash, input.expiresAt, JSON.stringify(seen), input.expiresAt - now + EXPIRED_APPROVAL_MEMORY_MS);
193
+ const result = await redis.eval(CREATE, 6, recordKey(input.approvalId), stateKey(input.approvalId), declinedKey(input.approvalId), seenKey(input.approvalId), settledKey(input.approvalId), withdrawnKey(input.approvalId), JSON.stringify(input), input.expiresAt - now, input.userId, input.conversationId, input.tool, input.argsHash, input.expiresAt, JSON.stringify(seen), input.expiresAt - now + EXPIRED_APPROVAL_MEMORY_MS);
172
194
  if (result !== 'ok')
173
195
  return refusal('decided', `an approval ${input.approvalId} already exists`);
174
196
  logger.info(audit(input, { expiresAt: input.expiresAt }), 'Approval stored');
@@ -257,18 +279,25 @@ export function createApprovalStore(redis, signer, logger, options = {}) {
257
279
  return null;
258
280
  },
259
281
  async settleExpired(approvalId, { userId, conversationId }) {
260
- const [outcome, raw] = ((await redis.eval(SETTLE, 3, stateKey(approvalId), seenKey(approvalId), settledKey(approvalId), userId, conversationId, expiryClaimLeaseMs)) ?? []);
282
+ const [outcome, raw, why] = ((await redis.eval(SETTLE, 4, stateKey(approvalId), seenKey(approvalId), settledKey(approvalId), withdrawnKey(approvalId), userId, conversationId, expiryClaimLeaseMs)) ?? []);
261
283
  if (outcome === 'open')
262
284
  return { approvalId, outcome };
263
285
  if ((outcome === 'claimed' || outcome === 'already') && raw) {
264
286
  const { expiresAt, decided } = JSON.parse(raw);
287
+ const withdrawn = APPROVAL_WITHDRAW_REASONS.includes(why ?? '') ? why : null;
265
288
  if (outcome === 'claimed') {
266
- logger.info({ approvalId, userId, conversationId, expiresAt, decided: decided ?? null }, 'Approval expired without running: claimed for a turn to store');
289
+ logger.info({ approvalId, userId, conversationId, expiresAt, decided: decided ?? null, withdrawn }, 'Approval expired without running: claimed for a turn to store');
267
290
  }
268
- return { approvalId, outcome, expiresAt, ...(decided === 'approved' ? { decided } : {}) };
291
+ return { approvalId, outcome, expiresAt, ...(decided === 'approved' ? { decided } : {}), ...(withdrawn ? { withdrawn } : {}) };
269
292
  }
270
293
  return { approvalId, outcome: 'unknown' };
271
294
  },
295
+ async withdraw(approvalId, { userId, conversationId }, reason) {
296
+ const outcome = (await redis.eval(WITHDRAW, 4, stateKey(approvalId), recordKey(approvalId), seenKey(approvalId), withdrawnKey(approvalId), userId, conversationId, reason));
297
+ if (outcome === 'withdrawn')
298
+ logger.info({ approvalId, userId, conversationId, reason }, 'Approval withdrawn before it was used');
299
+ return { approvalId, outcome: outcome === 'withdrawn' || outcome === 'settled' ? outcome : 'unknown' };
300
+ },
272
301
  async confirmExpirySettled(approvalId, { userId, conversationId }) {
273
302
  const outcome = await redis.eval(CONFIRM, 3, stateKey(approvalId), seenKey(approvalId), settledKey(approvalId), userId, conversationId, EXPIRED_APPROVAL_MEMORY_MS);
274
303
  if (outcome === 'confirmed')
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/approvals/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/approvals/store.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -24,6 +24,10 @@ export type { OUIResultStore } from './oui/results.js';
24
24
  export type { ResultsRedis, ResultsSubscriber } from './redis-waits.js';
25
25
  export { createSettlementStore, SETTLEMENT_TTL_SEC } from './events/settlements.js';
26
26
  export type { SettlementStore } from './events/settlements.js';
27
+ export { createTurnStopStore, TURN_STOP_TTL_SEC } from './turns/stops.js';
28
+ export type { TurnStopStore } from './turns/stops.js';
29
+ export { createTurnStopEvent } from './turns/client-event.js';
30
+ export { turnStopsRouter, MAX_STOP_WAIT_MS } from './turns/routes.js';
27
31
  export { MAX_RESULT_WAIT_MS } from './http/routes.js';
28
32
  export { createConsoleLogger } from './logger.js';
29
33
  export type { RealtimeLogger } from './logger.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,YAAY,EACV,oBAAoB,EACpB,WAAW,EACX,UAAU,EACV,UAAU,EACV,SAAS,EACT,aAAa,EACb,WAAW,EACX,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACnF,YAAY,EACV,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,aAAa,EACb,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACzF,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC9F,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACpF,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7E,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC1F,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,YAAY,EACV,oBAAoB,EACpB,WAAW,EACX,UAAU,EACV,UAAU,EACV,SAAS,EACT,aAAa,EACb,WAAW,EACX,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACnF,YAAY,EACV,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,aAAa,EACb,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACzF,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC9F,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACpF,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7E,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC1F,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -17,6 +17,9 @@ export { createRoomTokenSigner, DEFAULT_ROOM_TOKEN_TTL_MS } from './rooms/room-t
17
17
  export { joinRefusal } from './rooms/join.js';
18
18
  export { createOUIResultStore, RESULT_TTL_SEC, FINAL_RESULT_TTL_SEC } from './oui/results.js';
19
19
  export { createSettlementStore, SETTLEMENT_TTL_SEC } from './events/settlements.js';
20
+ export { createTurnStopStore, TURN_STOP_TTL_SEC } from './turns/stops.js';
21
+ export { createTurnStopEvent } from './turns/client-event.js';
22
+ export { turnStopsRouter, MAX_STOP_WAIT_MS } from './turns/routes.js';
20
23
  export { MAX_RESULT_WAIT_MS } from './http/routes.js';
21
24
  export { createConsoleLogger } from './logger.js';
22
25
  export { createApprovalStore, DECLINED_TTL_SEC } from './approvals/store.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAaH,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAQnF,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAEzF,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAG9F,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAEpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7E,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAaH,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAQnF,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAEzF,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAG9F,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAEpF,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7E,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/server.d.ts CHANGED
@@ -13,6 +13,7 @@ import type { RealtimeServerConfig } from './types.js';
13
13
  import { type RoomTokenSigner } from './rooms/room-token.js';
14
14
  import { type OUIResultStore } from './oui/results.js';
15
15
  import { type ApprovalStore } from './approvals/store.js';
16
+ import { type TurnStopStore } from './turns/stops.js';
16
17
  import { type SettlementStore } from './events/settlements.js';
17
18
  export interface RealtimeServerInstance {
18
19
  io: Server;
@@ -27,6 +28,8 @@ export interface RealtimeServerInstance {
27
28
  approvals: ApprovalStore;
28
29
  /** Job settlements, when the server has event declarations. */
29
30
  settlements: SettlementStore | null;
31
+ /** Stop requests for turns (ADR-0252). */
32
+ stops: TurnStopStore;
30
33
  close(): Promise<void>;
31
34
  }
32
35
  export declare function createRealtimeServer(config: RealtimeServerConfig): Promise<RealtimeServerInstance>;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAGnC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAKvD,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACpF,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE7E,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI/E,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAWtF,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC;IACxB,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,UAAU,EAAE,eAAe,CAAC;IAC5B,kCAAkC;IAClC,OAAO,EAAE,cAAc,CAAC;IACxB,qCAAqC;IACrC,SAAS,EAAE,aAAa,CAAC;IACzB,+DAA+D;IAC/D,WAAW,EAAE,eAAe,GAAG,IAAI,CAAC;IACpC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAqBD,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAkIxG"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAGnC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAKvD,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACpF,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE7E,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAM3E,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAWtF,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC;IACxB,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,UAAU,EAAE,eAAe,CAAC;IAC5B,kCAAkC;IAClC,OAAO,EAAE,cAAc,CAAC;IACxB,qCAAqC;IACrC,SAAS,EAAE,aAAa,CAAC;IACzB,+DAA+D;IAC/D,WAAW,EAAE,eAAe,GAAG,IAAI,CAAC;IACpC,0CAA0C;IAC1C,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAqBD,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAsIxG"}
package/dist/server.js CHANGED
@@ -22,6 +22,9 @@ import { createRoomTokenSigner } from './rooms/room-token.js';
22
22
  import { createOUIResultStore } from './oui/results.js';
23
23
  import { createApprovalTokenSigner } from './approvals/token.js';
24
24
  import { createApprovalStore } from './approvals/store.js';
25
+ import { createTurnStopStore } from './turns/stops.js';
26
+ import { createTurnStopEvent } from './turns/client-event.js';
27
+ import { turnStopsRouter } from './turns/routes.js';
25
28
  import { createApprovalDecideEvent } from './approvals/client-event.js';
26
29
  import { approvalRouter } from './approvals/routes.js';
27
30
  import { createDeclaredEvents } from './events/declared.js';
@@ -70,6 +73,7 @@ export async function createRealtimeServer(config) {
70
73
  }
71
74
  const results = createOUIResultStore(pub, resultsSub, logger);
72
75
  const approvals = createApprovalStore(pub, approvalTokens, logger);
76
+ const stops = createTurnStopStore(pub, resultsSub, logger);
73
77
  const settlements = declared ? createSettlementStore(pub, resultsSub, logger) : null;
74
78
  const clientEvents = [
75
79
  ...createBuiltinClientEvents({
@@ -80,6 +84,7 @@ export async function createRealtimeServer(config) {
80
84
  results: () => results,
81
85
  }),
82
86
  createApprovalDecideEvent(() => approvals),
87
+ createTurnStopEvent(config.roomPolicy, () => stops),
83
88
  ...(config.clientEvents ?? []),
84
89
  ];
85
90
  assertUniqueClientEvents(clientEvents);
@@ -110,6 +115,7 @@ export async function createRealtimeServer(config) {
110
115
  app.use(ouiResultsRouter(deps));
111
116
  app.use(approvalRouter({ approvals, isInternalKey: deps.isInternalKey }));
112
117
  app.use(settlementsRouter(deps));
118
+ app.use(turnStopsRouter({ stops: () => stops, isInternalKey: deps.isInternalKey, logger }));
113
119
  // Authentication, once per socket, through the product's verifier.
114
120
  io.use(async (socket, next) => {
115
121
  const token = socket.handshake.auth?.token ||
@@ -159,6 +165,7 @@ export async function createRealtimeServer(config) {
159
165
  results,
160
166
  approvals,
161
167
  settlements,
168
+ stops,
162
169
  async close() {
163
170
  await new Promise((resolve) => io.close(() => resolve()));
164
171
  await Promise.all(redisClients.map((c) => c.quit().catch(() => c.disconnect())));
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { type ClientEvent } from '../client-events/chain.js';
2
+ import type { RoomPolicy } from '../types.js';
3
+ import type { TurnStopStore } from './stops.js';
4
+ export declare function createTurnStopEvent(roomPolicy: RoomPolicy, stops: () => TurnStopStore): ClientEvent;
5
+ //# sourceMappingURL=client-event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-event.d.ts","sourceRoot":"","sources":["../../src/turns/client-event.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAOhD,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,aAAa,GAAG,WAAW,CAqBnG"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * `agent:turn_stop` (ADR-0252 §2.1): the person's Stop, on their own
3
+ * authenticated socket.
4
+ *
5
+ * What makes a stop the owner's is the key it is kept under, not the room.
6
+ * Who is asking is the socket's verified identity, never one the payload
7
+ * names; the stop is kept under that user; and a turn's worker reads only the
8
+ * stop of its turn's own user. So a stop from anyone else is never heard, and
9
+ * cannot stand in the way of the owner's.
10
+ *
11
+ * The room check is narrower than it may look. The server does not know which
12
+ * room belongs to which turn (each host names its own), so it cannot check
13
+ * that `room` is this turn's. It checks only that the socket is in the room it
14
+ * names and that the room is one that needs a token. A socket in any
15
+ * token-guarded room can therefore write a stop for any turn id, but only
16
+ * under its own user, where no other user's worker will read it. The check
17
+ * keeps the event to sockets that hold a room token at all, and nothing more.
18
+ */
19
+ import Joi from 'joi';
20
+ import { TURN_STOP_EVENT } from '@ouispec/agent-core';
21
+ import { defineClientEvent } from '../client-events/chain.js';
22
+ const turnStopSchema = Joi.object({
23
+ turnId: Joi.string().min(1).max(128).required(),
24
+ room: Joi.string().min(1).max(200).required(),
25
+ });
26
+ export function createTurnStopEvent(roomPolicy, stops) {
27
+ return defineClientEvent({
28
+ name: TURN_STOP_EVENT,
29
+ schema: turnStopSchema,
30
+ maxBytes: 1024,
31
+ // A person presses Stop; a burst is a script.
32
+ rate: { perSecond: 2, burst: 5 },
33
+ authorize: ({ socket }, payload) => roomPolicy.isValidRoom(payload.room) && roomPolicy.requiresToken(payload.room) && socket.rooms.has(payload.room)
34
+ ? { ok: true }
35
+ : { ok: false, reason: `not in the turn's room` },
36
+ refusal: (reason) => ({
37
+ ok: false,
38
+ reason: reason === `not in the turn's room` ? 'not_in_turn_room' : 'invalid',
39
+ }),
40
+ handle: async ({ user }, payload, ack) => {
41
+ const { first } = await stops().request(payload.turnId, user.userId, 'user_stop');
42
+ const result = { ok: true, stop: first ? 'requested' : 'already' };
43
+ ack?.(result);
44
+ },
45
+ });
46
+ }
47
+ //# sourceMappingURL=client-event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-event.js","sourceRoot":"","sources":["../../src/turns/client-event.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,eAAe,EAA6C,MAAM,qBAAqB,CAAC;AACjG,OAAO,EAAE,iBAAiB,EAAoB,MAAM,2BAA2B,CAAC;AAIhF,MAAM,cAAc,GAAG,GAAG,CAAC,MAAM,CAAC;IAChC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAC/C,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;CAC9C,CAAC,CAAC;AAEH,MAAM,UAAU,mBAAmB,CAAC,UAAsB,EAAE,KAA0B;IACpF,OAAO,iBAAiB,CAAkB;QACxC,IAAI,EAAE,eAAe;QACrB,MAAM,EAAE,cAAc;QACtB,QAAQ,EAAE,IAAI;QACd,8CAA8C;QAC9C,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;QAChC,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,CACjC,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;YAC9G,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE;YACd,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,wBAAwB,EAAE;QACrD,OAAO,EAAE,CAAC,MAAM,EAAkB,EAAE,CAAC,CAAC;YACpC,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,MAAM,KAAK,wBAAwB,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,SAAS;SAC7E,CAAC;QACF,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE;YACvC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,KAAK,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YAClF,MAAM,MAAM,GAAmB,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;YACnF,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;QAChB,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The worker's and the host's side of a turn stop (ADR-0252 §2.1). Both need
3
+ * the internal API key.
4
+ *
5
+ * POST /internal/turns/:turnId/stop { userId, reason }
6
+ * The host asks, for its user, that a turn stop: a newer message supersedes
7
+ * it, a chat is being deleted, or the tab could not reach its socket. The
8
+ * host has checked that the turn is `userId`'s.
9
+ * 200 — { ok: true, stop: 'requested' | 'already', record }
10
+ * 400 — userId missing, or reason not one of the stop reasons
11
+ *
12
+ * GET /internal/turns/:turnId/stop?userId=&waitMs=
13
+ * The stop asked for on a turn by its user, waiting up to `waitMs` (capped
14
+ * at 25 s) for one. A worker holds this open for the life of its turn.
15
+ * 200 — the TurnStopRecord
16
+ * 204 — no stop yet; ask again
17
+ * 400 — userId missing or waitMs invalid
18
+ *
19
+ * Both: 401 without the key, 503 while the store is not connected.
20
+ */
21
+ import { Router } from 'express';
22
+ import type { RealtimeLogger } from '../logger.js';
23
+ import type { TurnStopStore } from './stops.js';
24
+ /** The longest one request waits for a stop. The worker asks again. */
25
+ export declare const MAX_STOP_WAIT_MS = 25000;
26
+ export interface TurnStopRouteDeps {
27
+ /** Null until Redis is connected. */
28
+ stops: () => TurnStopStore | null;
29
+ isInternalKey: (presented: string | undefined) => boolean;
30
+ logger: RealtimeLogger;
31
+ }
32
+ export declare function turnStopsRouter(deps: TurnStopRouteDeps): Router;
33
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/turns/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,MAAM,EAA+B,MAAM,SAAS,CAAC;AAE9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,uEAAuE;AACvE,eAAO,MAAM,gBAAgB,QAAS,CAAC;AAEvC,MAAM,WAAW,iBAAiB;IAChC,qCAAqC;IACrC,KAAK,EAAE,MAAM,aAAa,GAAG,IAAI,CAAC;IAClC,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC;IAC1D,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAgE/D"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * The worker's and the host's side of a turn stop (ADR-0252 §2.1). Both need
3
+ * the internal API key.
4
+ *
5
+ * POST /internal/turns/:turnId/stop { userId, reason }
6
+ * The host asks, for its user, that a turn stop: a newer message supersedes
7
+ * it, a chat is being deleted, or the tab could not reach its socket. The
8
+ * host has checked that the turn is `userId`'s.
9
+ * 200 — { ok: true, stop: 'requested' | 'already', record }
10
+ * 400 — userId missing, or reason not one of the stop reasons
11
+ *
12
+ * GET /internal/turns/:turnId/stop?userId=&waitMs=
13
+ * The stop asked for on a turn by its user, waiting up to `waitMs` (capped
14
+ * at 25 s) for one. A worker holds this open for the life of its turn.
15
+ * 200 — the TurnStopRecord
16
+ * 204 — no stop yet; ask again
17
+ * 400 — userId missing or waitMs invalid
18
+ *
19
+ * Both: 401 without the key, 503 while the store is not connected.
20
+ */
21
+ import { Router } from 'express';
22
+ import { isTurnStopReason } from '@ouispec/agent-core';
23
+ /** The longest one request waits for a stop. The worker asks again. */
24
+ export const MAX_STOP_WAIT_MS = 25_000;
25
+ export function turnStopsRouter(deps) {
26
+ const router = Router();
27
+ /** The store, or null after answering why the request cannot be served. */
28
+ function storeFor(req, res) {
29
+ if (!deps.isInternalKey(req.headers['x-api-key'])) {
30
+ res.status(401).json({ error: 'Invalid or missing API key' });
31
+ return null;
32
+ }
33
+ const store = deps.stops();
34
+ if (!store)
35
+ res.status(503).json({ error: 'Turn stop store not connected' });
36
+ return store;
37
+ }
38
+ router.post('/internal/turns/:turnId/stop', async (req, res) => {
39
+ const store = storeFor(req, res);
40
+ if (!store)
41
+ return;
42
+ const turnId = req.params.turnId;
43
+ const { userId, reason } = (req.body ?? {});
44
+ if (typeof userId !== 'string' || !userId) {
45
+ res.status(400).json({ error: 'userId is required' });
46
+ return;
47
+ }
48
+ if (!isTurnStopReason(reason)) {
49
+ res.status(400).json({ error: 'reason must be user_stop or superseded' });
50
+ return;
51
+ }
52
+ try {
53
+ const { record, first } = await store.request(turnId, userId, reason);
54
+ res.json({ ok: true, stop: first ? 'requested' : 'already', record });
55
+ }
56
+ catch (err) {
57
+ deps.logger.error({ err, turnId, userId }, 'Turn stop request failed');
58
+ res.status(500).json({ error: 'Turn stop request failed' });
59
+ }
60
+ });
61
+ router.get('/internal/turns/:turnId/stop', async (req, res) => {
62
+ const store = storeFor(req, res);
63
+ if (!store)
64
+ return;
65
+ const turnId = req.params.turnId;
66
+ const userId = typeof req.query.userId === 'string' ? req.query.userId : '';
67
+ const waitMs = req.query.waitMs === undefined ? 0 : Number(req.query.waitMs);
68
+ if (!userId) {
69
+ res.status(400).json({ error: 'userId is required' });
70
+ return;
71
+ }
72
+ if (!Number.isFinite(waitMs) || waitMs < 0) {
73
+ res.status(400).json({ error: 'waitMs must be a non-negative number' });
74
+ return;
75
+ }
76
+ try {
77
+ const record = await store.await(turnId, userId, Math.min(waitMs, MAX_STOP_WAIT_MS));
78
+ if (!record) {
79
+ res.status(204).end();
80
+ return;
81
+ }
82
+ res.json(record);
83
+ }
84
+ catch (err) {
85
+ deps.logger.error({ err, turnId, userId }, 'Turn stop lookup failed');
86
+ res.status(500).json({ error: 'Turn stop lookup failed' });
87
+ }
88
+ });
89
+ return router;
90
+ }
91
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/turns/routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Stop requests for agent turns, held for the worker that runs the turn
3
+ * (ADR-0252 §2.1).
4
+ *
5
+ * The worker has no socket. A stop is written here, by the user's own socket
6
+ * or by the host's API, and the worker asks for it for as long as its turn
7
+ * runs. The request may arrive on one instance and the worker's wait be
8
+ * served by another, so both meet in Redis:
9
+ *
10
+ * turn:stop:{turnId}:{userId} → JSON TurnStopRecord, TTL 30 min, the first request stands
11
+ * channel turn:stops → `{turnId}:{userId}`, published when a stop is stored
12
+ *
13
+ * A stop is kept under the user who asked, and a wait is answered only with
14
+ * the stop of the user it asks for. The server keeps no record of who owns a
15
+ * turn, so this is what makes a stop the owner's: the worker asks for its
16
+ * turn's own user, and nobody else's request is ever read. One user's stop for
17
+ * another user's turn is a record nobody waits on.
18
+ *
19
+ * The record outlives any turn: a worker that starts late, or whose wait
20
+ * failed and was retried, still hears it.
21
+ */
22
+ import { type TurnStopReason, type TurnStopRecord } from '@ouispec/agent-core';
23
+ import type { RealtimeLogger } from '../logger.js';
24
+ import { type ResultsRedis, type ResultsSubscriber } from '../redis-waits.js';
25
+ export interface TurnStopStore {
26
+ /**
27
+ * Record that `userId` asks for `turnId` to stop. The first request stands:
28
+ * a later one changes nothing and gets the first back, with `first: false`.
29
+ */
30
+ request(turnId: string, userId: string, reason: TurnStopReason): Promise<{
31
+ record: TurnStopRecord;
32
+ first: boolean;
33
+ }>;
34
+ /** The stop `userId` asked for on `turnId`, waiting up to `waitMs` for one. */
35
+ await(turnId: string, userId: string, waitMs: number): Promise<TurnStopRecord | null>;
36
+ /** Waits in progress on this instance. */
37
+ pendingCount(): number;
38
+ }
39
+ export declare const TURN_STOP_TTL_SEC: number;
40
+ export declare function createTurnStopStore(redis: ResultsRedis, subscriber: ResultsSubscriber, logger: RealtimeLogger): TurnStopStore;
41
+ //# sourceMappingURL=stops.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stops.d.ts","sourceRoot":"","sources":["../../src/turns/stops.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAA2B,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAiB,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE7F,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,cAAc,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACrH,+EAA+E;IAC/E,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACtF,0CAA0C;IAC1C,YAAY,IAAI,MAAM,CAAC;CACxB;AAGD,eAAO,MAAM,iBAAiB,QAA4C,CAAC;AAK3E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,EAAE,cAAc,GAAG,aAAa,CA+B7H"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Stop requests for agent turns, held for the worker that runs the turn
3
+ * (ADR-0252 §2.1).
4
+ *
5
+ * The worker has no socket. A stop is written here, by the user's own socket
6
+ * or by the host's API, and the worker asks for it for as long as its turn
7
+ * runs. The request may arrive on one instance and the worker's wait be
8
+ * served by another, so both meet in Redis:
9
+ *
10
+ * turn:stop:{turnId}:{userId} → JSON TurnStopRecord, TTL 30 min, the first request stands
11
+ * channel turn:stops → `{turnId}:{userId}`, published when a stop is stored
12
+ *
13
+ * A stop is kept under the user who asked, and a wait is answered only with
14
+ * the stop of the user it asks for. The server keeps no record of who owns a
15
+ * turn, so this is what makes a stop the owner's: the worker asks for its
16
+ * turn's own user, and nobody else's request is ever read. One user's stop for
17
+ * another user's turn is a record nobody waits on.
18
+ *
19
+ * The record outlives any turn: a worker that starts late, or whose wait
20
+ * failed and was retried, still hears it.
21
+ */
22
+ import { TURN_STOP_RECORD_TTL_MS } from '@ouispec/agent-core';
23
+ import { createWaitHub } from '../redis-waits.js';
24
+ const CHANNEL = 'turn:stops';
25
+ export const TURN_STOP_TTL_SEC = Math.ceil(TURN_STOP_RECORD_TTL_MS / 1000);
26
+ const waitId = (turnId, userId) => `${turnId}:${userId}`;
27
+ const stopKey = (turnId, userId) => `turn:stop:${waitId(turnId, userId)}`;
28
+ export function createTurnStopStore(redis, subscriber, logger) {
29
+ const hub = createWaitHub(subscriber, CHANNEL, logger, 'Turn stops');
30
+ async function read(turnId, userId) {
31
+ const raw = await redis.get(stopKey(turnId, userId));
32
+ return raw ? JSON.parse(raw) : null;
33
+ }
34
+ return {
35
+ async request(turnId, userId, reason) {
36
+ const record = { turnId, by: userId, reason, at: Date.now() };
37
+ const written = await redis.set(stopKey(turnId, userId), JSON.stringify(record), 'EX', TURN_STOP_TTL_SEC, 'NX');
38
+ if (written !== 'OK') {
39
+ const held = await read(turnId, userId);
40
+ // Expired between the two commands: nothing stands, so this one does on a second try.
41
+ if (!held)
42
+ return this.request(turnId, userId, reason);
43
+ return { record: held, first: false };
44
+ }
45
+ await redis.publish(CHANNEL, waitId(turnId, userId));
46
+ logger.info({ turnId, userId, reason }, 'Turn stop requested');
47
+ return { record, first: true };
48
+ },
49
+ async await(turnId, userId, waitMs) {
50
+ return hub.wait(waitId(turnId, userId), waitMs, () => read(turnId, userId), (err) => logger.error({ err, turnId }, 'Turn stop read failed'));
51
+ },
52
+ pendingCount: () => hub.pendingCount(),
53
+ };
54
+ }
55
+ //# sourceMappingURL=stops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stops.js","sourceRoot":"","sources":["../../src/turns/stops.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,uBAAuB,EAA4C,MAAM,qBAAqB,CAAC;AAExG,OAAO,EAAE,aAAa,EAA6C,MAAM,mBAAmB,CAAC;AAc7F,MAAM,OAAO,GAAG,YAAY,CAAC;AAC7B,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;AAE3E,MAAM,MAAM,GAAG,CAAC,MAAc,EAAE,MAAc,EAAE,EAAE,CAAC,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;AACzE,MAAM,OAAO,GAAG,CAAC,MAAc,EAAE,MAAc,EAAE,EAAE,CAAC,aAAa,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;AAE1F,MAAM,UAAU,mBAAmB,CAAC,KAAmB,EAAE,UAA6B,EAAE,MAAsB;IAC5G,MAAM,GAAG,GAAG,aAAa,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IAErE,KAAK,UAAU,IAAI,CAAC,MAAc,EAAE,MAAc;QAChD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACrD,OAAO,GAAG,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1D,CAAC;IAED,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM;YAClC,MAAM,MAAM,GAAmB,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAC9E,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,CAAC,CAAC;YAChH,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBACxC,sFAAsF;gBACtF,IAAI,CAAC,IAAI;oBAAE,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;gBACvD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YACxC,CAAC;YACD,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC;YAC/D,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACjC,CAAC;QAED,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM;YAChC,OAAO,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAClF,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,uBAAuB,CAAC,CACvD,CAAC;QACJ,CAAC;QAED,YAAY,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,YAAY,EAAE;KACvC,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouispec/agent-realtime",
3
- "version": "0.4.0",
3
+ "version": "0.7.0",
4
4
  "description": "Realtime server for agent turns and UI actions — declared client events, room tokens, the UI action result store, the approval store, declared product events and their job settlements, Redis fan-out; the product supplies auth, room policy and keys",
5
5
  "homepage": "https://github.com/wesreid/oui/tree/main/packages/agent-realtime#readme",
6
6
  "bugs": {
@@ -37,9 +37,9 @@
37
37
  "ioredis": "^5.6.0",
38
38
  "joi": "^17.13.3",
39
39
  "socket.io": "^4.8.0",
40
- "@ouispec/agent-core": "^0.4.0",
41
- "@ouispec/agent-events": "^0.2.2",
42
- "oui-spec": "^0.8.0"
40
+ "@ouispec/agent-core": "^0.7.0",
41
+ "@ouispec/agent-events": "^0.7.0",
42
+ "oui-spec": "^0.10.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/cors": "^2.8.0",