@tai42/api-client 23.0.0 → 24.0.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.
Files changed (37) hide show
  1. package/dist/client/conversations-client.d.ts +190 -20
  2. package/dist/client/conversations-client.d.ts.map +1 -1
  3. package/dist/client/index.d.ts +194 -24
  4. package/dist/client/index.d.ts.map +1 -1
  5. package/dist/client/states-client.d.ts +2 -2
  6. package/dist/client/tools-client.d.ts +2 -2
  7. package/dist/generated/api-routes.d.ts +12 -0
  8. package/dist/generated/api-routes.d.ts.map +1 -1
  9. package/dist/generated/api-routes.js +3 -0
  10. package/dist/generated/api-routes.js.map +1 -1
  11. package/dist/generated/openapi-schemas.d.ts +1070 -52
  12. package/dist/generated/openapi-schemas.d.ts.map +1 -1
  13. package/dist/generated/openapi-schemas.js +24 -11
  14. package/dist/generated/openapi-schemas.js.map +1 -1
  15. package/dist/generated/served-schemas.d.ts +535 -72
  16. package/dist/generated/served-schemas.d.ts.map +1 -1
  17. package/dist/generated/served-schemas.js +501 -80
  18. package/dist/generated/served-schemas.js.map +1 -1
  19. package/dist/schemas/conversations.d.ts +360 -23
  20. package/dist/schemas/conversations.d.ts.map +1 -1
  21. package/dist/schemas/conversations.js +24 -9
  22. package/dist/schemas/conversations.js.map +1 -1
  23. package/dist/schemas/interactions.d.ts +47 -9
  24. package/dist/schemas/interactions.d.ts.map +1 -1
  25. package/dist/schemas/interactions.js +28 -7
  26. package/dist/schemas/interactions.js.map +1 -1
  27. package/dist/schemas/served.d.ts +492 -70
  28. package/dist/schemas/served.d.ts.map +1 -1
  29. package/dist/schemas/states.d.ts +4 -4
  30. package/dist/schemas/tools.d.ts +4 -4
  31. package/dist/tool-runs.d.ts +2 -2
  32. package/package.json +1 -1
  33. package/src/generated/api-routes.ts +3 -0
  34. package/src/generated/openapi-schemas.ts +44 -11
  35. package/src/generated/served-schemas.ts +503 -80
  36. package/src/schemas/conversations.ts +24 -9
  37. package/src/schemas/interactions.ts +28 -7
@@ -9,11 +9,12 @@ import { z } from 'zod';
9
9
  import { templatedText } from '../templated-text';
10
10
  export const accessPolicy = z.object({ "condition": templatedText.nullable().default(null), "policy_data": z.record(z.string(), z.unknown()).default({}), "scopes": z.array(z.string()).default([]) });
11
11
  export const overlapPolicy = z.object({ "deliver": z.enum(["one", "all"]).default("one"), "running": z.enum(["continue", "cancel"]).default("continue"), "settle_seconds": z.number().int().gte(0).lte(30).default(0) });
