|
13 | 13 | * runtime rejects it as malformed. |
14 | 14 | */ |
15 | 15 | export function stripClientIngressFields(part: string): string { |
| 16 | + return sanitizeClientInPart(part).part; |
| 17 | +} |
| 18 | + |
| 19 | +/** |
| 20 | + * {@link stripClientIngressFields}, plus the record's `kind` read from the same parse, so a route can |
| 21 | + * refuse kinds only a server may append (see {@link isServerOnlySessionInKind}). |
| 22 | + */ |
| 23 | +export function sanitizeClientInPart(part: string): { part: string; kind: string | undefined } { |
16 | 24 | let record: unknown; |
17 | 25 | try { |
18 | 26 | record = JSON.parse(part); |
19 | 27 | } catch { |
20 | | - return part; |
| 28 | + return { part, kind: undefined }; |
21 | 29 | } |
22 | | - if (!record || typeof record !== "object") return part; |
| 30 | + if (!record || typeof record !== "object") return { part, kind: undefined }; |
| 31 | + |
| 32 | + const rawKind = (record as { kind?: unknown }).kind; |
| 33 | + const kind = typeof rawKind === "string" ? rawKind : undefined; |
23 | 34 |
|
24 | 35 | const payload = (record as { payload?: unknown }).payload as Record<string, unknown> | undefined; |
25 | | - if (!payload || typeof payload !== "object") return part; |
| 36 | + if (!payload || typeof payload !== "object") return { part, kind }; |
26 | 37 |
|
27 | | - return removeClientIngressFields(payload) ? JSON.stringify(record) : part; |
| 38 | + return { part: removeClientIngressFields(payload) ? JSON.stringify(record) : part, kind }; |
| 39 | +} |
| 40 | + |
| 41 | +/** |
| 42 | + * `.in` record kinds only the customer's server sends: the head-start handover and its skip signal. The |
| 43 | + * agent takes the first one it receives as the warm first-turn response, tool calls included, so a |
| 44 | + * public access token must not be able to append one. |
| 45 | + */ |
| 46 | +export function isServerOnlySessionInKind(kind: string | undefined): boolean { |
| 47 | + return kind === "handover" || kind === "handover-skip"; |
28 | 48 | } |
29 | 49 |
|
30 | 50 | export function stripClientIngressFieldsFromBasePayload<T extends Record<string, unknown>>( |
|
0 commit comments