12
- export const apiConversationRoute = z.object({ "callback_secret": z.string().nullable().default(null), "callback_url": z.string().regex(new RegExp("^[hH][tT][tT][pP][sS]://[^/?#@]+(?:[/?#]|$)")).nullable().default(null), "cancel_expr": templatedText.nullable().default(null), "channel": z.null().default(null), "door": z.literal("api"), "error_reply_text": z.string().regex(new RegExp("\\S")).min(1).max(2000).nullable().default(null), "execution_key": z.string().min(1), "execution_key_fingerprint": z.string().min(1), "extras_expr": templatedText.nullable().default(null), "initial_mode": z.enum(["agent", "manual"]).default("agent"), "locale": z.string().nullable().default(null), "our_identity": z.null().default(null), "overlap": overlapPolicy.default({ "deliver": "one", "running": "continue", "settle_seconds": 0 }), "reply_expr": templatedText.nullable().default(null), "resume_expr": templatedText.nullable().default(null), "route_name": z.string().regex(new RegExp("^[a-z0-9-]+$")), "start_expr": templatedText.nullable().default(null), "target_kind": z.enum(["agent", "tool"]), "target_name": z.string().min(1), "turns_per_hour_override": z.number().int().gt(0).nullable().default(null) });
13
- export const apiConversationRouteCreate = z.object({ "callback_url": z.string().regex(new RegExp("^[hH][tT][tT][pP][sS]://[^/?#@]+(?:[/?#]|$)")).nullable().default(null), "cancel_expr": templatedText.nullable().default(null), "channel": z.null().default(null), "door": z.literal("api"), "error_reply_text": z.string().regex(new RegExp("\\S")).min(1).max(2000).nullable().default(null), "execution_key": z.string().min(1), "extras_expr": templatedText.nullable().default(null), "initial_mode": z.enum(["agent", "manual"]).default("agent"), "locale": z.string().nullable().default(null), "our_identity": z.null().default(null), "overlap": overlapPolicy.default({ "deliver": "one", "running": "continue", "settle_seconds": 0 }), "reply_expr": templatedText.nullable().default(null), "resume_expr": templatedText.nullable().default(null), "route_name": z.string().regex(new RegExp("^[a-z0-9-]+$")), "start_expr": templatedText.nullable().default(null), "target_kind": z.enum(["agent", "tool"]), "target_name": z.string().min(1), "turns_per_hour_override": z.number().int().gt(0).nullable().default(null) });
12
+ export const replyTexts = z.object({ "error": z.string().regex(new RegExp("\\S")).min(1).max(2000).nullable().default(null), "pairing_code": z.string().regex(new RegExp("\\S")).min(1).max(2000).nullable().default(null), "pairing_code_invalid": z.string().regex(new RegExp("\\S")).min(1).max(2000).nullable().default(null), "pairing_link_unavailable": z.string().regex(new RegExp("\\S")).min(1).max(2000).nullable().default(null), "pairing_linked": z.string().regex(new RegExp("\\S")).min(1).max(2000).nullable().default(null), "pairing_not_linked": z.string().regex(new RegExp("\\S")).min(1).max(2000).nullable().default(null), "pairing_unlink_unavailable": z.string().regex(new RegExp("\\S")).min(1).max(2000).nullable().default(null), "pairing_unlinked": z.string().regex(new RegExp("\\S")).min(1).max(2000).nullable().default(null), "rejected_could_not_receive": z.string().regex(new RegExp("\\S")).min(1).max(2000).nullable().default(null), "rejected_too_large": z.string().regex(new RegExp("\\S")).min(1).max(2000).nullable().default(null), "rejected_unsupported_type": z.string().regex(new RegExp("\\S")).min(1).max(2000).nullable().default(null), "slow_down": z.string().regex(new RegExp("\\S")).min(1).max(2000).nullable().default(null) }).strict();
13
+ export const apiConversationRoute = z.object({ "callback_secret": z.string().nullable().default(null), "callback_url": z.string().regex(new RegExp("^[hH][tT][tT][pP][sS]://[^/?#@]+(?:[/?#]|$)")).nullable().default(null), "cancel_expr": templatedText.nullable().default(null), "channel": z.null().default(null), "door": z.literal("api"), "execution_key": z.string().min(1), "execution_key_fingerprint": z.string().min(1), "extras_expr": templatedText.nullable().default(null), "initial_mode": z.enum(["agent", "manual"]).default("agent"), "locale": z.string().nullable().default(null), "our_identity": z.null().default(null), "overlap": overlapPolicy.default({ "deliver": "one", "running": "continue", "settle_seconds": 0 }), "reply_expr": templatedText.nullable().default(null), "reply_texts": replyTexts.nullable().default(null), "resume_expr": templatedText.nullable().default(null), "route_name": z.string().regex(new RegExp("^[a-z0-9-]+$")), "start_expr": templatedText.nullable().default(null), "target_kind": z.enum(["agent", "tool"]), "target_name": z.string().min(1), "turns_per_hour_override": z.number().int().gt(0).nullable().default(null) });
14
+ export const apiConversationRouteCreate = z.object({ "callback_url": z.string().regex(new RegExp("^[hH][tT][tT][pP][sS]://[^/?#@]+(?:[/?#]|$)")).nullable().default(null), "cancel_expr": templatedText.nullable().default(null), "channel": z.null().default(null), "door": z.literal("api"), "execution_key": z.string().min(1), "extras_expr": templatedText.nullable().default(null), "initial_mode": z.enum(["agent", "manual"]).default("agent"), "locale": z.string().nullable().default(null), "our_identity": z.null().default(null), "overlap": overlapPolicy.default({ "deliver": "one", "running": "continue", "settle_seconds": 0 }), "reply_expr": templatedText.nullable().default(null), "reply_texts": replyTexts.nullable().default(null), "resume_expr": templatedText.nullable().default(null), "route_name": z.string().regex(new RegExp("^[a-z0-9-]+$")), "start_expr": templatedText.nullable().default(null), "target_kind": z.enum(["agent", "tool"]), "target_name": z.string().min(1), "turns_per_hour_override": z.number().int().gt(0).nullable().default(null) });
14
15
  export const callbackSchema = z.object({ "carried_kwargs": z.record(z.string(), z.unknown()).default({}), "condition": templatedText.nullable().default(null), "expr": templatedText.nullable().default(null), "tool": z.string().default("") });
15
- export const channelConversationRoute = z.object({ "callback_secret": z.null().default(null), "callback_url": z.null().default(null), "cancel_expr": templatedText.nullable().default(null), "channel": z.string().regex(new RegExp("^[^:]*[^:\\s][^:]*$")), "door": z.literal("channel"), "error_reply_text": z.string().regex(new RegExp("\\S")).min(1).max(2000).nullable().default(null), "execution_key": z.string().min(1), "execution_key_fingerprint": z.string().min(1), "extras_expr": templatedText.nullable().default(null), "initial_mode": z.enum(["agent", "manual"]).default("agent"), "locale": z.string().nullable().default(null), "our_identity": z.string().regex(new RegExp("\\S")), "overlap": overlapPolicy.default({ "deliver": "one", "running": "continue", "settle_seconds": 0 }), "reply_expr": templatedText.nullable().default(null), "resume_expr": templatedText.nullable().default(null), "route_name": z.string().regex(new RegExp("^[a-z0-9-]+$")), "start_expr": templatedText.nullable().default(null), "target_kind": z.enum(["agent", "tool"]), "target_name": z.string().min(1), "turns_per_hour_override": z.number().int().gt(0).nullable().default(null) });
16
- export const channelConversationRouteCreate = z.object({ "callback_url": z.null().default(null), "cancel_expr": templatedText.nullable().default(null), "channel": z.string().regex(new RegExp("^[^:]*[^:\\s][^:]*$")), "door": z.literal("channel"), "error_reply_text": z.string().regex(new RegExp("\\S")).min(1).max(2000).nullable().default(null), "execution_key": z.string().min(1), "extras_expr": templatedText.nullable().default(null), "initial_mode": z.enum(["agent", "manual"]).default("agent"), "locale": z.string().nullable().default(null), "our_identity": z.string().regex(new RegExp("\\S")), "overlap": overlapPolicy.default({ "deliver": "one", "running": "continue", "settle_seconds": 0 }), "reply_expr": templatedText.nullable().default(null), "resume_expr": templatedText.nullable().default(null), "route_name": z.string().regex(new RegExp("^[a-z0-9-]+$")), "start_expr": templatedText.nullable().default(null), "target_kind": z.enum(["agent", "tool"]), "target_name": z.string().min(1), "turns_per_hour_override": z.number().int().gt(0).nullable().default(null) });
16
+ export const channelConversationRoute = z.object({ "callback_secret": z.null().default(null), "callback_url": z.null().default(null), "cancel_expr": templatedText.nullable().default(null), "channel": z.string().regex(new RegExp("^[^:]*[^:\\s][^:]*$")), "door": z.literal("channel"), "execution_key": z.string().min(1), "execution_key_fingerprint": z.string().min(1), "extras_expr": templatedText.nullable().default(null), "initial_mode": z.enum(["agent", "manual"]).default("agent"), "locale": z.string().nullable().default(null), "our_identity": z.string().regex(new RegExp("\\S")), "overlap": overlapPolicy.default({ "deliver": "one", "running": "continue", "settle_seconds": 0 }), "reply_expr": templatedText.nullable().default(null), "reply_texts": replyTexts.nullable().default(null), "resume_expr": templatedText.nullable().default(null), "route_name": z.string().regex(new RegExp("^[a-z0-9-]+$")), "start_expr": templatedText.nullable().default(null), "target_kind": z.enum(["agent", "tool"]), "target_name": z.string().min(1), "turns_per_hour_override": z.number().int().gt(0).nullable().default(null) });
17
+ export const channelConversationRouteCreate = z.object({ "callback_url": z.null().default(null), "cancel_expr": templatedText.nullable().default(null), "channel": z.string().regex(new RegExp("^[^:]*[^:\\s][^:]*$")), "door": z.literal("channel"), "execution_key": z.string().min(1), "extras_expr": templatedText.nullable().default(null), "initial_mode": z.enum(["agent", "manual"]).default("agent"), "locale": z.string().nullable().default(null), "our_identity": z.string().regex(new RegExp("\\S")), "overlap": overlapPolicy.default({ "deliver": "one", "running": "continue", "settle_seconds": 0 }), "reply_expr": templatedText.nullable().default(null), "reply_texts": replyTexts.nullable().default(null), "resume_expr": templatedText.nullable().default(null), "route_name": z.string().regex(new RegExp("^[a-z0-9-]+$")), "start_expr": templatedText.nullable().default(null), "target_kind": z.enum(["agent", "tool"]), "target_name": z.string().min(1), "turns_per_hour_override": z.number().int().gt(0).nullable().default(null) });
17
18
  export const channelTemplate = z.object({ "language": z.string(), "name": z.string(), "parameters": z.record(z.string(), z.unknown()).nullable().default(null) }).strict();
18
19
  export const conversationRoute = z.discriminatedUnion("door", [apiConversationRoute, channelConversationRoute]);
19
20
  export const conversationRouteCreate = z.discriminatedUnion("door", [apiConversationRouteCreate, channelConversationRouteCreate]);
@@ -473,21 +474,6 @@ export const servedDocumentsJson = {
473
474
  "title": "Door",
474
475
  "type": "string"
475
476
  },
476
- "error_reply_text": {
477
- "anyOf": [
478
- {
479
- "maxLength": 2000,
480
- "minLength": 1,
481
- "pattern": "\\S",
482
- "type": "string"
483
- },
484
- {
485
- "type": "null"
486
- }
487
- ],
488
- "default": null,
489
- "title": "Error Reply Text"
490
- },
491
477
  "execution_key": {
492
478
  "description": "The api-key ``user_id`` the turn runs AS; its live stored grants authorize the agent run or tool dispatch and every tool call the turn makes.",
493
479
  "minLength": 1,
@@ -587,14 +573,25 @@ export const servedDocumentsJson = {
587
573
  "returns": "the reply: null (silent), a string, or a list of answer parts",
588
574
  "variables": [
589
575
  {
590
- "blurb": "the turn ids and subject this reply answers ({id, inbound, subject}); null when an out-of-band delivery's originating record has aged out",
576
+ "blurb": "the turn this reply answers ({id, inbound, subject, reply_window}); reply_window {state, closes_at} is read when the turn starts, or at delivery for a late reply: open until closes_at, closed, or none; null when an out-of-band delivery's originating record has aged out",
591
577
  "name": "turn",
592
578
  "sample": {
593
579
  "id": "m-1",
594
580
  "inbound": {
595
581
  "id": "i-1",
596
582
  "kind": "message",
597
- "source": "api"
583
+ "source": "chat-line"
584
+ },
585
+ "reply_window": {
586
+ "closes_at": "2026-01-02T09:30:00Z",
587
+ "state": "open"
588
+ },
589
+ "subject": {
590
+ "locale": null,
591
+ "person": null,
592
+ "target_kind": "agent",
593
+ "target_name": "assistant",
594
+ "thread": "t-1"
598
595
  }
599
596
  }
600
597
  },
@@ -629,6 +626,17 @@ export const servedDocumentsJson = {
629
626
  ]
630
627
  }
631
628
  },
629
+ "reply_texts": {
630
+ "anyOf": [
631
+ {
632
+ "$ref": "#/$defs/ReplyTexts"
633
+ },
634
+ {
635
+ "type": "null"
636
+ }
637
+ ],
638
+ "default": null
639
+ },
632
640
  "resume_expr": {
633
641
  "anyOf": [
634
642
  {
@@ -736,7 +744,11 @@ export const servedDocumentsJson = {
736
744
  "name": "location"
737
745
  },
738
746
  {
739
- "gloss": "overlap deliver=all: the batch carried into this turn, in acceptance order, each {id, text, accepted_at} (+ form/form_tag/attachments/location when that message carried them)",
747
+ "gloss": "the earlier message this one replies to, {message_id, status, text}; present only when the inbound quoted one",
748
+ "name": "reply_to"
749
+ },
750
+ {
751
+ "gloss": "overlap deliver=all: the batch carried into this turn, in acceptance order, each {id, text, accepted_at} (+ form/form_tag/attachments/location/reply_to when that message carried them)",
740
752
  "name": "messages"
741
753
  },
742
754
  {
@@ -744,7 +756,7 @@ export const servedDocumentsJson = {
744
756
  "name": "superseded"
745
757
  },
746
758
  {
747
- "gloss": "the turn ids: {id, inbound: {id, kind, source}}",
759
+ "gloss": "the turn: {id, inbound: {id, kind, source}, subject: {target_kind, target_name, person, thread, locale}, reply_window: {state, closes_at}}; reply_window.state is open (a free-form reply is allowed until closes_at), closed, or none (no window on this channel or address)",
748
760
  "name": "turn"
749
761
  },
750
762
  {
@@ -873,21 +885,6 @@ export const servedDocumentsJson = {
873
885
  "title": "Door",
874
886
  "type": "string"
875
887
  },
876
- "error_reply_text": {
877
- "anyOf": [
878
- {
879
- "maxLength": 2000,
880
- "minLength": 1,
881
- "pattern": "\\S",
882
- "type": "string"
883
- },
884
- {
885
- "type": "null"
886
- }
887
- ],
888
- "default": null,
889
- "title": "Error Reply Text"
890
- },
891
888
  "execution_key": {
892
889
  "description": "The api-key ``user_id`` the turn runs AS; its live stored grants authorize the agent run or tool dispatch and every tool call the turn makes.",
893
890
  "minLength": 1,
@@ -987,14 +984,25 @@ export const servedDocumentsJson = {
987
984
  "returns": "the reply: null (silent), a string, or a list of answer parts",
988
985
  "variables": [
989
986
  {
990
- "blurb": "the turn ids and subject this reply answers ({id, inbound, subject}); null when an out-of-band delivery's originating record has aged out",
987
+ "blurb": "the turn this reply answers ({id, inbound, subject, reply_window}); reply_window {state, closes_at} is read when the turn starts, or at delivery for a late reply: open until closes_at, closed, or none; null when an out-of-band delivery's originating record has aged out",
991
988
  "name": "turn",
992
989
  "sample": {
993
990
  "id": "m-1",
994
991
  "inbound": {
995
992
  "id": "i-1",
996
993
  "kind": "message",
997
- "source": "api"
994
+ "source": "chat-line"
995
+ },
996
+ "reply_window": {
997
+ "closes_at": "2026-01-02T09:30:00Z",
998
+ "state": "open"
999
+ },
1000
+ "subject": {
1001
+ "locale": null,
1002
+ "person": null,
1003
+ "target_kind": "agent",
1004
+ "target_name": "assistant",
1005
+ "thread": "t-1"
998
1006
  }
999
1007
  }
1000
1008
  },
@@ -1029,6 +1037,17 @@ export const servedDocumentsJson = {
1029
1037
  ]
1030
1038
  }
1031
1039
  },
1040
+ "reply_texts": {
1041
+ "anyOf": [
1042
+ {
1043
+ "$ref": "#/$defs/ReplyTexts"
1044
+ },
1045
+ {
1046
+ "type": "null"
1047
+ }
1048
+ ],
1049
+ "default": null
1050
+ },
1032
1051
  "resume_expr": {
1033
1052
  "anyOf": [
1034
1053
  {
@@ -1136,7 +1155,11 @@ export const servedDocumentsJson = {
1136
1155
  "name": "location"
1137
1156
  },
1138
1157
  {
1139
- "gloss": "overlap deliver=all: the batch carried into this turn, in acceptance order, each {id, text, accepted_at} (+ form/form_tag/attachments/location when that message carried them)",
1158
+ "gloss": "the earlier message this one replies to, {message_id, status, text}; present only when the inbound quoted one",
1159
+ "name": "reply_to"
1160
+ },
1161
+ {
1162
+ "gloss": "overlap deliver=all: the batch carried into this turn, in acceptance order, each {id, text, accepted_at} (+ form/form_tag/attachments/location/reply_to when that message carried them)",
1140
1163
  "name": "messages"
1141
1164
  },
1142
1165
  {
@@ -1144,7 +1167,7 @@ export const servedDocumentsJson = {
1144
1167
  "name": "superseded"
1145
1168
  },
1146
1169
  {
1147
- "gloss": "the turn ids: {id, inbound: {id, kind, source}}",
1170
+ "gloss": "the turn: {id, inbound: {id, kind, source}, subject: {target_kind, target_name, person, thread, locale}, reply_window: {state, closes_at}}; reply_window.state is open (a free-form reply is allowed until closes_at), closed, or none (no window on this channel or address)",
1148
1171
  "name": "turn"
1149
1172
  },
1150
1173
  {
@@ -1249,6 +1272,194 @@ export const servedDocumentsJson = {
1249
1272
  "title": "OverlapPolicy",
1250
1273
  "type": "object"
1251
1274
  },
1275
+ "ReplyTexts": {
1276
+ "additionalProperties": false,
1277
+ "description": "The caller's words for the platform's fixed participant replies on one route. Frozen, strict keys.\n\n``error`` is sent when a turn fails and the target gave no reply; ``slow_down`` when an address\nis over the turn cap; ``pairing_linked`` when a pair code was redeemed and the two persons\nmerged; ``pairing_unlinked`` when ``/unlink`` detached the address; ``pairing_not_linked`` when\n``/unlink`` came from an address linked to nothing; ``pairing_code_invalid`` when a redeem was\nrefused; ``pairing_code`` is the ``/link`` reply carrying the fresh code, a template that MUST\nreference ``{pairing_code}`` and may reference ``{expires_at}`` (the code's ISO-8601 expiry),\nwith no conversion or format spec; ``pairing_link_unavailable`` when a redeem met a person being\nerased (its code is consumed, so the reply asks for a new one); ``pairing_unlink_unavailable``\nwhen ``/unlink`` met the sender's person being erased; ``rejected_unsupported_type`` / ``rejected_too_large`` /\n``rejected_could_not_receive`` are the notices for an inbound message the channel cannot\nbridge, a file over the cap, and a file the channel could not fetch. Every member but\n``pairing_code`` is literal text: a ``{`` in it is drawn as written. Each is a\n:data:`~tai42_contract.interactions.ReplyText` in the line's language; absent, the built-in\nEnglish reply is sent. An empty catalogue names nothing and is refused; an unknown key is\nrefused.",
1278
+ "properties": {
1279
+ "error": {
1280
+ "anyOf": [
1281
+ {
1282
+ "maxLength": 2000,
1283
+ "minLength": 1,
1284
+ "pattern": "\\S",
1285
+ "type": "string"
1286
+ },
1287
+ {
1288
+ "type": "null"
1289
+ }
1290
+ ],
1291
+ "default": null,
1292
+ "title": "Error"
1293
+ },
1294
+ "pairing_code": {
1295
+ "anyOf": [
1296
+ {
1297
+ "maxLength": 2000,
1298
+ "minLength": 1,
1299
+ "pattern": "\\S",
1300
+ "type": "string"
1301
+ },
1302
+ {
1303
+ "type": "null"
1304
+ }
1305
+ ],
1306
+ "default": null,
1307
+ "title": "Pairing Code"
1308
+ },
1309
+ "pairing_code_invalid": {
1310
+ "anyOf": [
1311
+ {
1312
+ "maxLength": 2000,
1313
+ "minLength": 1,
1314
+ "pattern": "\\S",
1315
+ "type": "string"
1316
+ },
1317
+ {
1318
+ "type": "null"
1319
+ }
1320
+ ],
1321
+ "default": null,
1322
+ "title": "Pairing Code Invalid"
1323
+ },
1324
+ "pairing_link_unavailable": {
1325
+ "anyOf": [
1326
+ {
1327
+ "maxLength": 2000,
1328
+ "minLength": 1,
1329
+ "pattern": "\\S",
1330
+ "type": "string"
1331
+ },
1332
+ {
1333
+ "type": "null"
1334
+ }
1335
+ ],
1336
+ "default": null,
1337
+ "title": "Pairing Link Unavailable"
1338
+ },
1339
+ "pairing_linked": {
1340
+ "anyOf": [
1341
+ {
1342
+ "maxLength": 2000,
1343
+ "minLength": 1,
1344
+ "pattern": "\\S",
1345
+ "type": "string"
1346
+ },
1347
+ {
1348
+ "type": "null"
1349
+ }
1350
+ ],
1351
+ "default": null,
1352
+ "title": "Pairing Linked"
1353
+ },
1354
+ "pairing_not_linked": {
1355
+ "anyOf": [
1356
+ {
1357
+ "maxLength": 2000,
1358
+ "minLength": 1,
1359
+ "pattern": "\\S",
1360
+ "type": "string"
1361
+ },
1362
+ {
1363
+ "type": "null"
1364
+ }
1365
+ ],
1366
+ "default": null,
1367
+ "title": "Pairing Not Linked"
1368
+ },
1369
+ "pairing_unlink_unavailable": {
1370
+ "anyOf": [
1371
+ {
1372
+ "maxLength": 2000,
1373
+ "minLength": 1,
1374
+ "pattern": "\\S",
1375
+ "type": "string"
1376
+ },
1377
+ {
1378
+ "type": "null"
1379
+ }
1380
+ ],
1381
+ "default": null,
1382
+ "title": "Pairing Unlink Unavailable"
1383
+ },
1384
+ "pairing_unlinked": {
1385
+ "anyOf": [
1386
+ {
1387
+ "maxLength": 2000,
1388
+ "minLength": 1,
1389
+ "pattern": "\\S",
1390
+ "type": "string"
1391
+ },
1392
+ {
1393
+ "type": "null"
1394
+ }
1395
+ ],
1396
+ "default": null,
1397
+ "title": "Pairing Unlinked"
1398
+ },
1399
+ "rejected_could_not_receive": {
1400
+ "anyOf": [
1401
+ {
1402
+ "maxLength": 2000,
1403
+ "minLength": 1,
1404
+ "pattern": "\\S",
1405
+ "type": "string"
1406
+ },
1407
+ {
1408
+ "type": "null"
1409
+ }
1410
+ ],
1411
+ "default": null,
1412
+ "title": "Rejected Could Not Receive"
1413
+ },
1414
+ "rejected_too_large": {
1415
+ "anyOf": [
1416
+ {
1417
+ "maxLength": 2000,
1418
+ "minLength": 1,
1419
+ "pattern": "\\S",
1420
+ "type": "string"
1421
+ },
1422
+ {
1423
+ "type": "null"
1424
+ }
1425
+ ],
1426
+ "default": null,
1427
+ "title": "Rejected Too Large"
1428
+ },
1429
+ "rejected_unsupported_type": {
1430
+ "anyOf": [
1431
+ {
1432
+ "maxLength": 2000,
1433
+ "minLength": 1,
1434
+ "pattern": "\\S",
1435
+ "type": "string"
1436
+ },
1437
+ {
1438
+ "type": "null"
1439
+ }
1440
+ ],
1441
+ "default": null,
1442
+ "title": "Rejected Unsupported Type"
1443
+ },
1444
+ "slow_down": {
1445
+ "anyOf": [
1446
+ {
1447
+ "maxLength": 2000,
1448
+ "minLength": 1,
1449
+ "pattern": "\\S",
1450
+ "type": "string"
1451
+ },
1452
+ {
1453
+ "type": "null"
1454
+ }
1455
+ ],
1456
+ "default": null,
1457
+ "title": "Slow Down"
1458
+ }
1459
+ },
1460
+ "title": "ReplyTexts",
1461
+ "type": "object"
1462
+ },
1252
1463
  "TemplatedText": {
1253
1464
  "additionalProperties": false,
1254
1465
  "description": "A renderable text: its source plus the parameters its render takes.\n\nEXACTLY ONE source is set — ``content`` (the text inline) or ``id`` (the id of a\nstored resource holding the text); neither and both are refused at construction.\n``kwargs`` are the render parameters for the TEXT and apply either way, so moving a\ntext from inline to stored (or back) leaves its parameters untouched.",
@@ -1372,21 +1583,6 @@ export const servedDocumentsJson = {
1372
1583
  "title": "Door",
1373
1584
  "type": "string"
1374
1585
  },
1375
- "error_reply_text": {
1376
- "anyOf": [
1377
- {
1378
- "maxLength": 2000,
1379
- "minLength": 1,
1380
- "pattern": "\\S",
1381
- "type": "string"
1382
- },
1383
- {
1384
- "type": "null"
1385
- }
1386
- ],
1387
- "default": null,
1388
- "title": "Error Reply Text"
1389
- },
1390
1586
  "execution_key": {
1391
1587
  "description": "The api-key ``user_id`` the turn runs AS; its live stored grants authorize the agent run or tool dispatch and every tool call the turn makes.",
1392
1588
  "minLength": 1,
@@ -1480,14 +1676,25 @@ export const servedDocumentsJson = {
1480
1676
  "returns": "the reply: null (silent), a string, or a list of answer parts",
1481
1677
  "variables": [
1482
1678
  {
1483
- "blurb": "the turn ids and subject this reply answers ({id, inbound, subject}); null when an out-of-band delivery's originating record has aged out",
1679
+ "blurb": "the turn this reply answers ({id, inbound, subject, reply_window}); reply_window {state, closes_at} is read when the turn starts, or at delivery for a late reply: open until closes_at, closed, or none; null when an out-of-band delivery's originating record has aged out",
1484
1680
  "name": "turn",
1485
1681
  "sample": {
1486
1682
  "id": "m-1",
1487
1683
  "inbound": {
1488
1684
  "id": "i-1",
1489
1685
  "kind": "message",
1490
- "source": "api"
1686
+ "source": "chat-line"
1687
+ },
1688
+ "reply_window": {
1689
+ "closes_at": "2026-01-02T09:30:00Z",
1690
+ "state": "open"
1691
+ },
1692
+ "subject": {
1693
+ "locale": null,
1694
+ "person": null,
1695
+ "target_kind": "agent",
1696
+ "target_name": "assistant",
1697
+ "thread": "t-1"
1491
1698
  }
1492
1699
  }
1493
1700
  },
@@ -1522,6 +1729,17 @@ export const servedDocumentsJson = {
1522
1729
  ]
1523
1730
  }
1524
1731
  },
1732
+ "reply_texts": {
1733
+ "anyOf": [
1734
+ {
1735
+ "$ref": "#/$defs/ReplyTexts"
1736
+ },
1737
+ {
1738
+ "type": "null"
1739
+ }
1740
+ ],
1741
+ "default": null
1742
+ },
1525
1743
  "resume_expr": {
1526
1744
  "anyOf": [
1527
1745
  {
@@ -1629,7 +1847,11 @@ export const servedDocumentsJson = {
1629
1847
  "name": "location"
1630
1848
  },
1631
1849
  {
1632
- "gloss": "overlap deliver=all: the batch carried into this turn, in acceptance order, each {id, text, accepted_at} (+ form/form_tag/attachments/location when that message carried them)",
1850
+ "gloss": "the earlier message this one replies to, {message_id, status, text}; present only when the inbound quoted one",
1851
+ "name": "reply_to"
1852
+ },
1853
+ {
1854
+ "gloss": "overlap deliver=all: the batch carried into this turn, in acceptance order, each {id, text, accepted_at} (+ form/form_tag/attachments/location/reply_to when that message carried them)",
1633
1855
  "name": "messages"
1634
1856
  },
1635
1857
  {
@@ -1637,7 +1859,7 @@ export const servedDocumentsJson = {
1637
1859
  "name": "superseded"
1638
1860
  },
1639
1861
  {
1640
- "gloss": "the turn ids: {id, inbound: {id, kind, source}}",
1862
+ "gloss": "the turn: {id, inbound: {id, kind, source}, subject: {target_kind, target_name, person, thread, locale}, reply_window: {state, closes_at}}; reply_window.state is open (a free-form reply is allowed until closes_at), closed, or none (no window on this channel or address)",
1641
1863
  "name": "turn"
1642
1864
  },
1643
1865
  {
@@ -1760,21 +1982,6 @@ export const servedDocumentsJson = {
1760
1982
  "title": "Door",
1761
1983
  "type": "string"
1762
1984
  },
1763
- "error_reply_text": {
1764
- "anyOf": [
1765
- {
1766
- "maxLength": 2000,
1767
- "minLength": 1,
1768
- "pattern": "\\S",
1769
- "type": "string"
1770
- },
1771
- {
1772
- "type": "null"
1773
- }
1774
- ],
1775
- "default": null,
1776
- "title": "Error Reply Text"
1777
- },
1778
1985
  "execution_key": {
1779
1986
  "description": "The api-key ``user_id`` the turn runs AS; its live stored grants authorize the agent run or tool dispatch and every tool call the turn makes.",
1780
1987
  "minLength": 1,
@@ -1868,14 +2075,25 @@ export const servedDocumentsJson = {
1868
2075
  "returns": "the reply: null (silent), a string, or a list of answer parts",
1869
2076
  "variables": [
1870
2077
  {
1871
- "blurb": "the turn ids and subject this reply answers ({id, inbound, subject}); null when an out-of-band delivery's originating record has aged out",
2078
+ "blurb": "the turn this reply answers ({id, inbound, subject, reply_window}); reply_window {state, closes_at} is read when the turn starts, or at delivery for a late reply: open until closes_at, closed, or none; null when an out-of-band delivery's originating record has aged out",
1872
2079
  "name": "turn",
1873
2080
  "sample": {
1874
2081
  "id": "m-1",
1875
2082
  "inbound": {
1876
2083
  "id": "i-1",
1877
2084
  "kind": "message",
1878
- "source": "api"
2085
+ "source": "chat-line"
2086
+ },
2087
+ "reply_window": {
2088
+ "closes_at": "2026-01-02T09:30:00Z",
2089
+ "state": "open"
2090
+ },
2091
+ "subject": {
2092
+ "locale": null,
2093
+ "person": null,
2094
+ "target_kind": "agent",
2095
+ "target_name": "assistant",
2096
+ "thread": "t-1"
1879
2097
  }
1880
2098
  }
1881
2099
  },
@@ -1910,6 +2128,17 @@ export const servedDocumentsJson = {
1910
2128
  ]
1911
2129
  }
1912
2130
  },
2131
+ "reply_texts": {
2132
+ "anyOf": [
2133
+ {
2134
+ "$ref": "#/$defs/ReplyTexts"
2135
+ },
2136
+ {
2137
+ "type": "null"
2138
+ }
2139
+ ],
2140
+ "default": null
2141
+ },
1913
2142
  "resume_expr": {
1914
2143
  "anyOf": [
1915
2144
  {
@@ -2017,7 +2246,11 @@ export const servedDocumentsJson = {
2017
2246
  "name": "location"
2018
2247
  },
2019
2248
  {
2020
- "gloss": "overlap deliver=all: the batch carried into this turn, in acceptance order, each {id, text, accepted_at} (+ form/form_tag/attachments/location when that message carried them)",
2249
+ "gloss": "the earlier message this one replies to, {message_id, status, text}; present only when the inbound quoted one",
2250
+ "name": "reply_to"
2251
+ },
2252
+ {
2253
+ "gloss": "overlap deliver=all: the batch carried into this turn, in acceptance order, each {id, text, accepted_at} (+ form/form_tag/attachments/location/reply_to when that message carried them)",
2021
2254
  "name": "messages"
2022
2255
  },
2023
2256
  {
@@ -2025,7 +2258,7 @@ export const servedDocumentsJson = {
2025
2258
  "name": "superseded"
2026
2259
  },
2027
2260
  {
2028
- "gloss": "the turn ids: {id, inbound: {id, kind, source}}",
2261
+ "gloss": "the turn: {id, inbound: {id, kind, source}, subject: {target_kind, target_name, person, thread, locale}, reply_window: {state, closes_at}}; reply_window.state is open (a free-form reply is allowed until closes_at), closed, or none (no window on this channel or address)",
2029
2262
  "name": "turn"
2030
2263
  },
2031
2264
  {
@@ -2129,6 +2362,194 @@ export const servedDocumentsJson = {
2129
2362
  "title": "OverlapPolicy",
2130
2363
  "type": "object"
2131
2364
  },
2365
+ "ReplyTexts": {
2366
+ "additionalProperties": false,
2367
+ "description": "The caller's words for the platform's fixed participant replies on one route. Frozen, strict keys.\n\n``error`` is sent when a turn fails and the target gave no reply; ``slow_down`` when an address\nis over the turn cap; ``pairing_linked`` when a pair code was redeemed and the two persons\nmerged; ``pairing_unlinked`` when ``/unlink`` detached the address; ``pairing_not_linked`` when\n``/unlink`` came from an address linked to nothing; ``pairing_code_invalid`` when a redeem was\nrefused; ``pairing_code`` is the ``/link`` reply carrying the fresh code, a template that MUST\nreference ``{pairing_code}`` and may reference ``{expires_at}`` (the code's ISO-8601 expiry),\nwith no conversion or format spec; ``pairing_link_unavailable`` when a redeem met a person being\nerased (its code is consumed, so the reply asks for a new one); ``pairing_unlink_unavailable``\nwhen ``/unlink`` met the sender's person being erased; ``rejected_unsupported_type`` / ``rejected_too_large`` /\n``rejected_could_not_receive`` are the notices for an inbound message the channel cannot\nbridge, a file over the cap, and a file the channel could not fetch. Every member but\n``pairing_code`` is literal text: a ``{`` in it is drawn as written. Each is a\n:data:`~tai42_contract.interactions.ReplyText` in the line's language; absent, the built-in\nEnglish reply is sent. An empty catalogue names nothing and is refused; an unknown key is\nrefused.",
2368
+ "properties": {
2369
+ "error": {
2370
+ "anyOf": [
2371
+ {
2372
+ "maxLength": 2000,
2373
+ "minLength": 1,
2374
+ "pattern": "\\S",
2375
+ "type": "string"
2376
+ },
2377
+ {
2378
+ "type": "null"
2379
+ }
2380
+ ],
2381
+ "default": null,
2382
+ "title": "Error"
2383
+ },
2384
+ "pairing_code": {
2385
+ "anyOf": [
2386
+ {
2387
+ "maxLength": 2000,
2388
+ "minLength": 1,
2389
+ "pattern": "\\S",
2390
+ "type": "string"
2391
+ },
2392
+ {
2393
+ "type": "null"
2394
+ }
2395
+ ],
2396
+ "default": null,
2397
+ "title": "Pairing Code"
2398
+ },
2399
+ "pairing_code_invalid": {
2400
+ "anyOf": [
2401
+ {
2402
+ "maxLength": 2000,
2403
+ "minLength": 1,
2404
+ "pattern": "\\S",
2405
+ "type": "string"
2406
+ },
2407
+ {
2408
+ "type": "null"
2409
+ }
2410
+ ],
2411
+ "default": null,
2412
+ "title": "Pairing Code Invalid"
2413
+ },
2414
+ "pairing_link_unavailable": {
2415
+ "anyOf": [
2416
+ {
2417
+ "maxLength": 2000,
2418
+ "minLength": 1,
2419
+ "pattern": "\\S",
2420
+ "type": "string"
2421
+ },
2422
+ {
2423
+ "type": "null"
2424
+ }
2425
+ ],
2426
+ "default": null,
2427
+ "title": "Pairing Link Unavailable"
2428
+ },
2429
+ "pairing_linked": {
2430
+ "anyOf": [
2431
+ {
2432
+ "maxLength": 2000,
2433
+ "minLength": 1,
2434
+ "pattern": "\\S",
2435
+ "type": "string"
2436
+ },
2437
+ {
2438
+ "type": "null"
2439
+ }
2440
+ ],
2441
+ "default": null,
2442
+ "title": "Pairing Linked"
2443
+ },
2444
+ "pairing_not_linked": {
2445
+ "anyOf": [
2446
+ {
2447
+ "maxLength": 2000,
2448
+ "minLength": 1,
2449
+ "pattern": "\\S",
2450
+ "type": "string"
2451
+ },
2452
+ {
2453
+ "type": "null"
2454
+ }
2455
+ ],
2456
+ "default": null,
2457
+ "title": "Pairing Not Linked"
2458
+ },
2459
+ "pairing_unlink_unavailable": {
2460
+ "anyOf": [
2461
+ {
2462
+ "maxLength": 2000,
2463
+ "minLength": 1,
2464
+ "pattern": "\\S",
2465
+ "type": "string"
2466
+ },
2467
+ {
2468
+ "type": "null"
2469
+ }
2470
+ ],
2471
+ "default": null,
2472
+ "title": "Pairing Unlink Unavailable"
2473
+ },
2474
+ "pairing_unlinked": {
2475
+ "anyOf": [
2476
+ {
2477
+ "maxLength": 2000,
2478
+ "minLength": 1,
2479
+ "pattern": "\\S",
2480
+ "type": "string"
2481
+ },
2482
+ {
2483
+ "type": "null"
2484
+ }
2485
+ ],
2486
+ "default": null,
2487
+ "title": "Pairing Unlinked"
2488
+ },
2489
+ "rejected_could_not_receive": {
2490
+ "anyOf": [
2491
+ {
2492
+ "maxLength": 2000,
2493
+ "minLength": 1,
2494
+ "pattern": "\\S",
2495
+ "type": "string"
2496
+ },
2497
+ {
2498
+ "type": "null"
2499
+ }
2500
+ ],
2501
+ "default": null,
2502
+ "title": "Rejected Could Not Receive"
2503
+ },
2504
+ "rejected_too_large": {
2505
+ "anyOf": [
2506
+ {
2507
+ "maxLength": 2000,
2508
+ "minLength": 1,
2509
+ "pattern": "\\S",
2510
+ "type": "string"
2511
+ },
2512
+ {
2513
+ "type": "null"
2514
+ }
2515
+ ],
2516
+ "default": null,
2517
+ "title": "Rejected Too Large"
2518
+ },
2519
+ "rejected_unsupported_type": {
2520
+ "anyOf": [
2521
+ {
2522
+ "maxLength": 2000,
2523
+ "minLength": 1,
2524
+ "pattern": "\\S",
2525
+ "type": "string"
2526
+ },
2527
+ {
2528
+ "type": "null"
2529
+ }
2530
+ ],
2531
+ "default": null,
2532
+ "title": "Rejected Unsupported Type"
2533
+ },
2534
+ "slow_down": {
2535
+ "anyOf": [
2536
+ {
2537
+ "maxLength": 2000,
2538
+ "minLength": 1,
2539
+ "pattern": "\\S",
2540
+ "type": "string"
2541
+ },
2542
+ {
2543
+ "type": "null"
2544
+ }
2545
+ ],
2546
+ "default": null,
2547
+ "title": "Slow Down"
2548
+ }
2549
+ },
2550
+ "title": "ReplyTexts",
2551
+ "type": "object"
2552
+ },
2132
2553
  "TemplatedText": {
2133
2554
  "additionalProperties": false,
2134
2555
  "description": "A renderable text: its source plus the parameters its render takes.\n\nEXACTLY ONE source is set — ``content`` (the text inline) or ``id`` (the id of a\nstored resource holding the text); neither and both are refused at construction.\n``kwargs`` are the render parameters for the TEXT and apply either way, so moving a\ntext from inline to stored (or back) leaves its parameters untouched.",