@openwop/openwop 1.3.0 → 1.4.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/dist/client.d.ts +29 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +85 -0
- package/dist/client.js.map +1 -1
- package/dist/event-helpers.d.ts +24 -1
- package/dist/event-helpers.d.ts.map +1 -1
- package/dist/event-helpers.js +54 -0
- package/dist/event-helpers.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +287 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +109 -0
- package/src/event-helpers.ts +99 -0
- package/src/index.ts +30 -0
- package/src/types.ts +319 -3
package/src/event-helpers.ts
CHANGED
|
@@ -39,6 +39,14 @@ import type {
|
|
|
39
39
|
OutputChunkPayload,
|
|
40
40
|
RunEventDoc,
|
|
41
41
|
TypedRunEvent,
|
|
42
|
+
VoiceSpeechStartPayload,
|
|
43
|
+
VoiceTranscriptPayload,
|
|
44
|
+
VoiceEndpointCandidatePayload,
|
|
45
|
+
VoiceTurnCommitPayload,
|
|
46
|
+
VoiceSynthesisChunkPayload,
|
|
47
|
+
VoiceBargeInPayload,
|
|
48
|
+
VoiceCancelledPayload,
|
|
49
|
+
ChannelPresencePayload,
|
|
42
50
|
} from './types.js';
|
|
43
51
|
|
|
44
52
|
// ─── Type guards ────────────────────────────────────────────────────────
|
|
@@ -160,6 +168,97 @@ export function isOutputChunk(
|
|
|
160
168
|
return typeof (ev.payload as Record<string, unknown>).isLast === 'boolean';
|
|
161
169
|
}
|
|
162
170
|
|
|
171
|
+
function hasNumberField(payload: unknown, field: string): boolean {
|
|
172
|
+
return (
|
|
173
|
+
payload !== null &&
|
|
174
|
+
typeof payload === 'object' &&
|
|
175
|
+
typeof (payload as Record<string, unknown>)[field] === 'number'
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** `voice.speech_start` (RFC 0106). */
|
|
180
|
+
export function isVoiceSpeechStart(
|
|
181
|
+
ev: RunEventDoc,
|
|
182
|
+
): ev is TypedRunEvent<VoiceSpeechStartPayload> {
|
|
183
|
+
return ev.type === 'voice.speech_start' && hasNumberField(ev.payload, 'atMs');
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** `voice.transcript` (RFC 0106). Narrows when `type` matches AND payload
|
|
187
|
+
* carries the required `text` + `isFinal` + `atMs` + `contentTrust`. The
|
|
188
|
+
* transcript is untrusted ingress (`voice-transcript-untrusted`). */
|
|
189
|
+
export function isVoiceTranscript(
|
|
190
|
+
ev: RunEventDoc,
|
|
191
|
+
): ev is TypedRunEvent<VoiceTranscriptPayload> {
|
|
192
|
+
return (
|
|
193
|
+
ev.type === 'voice.transcript' &&
|
|
194
|
+
hasStringField(ev.payload, 'text') &&
|
|
195
|
+
typeof (ev.payload as Record<string, unknown>).isFinal === 'boolean' &&
|
|
196
|
+
hasNumberField(ev.payload, 'atMs') &&
|
|
197
|
+
(ev.payload as Record<string, unknown>).contentTrust === 'untrusted'
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** `voice.endpoint_candidate` (RFC 0106). */
|
|
202
|
+
export function isVoiceEndpointCandidate(
|
|
203
|
+
ev: RunEventDoc,
|
|
204
|
+
): ev is TypedRunEvent<VoiceEndpointCandidatePayload> {
|
|
205
|
+
return (
|
|
206
|
+
ev.type === 'voice.endpoint_candidate' && hasNumberField(ev.payload, 'atMs')
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** `voice.turn_commit` (RFC 0106). Narrows when payload carries the required
|
|
211
|
+
* `atMs` + `finalText` (the settled transcript). */
|
|
212
|
+
export function isVoiceTurnCommit(
|
|
213
|
+
ev: RunEventDoc,
|
|
214
|
+
): ev is TypedRunEvent<VoiceTurnCommitPayload> {
|
|
215
|
+
return (
|
|
216
|
+
ev.type === 'voice.turn_commit' &&
|
|
217
|
+
hasNumberField(ev.payload, 'atMs') &&
|
|
218
|
+
hasStringField(ev.payload, 'finalText')
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** `voice.synthesis_chunk` (RFC 0106). Narrows when payload carries the
|
|
223
|
+
* required `seq` (number) + `mimeType` (string). */
|
|
224
|
+
export function isVoiceSynthesisChunk(
|
|
225
|
+
ev: RunEventDoc,
|
|
226
|
+
): ev is TypedRunEvent<VoiceSynthesisChunkPayload> {
|
|
227
|
+
return (
|
|
228
|
+
ev.type === 'voice.synthesis_chunk' &&
|
|
229
|
+
hasNumberField(ev.payload, 'seq') &&
|
|
230
|
+
hasStringField(ev.payload, 'mimeType')
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/** `voice.barge_in` (RFC 0106). */
|
|
235
|
+
export function isVoiceBargeIn(
|
|
236
|
+
ev: RunEventDoc,
|
|
237
|
+
): ev is TypedRunEvent<VoiceBargeInPayload> {
|
|
238
|
+
return ev.type === 'voice.barge_in' && hasNumberField(ev.payload, 'atMs');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** `voice.cancelled` (RFC 0106). */
|
|
242
|
+
export function isVoiceCancelled(
|
|
243
|
+
ev: RunEventDoc,
|
|
244
|
+
): ev is TypedRunEvent<VoiceCancelledPayload> {
|
|
245
|
+
return ev.type === 'voice.cancelled' && hasNumberField(ev.payload, 'atMs');
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/** `channel.presence` (RFC 0110). EPHEMERAL — observable on the LIVE event
|
|
249
|
+
* stream only; ABSENT on replay / `:fork` (the host never persists presence
|
|
250
|
+
* to the replayable log). Narrows when payload carries `conversationId` +
|
|
251
|
+
* a `present` array. */
|
|
252
|
+
export function isChannelPresence(
|
|
253
|
+
ev: RunEventDoc,
|
|
254
|
+
): ev is TypedRunEvent<ChannelPresencePayload> {
|
|
255
|
+
return (
|
|
256
|
+
ev.type === 'channel.presence' &&
|
|
257
|
+
hasStringField(ev.payload, 'conversationId') &&
|
|
258
|
+
Array.isArray((ev.payload as Record<string, unknown>).present)
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
|
|
163
262
|
// ─── High-level subscription helper ─────────────────────────────────────
|
|
164
263
|
|
|
165
264
|
/** Returned by {@link subscribeToAgentReasoning}. Call to cancel the
|
package/src/index.ts
CHANGED
|
@@ -61,6 +61,16 @@ export type {
|
|
|
61
61
|
MemoryWrittenPayload,
|
|
62
62
|
// RFC 0094 §D — streaming output chunk (`output.chunk` / `ai.message.chunk`)
|
|
63
63
|
OutputChunkPayload,
|
|
64
|
+
// RFC 0106 — voice.* run-event payloads
|
|
65
|
+
VoiceSpeechStartPayload,
|
|
66
|
+
VoiceTranscriptPayload,
|
|
67
|
+
VoiceEndpointCandidatePayload,
|
|
68
|
+
VoiceTurnCommitPayload,
|
|
69
|
+
VoiceSynthesisChunkPayload,
|
|
70
|
+
VoiceBargeInPayload,
|
|
71
|
+
VoiceCancelledPayload,
|
|
72
|
+
// RFC 0110 — channel.presence run-event payload
|
|
73
|
+
ChannelPresencePayload,
|
|
64
74
|
// RFC 0027 + RFC 0028 — Prompt library (spec/v1/prompts.md)
|
|
65
75
|
GetPromptRequest,
|
|
66
76
|
ListPromptsRequest,
|
|
@@ -116,6 +126,14 @@ export {
|
|
|
116
126
|
isAgentDecided,
|
|
117
127
|
isMemoryWritten,
|
|
118
128
|
isOutputChunk,
|
|
129
|
+
isVoiceSpeechStart,
|
|
130
|
+
isVoiceTranscript,
|
|
131
|
+
isVoiceEndpointCandidate,
|
|
132
|
+
isVoiceTurnCommit,
|
|
133
|
+
isVoiceSynthesisChunk,
|
|
134
|
+
isVoiceBargeIn,
|
|
135
|
+
isVoiceCancelled,
|
|
136
|
+
isChannelPresence,
|
|
119
137
|
subscribeToAgentReasoning,
|
|
120
138
|
} from './event-helpers.js';
|
|
121
139
|
export type {
|
|
@@ -183,6 +201,7 @@ export type {
|
|
|
183
201
|
// AI Envelope types (DRAFT v1.x — spec/v1/ai-envelope.md). Inbound LLM-emission
|
|
184
202
|
// envelope, distinct from RunEventDoc (outbound) and ErrorEnvelope (host HTTP).
|
|
185
203
|
export type {
|
|
204
|
+
A2UISurfacePayload,
|
|
186
205
|
AIEnvelope,
|
|
187
206
|
AIEnvelopeErrorPayload,
|
|
188
207
|
ClarificationRequestPayload,
|
|
@@ -196,6 +215,17 @@ export type {
|
|
|
196
215
|
SchemaRequestPayload,
|
|
197
216
|
SchemaResponsePayload,
|
|
198
217
|
ValidationDetail,
|
|
218
|
+
// RFC 0103 — localized content surface
|
|
219
|
+
LocalizedContentStatus,
|
|
220
|
+
LocalizedContentPage,
|
|
221
|
+
LocalizedContentSection,
|
|
222
|
+
LocalizedContentPageResponse,
|
|
223
|
+
LocalizedContentLanguageSettings,
|
|
224
|
+
PutContentSectionRequest,
|
|
225
|
+
// RFC 0099 — trigger subscription registration
|
|
226
|
+
TriggerSubscriptionRegistration,
|
|
227
|
+
TriggerSubscription,
|
|
228
|
+
CreateTriggerSubscriptionResponse,
|
|
199
229
|
} from './types.js';
|
|
200
230
|
|
|
201
231
|
// RFC 0030 §A `reasoning` field prompt-directive helper. Hosts that
|
package/src/types.ts
CHANGED
|
@@ -75,6 +75,68 @@ export interface Capabilities {
|
|
|
75
75
|
* host-defined / unbounded. */
|
|
76
76
|
maxParticipants?: number;
|
|
77
77
|
};
|
|
78
|
+
/** RFC 0100. Host exposes itself as an A2A (Agent2Agent) agent. `supported`
|
|
79
|
+
* alone ⇒ the synchronous `message/send` → poll `tasks/get` round-trip
|
|
80
|
+
* (`a2a-integration.md`). The optional flags gate the RFC 0100 async/durable
|
|
81
|
+
* additions. Absent ⇒ no A2A advertisement. */
|
|
82
|
+
a2a?: {
|
|
83
|
+
/** Host exposes itself as an A2A agent. */
|
|
84
|
+
supported: boolean;
|
|
85
|
+
/** A2A 0.3 well-known agent card URL (`/.well-known/agent-card.json`). */
|
|
86
|
+
agentCardUrl: string;
|
|
87
|
+
/** `message/stream` + `tasks/resubscribe` (RFC 0100 §3 resubscribe re-attach). */
|
|
88
|
+
streaming?: boolean;
|
|
89
|
+
/** A2A push-notification config (RFC 0100 §4); a caller-supplied
|
|
90
|
+
* `pushConfig.url` is SSRF-validated (`a2a-push-egress-ssrf`). */
|
|
91
|
+
pushNotifications?: boolean;
|
|
92
|
+
/** RFC 0100 §2. Host persists the projected `A2ATaskState` per backing run;
|
|
93
|
+
* `tasks/get` returns live state after disconnect. Absent/false ⇒
|
|
94
|
+
* synchronous round-trip only. */
|
|
95
|
+
durableTasks?: boolean;
|
|
96
|
+
};
|
|
97
|
+
/** RFC 0109. Host stamps the optional non-secret `agent.model`
|
|
98
|
+
* (`{ provider, model }`) on `role:'agent'` conversation turns, recording
|
|
99
|
+
* which model produced the turn (read verbatim on `:fork`). Absent ⇒ no
|
|
100
|
+
* provenance; the host omits `agent.model`. */
|
|
101
|
+
conversationTurnModelProvenance?: {
|
|
102
|
+
/** Toggle — `true` when the host stamps `agent.model`. */
|
|
103
|
+
supported: boolean;
|
|
104
|
+
};
|
|
105
|
+
/** RFC 0110. Host emits the ephemeral `channel.presence` RunEvent (online +
|
|
106
|
+
* per-member typing) for `type:'channel'` conversations. Presence is live
|
|
107
|
+
* state — the host never persists it to the replayable event log and it
|
|
108
|
+
* never affects replay / `:fork`. Membership-gated (default-deny, CTI-1).
|
|
109
|
+
* Absent ⇒ no presence. */
|
|
110
|
+
channelPresence?: {
|
|
111
|
+
/** Toggle — `true` when the host emits `channel.presence`. */
|
|
112
|
+
supported: boolean;
|
|
113
|
+
};
|
|
114
|
+
/** Capability advertisement for the host AI-proxy (`aiProviders` in
|
|
115
|
+
* `capabilities.md`). Absent ⇒ the host advertises no AI-proxy surface.
|
|
116
|
+
* Carries BYOK policy plus the RFC 0105/0106/0108 self-hosted / speech /
|
|
117
|
+
* real-time-voice flags. The wire object MAY carry additional fields
|
|
118
|
+
* (`input`, `authModes`, `maxInlineMediaBytes`) not modeled here. */
|
|
119
|
+
aiProviders?: AIProvidersCapability;
|
|
120
|
+
/** RFC 0104. Portable HITL approver-routing advertisement. When
|
|
121
|
+
* `approverRouting.supported`, the host honors the OPTIONAL, ADVISORY
|
|
122
|
+
* `approverGroupRefs` / `approverRoleRefs` / `audience` fields on the
|
|
123
|
+
* `kind:'approval'` interrupt payload (the SDK carries the interrupt
|
|
124
|
+
* payload opaquely as `data`, so those advisory fields ride that opaque
|
|
125
|
+
* object), resolves the advertised `refKinds` against its own RBAC, and
|
|
126
|
+
* ENFORCES eligibility at resolve time. Absent ⇒ the host ignores them. */
|
|
127
|
+
interrupt?: {
|
|
128
|
+
approverRouting?: {
|
|
129
|
+
/** Host honors the RFC 0104 approver-routing fields. */
|
|
130
|
+
supported: boolean;
|
|
131
|
+
/** Ref kinds the host actually resolves: `'group'` ⇒ honors
|
|
132
|
+
* `approverGroupRefs`, `'role'` ⇒ honors `approverRoleRefs`. Absent ⇒
|
|
133
|
+
* advisory-only passthrough (the host resolves neither). */
|
|
134
|
+
refKinds?: readonly ('group' | 'role')[];
|
|
135
|
+
/** Host honors the `audience` notification-targeting override.
|
|
136
|
+
* Absent/`false` ⇒ the host notifies the resolved eligible union. */
|
|
137
|
+
audience?: boolean;
|
|
138
|
+
};
|
|
139
|
+
};
|
|
78
140
|
extensions?: Record<string, unknown>;
|
|
79
141
|
// Network-handshake superset (all `(future)` fields per capabilities.md)
|
|
80
142
|
implementation?: { name?: string; version?: string; vendor?: string };
|
|
@@ -520,16 +582,46 @@ export type AIPolicyDenyReason =
|
|
|
520
582
|
* that don't enforce per-provider policies.
|
|
521
583
|
*/
|
|
522
584
|
export interface AIProvidersCapability {
|
|
523
|
-
/** Provider ids the host's AI-proxy can route to.
|
|
524
|
-
|
|
585
|
+
/** Provider ids the host's AI-proxy can route to. Optional per
|
|
586
|
+
* `capabilities.schema.json` (the `aiProviders` block has no required
|
|
587
|
+
* fields); a host advertising the block normally lists them. */
|
|
588
|
+
supported?: readonly string[];
|
|
525
589
|
/** Subset of `supported` for which BYOK is permitted. */
|
|
526
|
-
byok
|
|
590
|
+
byok?: readonly string[];
|
|
527
591
|
/** Optional 4-mode policy enforcement advertisement. */
|
|
528
592
|
policies?: {
|
|
529
593
|
modes: readonly AIPolicyMode[];
|
|
530
594
|
scopes?: readonly string[];
|
|
531
595
|
errorCode?: string;
|
|
532
596
|
};
|
|
597
|
+
/** RFC 0108. Subset of `supported` whose entries are operator-/tenant-
|
|
598
|
+
* configured OpenAI-compatible endpoints (Ollama / vLLM / LM Studio / any
|
|
599
|
+
* `/v1/chat/completions`-compatible server), as opposed to a host-managed
|
|
600
|
+
* connection to a known public vendor. Each entry also appears in
|
|
601
|
+
* `supported` and MAY also appear in `byok`. The id is an OPAQUE label that
|
|
602
|
+
* MUST NOT encode the endpoint's network location (RFC 0108 §A.3), and a
|
|
603
|
+
* client MUST NOT infer model capabilities from it (§B) — the authoritative
|
|
604
|
+
* sources are `modelCapabilities.advertised[]` and `aiProviders.input`. */
|
|
605
|
+
selfHosted?: readonly string[];
|
|
606
|
+
/** RFC 0105. Present (value MUST be `'supported'`) ⇒ the host exposes speech
|
|
607
|
+
* synthesis via the host-side `ctx.callSpeechSynthesizer`. Absent ⇒ no TTS
|
|
608
|
+
* (a call is rejected with `speech_synthesis_unsupported`). */
|
|
609
|
+
speechSynthesis?: 'supported';
|
|
610
|
+
/** RFC 0106. Optional real-time voice profile. Absent ⇒ no live voice. The
|
|
611
|
+
* sub-flags gate streaming STT / chunked TTS and turn-taking; the host
|
|
612
|
+
* enforces that `turnDetection`/`bargeIn` require `transcription`. */
|
|
613
|
+
realtimeVoice?: {
|
|
614
|
+
/** Present (`'streaming'`) ⇒ host exposes streaming `ctx.callTranscriber`. */
|
|
615
|
+
transcription?: 'streaming';
|
|
616
|
+
/** Present (`'streaming'`) ⇒ `ctx.callSpeechSynthesizer` honors `stream:true`.
|
|
617
|
+
* Requires `aiProviders.speechSynthesis: 'supported'`. */
|
|
618
|
+
synthesis?: 'streaming';
|
|
619
|
+
/** Endpointing sophistication; requires `transcription`. */
|
|
620
|
+
turnDetection?: 'vad' | 'semantic';
|
|
621
|
+
/** Present (`'supported'`) ⇒ host emits `voice.barge_in`/`voice.cancelled`
|
|
622
|
+
* on overlapping speech; requires `transcription`. */
|
|
623
|
+
bargeIn?: 'supported';
|
|
624
|
+
};
|
|
533
625
|
}
|
|
534
626
|
|
|
535
627
|
/**
|
|
@@ -787,6 +879,104 @@ export interface OutputChunkPayload {
|
|
|
787
879
|
[key: string]: unknown;
|
|
788
880
|
}
|
|
789
881
|
|
|
882
|
+
// ─── RFC 0106 voice.* run-event payloads ────────────────────────────────
|
|
883
|
+
// Mirror `run-event-payloads.schema.json`. These events are emitted on the
|
|
884
|
+
// durable event log by the host-side `ctx.callTranscriber` /
|
|
885
|
+
// `ctx.callSpeechSynthesizer(stream:true)` methods (out of client-SDK scope);
|
|
886
|
+
// a client tails them off the run event stream.
|
|
887
|
+
|
|
888
|
+
/** `voice.speech_start` (RFC 0106). Host detected start of speech. */
|
|
889
|
+
export interface VoiceSpeechStartPayload {
|
|
890
|
+
/** Milliseconds since the turn/session epoch. */
|
|
891
|
+
atMs: number;
|
|
892
|
+
[key: string]: unknown;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
/** `voice.transcript` (RFC 0106). An interim or final transcript fragment.
|
|
896
|
+
* `contentTrust` is REQUIRED and always `'untrusted'` — live transcript is
|
|
897
|
+
* untrusted ingress (`voice-transcript-untrusted`); consumers MUST NOT
|
|
898
|
+
* promote it to higher authority. */
|
|
899
|
+
export interface VoiceTranscriptPayload {
|
|
900
|
+
text: string;
|
|
901
|
+
/** `true` once the fragment is finalized (committed at `voice.turn_commit`). */
|
|
902
|
+
isFinal: boolean;
|
|
903
|
+
atMs: number;
|
|
904
|
+
/** Always `'untrusted'`. */
|
|
905
|
+
contentTrust: 'untrusted';
|
|
906
|
+
/** Stable prefix carried across interim revisions. */
|
|
907
|
+
committedPrefix?: string;
|
|
908
|
+
/** Provider-formatted variant (punctuation/casing). */
|
|
909
|
+
formatted?: string;
|
|
910
|
+
/** Provider stability score for an interim fragment. */
|
|
911
|
+
stability?: number;
|
|
912
|
+
[key: string]: unknown;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
/** `voice.endpoint_candidate` (RFC 0106). A `semantic` turn detector's
|
|
916
|
+
* candidate end-of-turn, distinct from the committed `voice.turn_commit`. */
|
|
917
|
+
export interface VoiceEndpointCandidatePayload {
|
|
918
|
+
atMs: number;
|
|
919
|
+
/** Detector confidence in the candidate endpoint. */
|
|
920
|
+
confidence?: number;
|
|
921
|
+
[key: string]: unknown;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
/** `voice.turn_commit` (RFC 0106). The turn is committed; `finalText` is the
|
|
925
|
+
* settled transcript the `ctx.callTranscriber` Promise resolves with. */
|
|
926
|
+
export interface VoiceTurnCommitPayload {
|
|
927
|
+
atMs: number;
|
|
928
|
+
finalText: string;
|
|
929
|
+
[key: string]: unknown;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
/** `voice.synthesis_chunk` (RFC 0106). Metadata for a streamed-synthesis
|
|
933
|
+
* clause-boundary chunk; bytes ride `url`/`streamRef` (or inline `base64`
|
|
934
|
+
* only under the host cap), never inlined past the cap. */
|
|
935
|
+
export interface VoiceSynthesisChunkPayload {
|
|
936
|
+
/** Monotonic chunk sequence within the synthesis. */
|
|
937
|
+
seq: number;
|
|
938
|
+
mimeType: string;
|
|
939
|
+
/** Host-served URL for the chunk bytes. */
|
|
940
|
+
url?: string;
|
|
941
|
+
/** Live-conduit handle for the chunk bytes. */
|
|
942
|
+
streamRef?: string;
|
|
943
|
+
/** Inline bytes — present only under the host's inline cap. */
|
|
944
|
+
base64?: string;
|
|
945
|
+
durationMs?: number;
|
|
946
|
+
/** `true` for the final chunk of the synthesis. */
|
|
947
|
+
final?: boolean;
|
|
948
|
+
[key: string]: unknown;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
/** `voice.barge_in` (RFC 0106). Overlapping speech detected during playback. */
|
|
952
|
+
export interface VoiceBargeInPayload {
|
|
953
|
+
atMs: number;
|
|
954
|
+
[key: string]: unknown;
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
/** `voice.cancelled` (RFC 0106). Downstream work cancelled (e.g. after a
|
|
958
|
+
* barge-in); no synthesis chunk follows. */
|
|
959
|
+
export interface VoiceCancelledPayload {
|
|
960
|
+
atMs: number;
|
|
961
|
+
/** Host-defined cancellation reason. */
|
|
962
|
+
reason?: string;
|
|
963
|
+
[key: string]: unknown;
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
/** `channel.presence` (RFC 0110). EPHEMERAL online + typing presence for a
|
|
967
|
+
* `type:'channel'` conversation. Observable on the LIVE run-event stream
|
|
968
|
+
* only — the host MUST NOT persist it to the replayable event log, so it is
|
|
969
|
+
* ABSENT on replay / `POST /v1/runs/{runId}:fork`. Membership-gated: every
|
|
970
|
+
* ref is a current participant (opaque RFC 0041 subject refs, non-PII). */
|
|
971
|
+
export interface ChannelPresencePayload {
|
|
972
|
+
conversationId: string;
|
|
973
|
+
/** Subject refs of members currently present (subset of participants). */
|
|
974
|
+
present: readonly string[];
|
|
975
|
+
/** Subset of `present` currently typing (boolean-by-presence; no free text). */
|
|
976
|
+
typing?: readonly string[];
|
|
977
|
+
[key: string]: unknown;
|
|
978
|
+
}
|
|
979
|
+
|
|
790
980
|
/** A `RunEventDoc` narrowed to a specific event-type discriminator +
|
|
791
981
|
* payload shape. Returned by the `isAgent*` type guards in
|
|
792
982
|
* `event-helpers.ts`. */
|
|
@@ -942,6 +1132,39 @@ export interface AIEnvelopeErrorPayload {
|
|
|
942
1132
|
details?: Record<string, unknown>;
|
|
943
1133
|
}
|
|
944
1134
|
|
|
1135
|
+
/**
|
|
1136
|
+
* Payload of the core `ui.a2ui-surface` envelope kind (RFC 0102 — A2UI
|
|
1137
|
+
* agent-authored interface surfaces, `schemas/envelopes/ui.a2ui-surface.schema.json`).
|
|
1138
|
+
* An advertised, optional core kind beside the `media.*` family: a declarative
|
|
1139
|
+
* interactive UI a consumer renders with native widgets, routing user actions
|
|
1140
|
+
* back **without executing agent-supplied code**.
|
|
1141
|
+
*
|
|
1142
|
+
* `surface` is the closed component tree, kept loose here (`Record<string,
|
|
1143
|
+
* unknown>`) — it is rendered by a dedicated A2UI renderer the SDK does not
|
|
1144
|
+
* provide, and matches the SDK convention of keeping complex nested shapes
|
|
1145
|
+
* structural (cf. `ClarificationRequestPayload.questions[].schema`).
|
|
1146
|
+
*
|
|
1147
|
+
* NOTE: the broader AI-envelope surface (`AIEnvelope`, `EnvelopeMeta`, the
|
|
1148
|
+
* universal payloads) is currently modeled only in this TypeScript SDK; the
|
|
1149
|
+
* Python and Go SDKs do not yet model AI envelopes. `A2UISurfacePayload`
|
|
1150
|
+
* therefore lands here only; cross-SDK AI-envelope modeling is a separate
|
|
1151
|
+
* follow-on (tracked in PARITY.md), not part of RFC 0102.
|
|
1152
|
+
*/
|
|
1153
|
+
export interface A2UISurfacePayload {
|
|
1154
|
+
/** The A2UI catalog version the surface targets. A host-enumerated,
|
|
1155
|
+
* growing set (currently `'0.9.1'`); a consumer MUST refuse an unknown /
|
|
1156
|
+
* higher version with `unknown_schema_version`. Typed as `string` (not a
|
|
1157
|
+
* pinned literal) so the read-type stays forward-compatible as the host's
|
|
1158
|
+
* supported set grows; the consumer enforces refuse-unknown at runtime. */
|
|
1159
|
+
catalogVersion: string;
|
|
1160
|
+
/** The A2UI surface document — a closed component tree, self-contained and
|
|
1161
|
+
* renderable from the payload alone (never a live reference into an
|
|
1162
|
+
* external catalog). Kept structural; rendered by an A2UI renderer. */
|
|
1163
|
+
surface: Record<string, unknown>;
|
|
1164
|
+
/** OPTIONAL model reasoning (RFC 0030 §A), conventionally first. */
|
|
1165
|
+
reasoning?: string;
|
|
1166
|
+
}
|
|
1167
|
+
|
|
945
1168
|
// ── RFC 0027 + RFC 0028 — Prompt library (spec/v1/prompts.md) ──
|
|
946
1169
|
|
|
947
1170
|
/**
|
|
@@ -1401,3 +1624,96 @@ export interface AgentDeploymentTransition {
|
|
|
1401
1624
|
evalRunId?: string;
|
|
1402
1625
|
reason?: string;
|
|
1403
1626
|
}
|
|
1627
|
+
|
|
1628
|
+
// ── RFC 0103 Localized content surface (spec/v1/localized-content.md) ──
|
|
1629
|
+
// Mirror schemas/localized-content-*.schema.json. Host-defined structured
|
|
1630
|
+
// content (`data`, `localizations`, `seo`) is kept open per the schemas
|
|
1631
|
+
// (additionalProperties: true) — it is the host's content model, not a
|
|
1632
|
+
// fixed wire shape.
|
|
1633
|
+
|
|
1634
|
+
export type LocalizedContentStatus = 'draft' | 'published';
|
|
1635
|
+
|
|
1636
|
+
/** A content page record (`schemas/localized-content-page.schema.json`). */
|
|
1637
|
+
export interface LocalizedContentPage {
|
|
1638
|
+
pageId: string;
|
|
1639
|
+
slug: string;
|
|
1640
|
+
/** Human-facing page name (admin/authoring label). */
|
|
1641
|
+
name: string;
|
|
1642
|
+
status: LocalizedContentStatus;
|
|
1643
|
+
/** Ordered section ids composing the page. */
|
|
1644
|
+
sectionOrder: readonly string[];
|
|
1645
|
+
/** Open SEO metadata object (host-defined). */
|
|
1646
|
+
seo?: Record<string, unknown>;
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
/** A content section record (`schemas/localized-content-section.schema.json`).
|
|
1650
|
+
* A section is one record: a base `data` payload + a sparse `localizations`
|
|
1651
|
+
* map (BCP-47 keys, never the base locale). */
|
|
1652
|
+
export interface LocalizedContentSection {
|
|
1653
|
+
sectionId: string;
|
|
1654
|
+
sectionType: string;
|
|
1655
|
+
/** Base-locale field payload (host-defined open shape). */
|
|
1656
|
+
data: Record<string, unknown>;
|
|
1657
|
+
/** Per-locale sparse field overlays, keyed by BCP-47 locale. */
|
|
1658
|
+
localizations: Record<string, Record<string, unknown>>;
|
|
1659
|
+
status: LocalizedContentStatus;
|
|
1660
|
+
enabled: boolean;
|
|
1661
|
+
order: number;
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
/** Public delivery response for `GET /v1/content/pages/{slug}` — the negotiated
|
|
1665
|
+
* locale's resolved page + sections (the RFC 0103 `resolveSection` merge is
|
|
1666
|
+
* applied host-side: exact → language-family → base). */
|
|
1667
|
+
export interface LocalizedContentPageResponse {
|
|
1668
|
+
/** Response schema version marker (e.g. `"1"`). */
|
|
1669
|
+
version: string;
|
|
1670
|
+
generatedAt: string;
|
|
1671
|
+
/** The negotiated locale this response was resolved for. */
|
|
1672
|
+
locale: string;
|
|
1673
|
+
slug: string;
|
|
1674
|
+
page: LocalizedContentPage;
|
|
1675
|
+
sections: readonly LocalizedContentSection[];
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
/** Language settings (`schemas/localized-content-language-settings.schema.json`). */
|
|
1679
|
+
export interface LocalizedContentLanguageSettings {
|
|
1680
|
+
baseLocale: string;
|
|
1681
|
+
supportedLocales: readonly string[];
|
|
1682
|
+
autoTranslateOnPublish: boolean;
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
/** Request body for `PUT /v1/content/pages/{pageId}/sections/{sectionId}`. */
|
|
1686
|
+
export interface PutContentSectionRequest {
|
|
1687
|
+
/** Target locale; the baseLocale upserts `data`, else `localizations[locale]`. */
|
|
1688
|
+
locale: string;
|
|
1689
|
+
/** The field overlay for the target locale (host-defined open shape). */
|
|
1690
|
+
data: Record<string, unknown>;
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
// ── RFC 0099 Trigger subscription registration (spec/v1/trigger-bridge.md §F) ──
|
|
1694
|
+
|
|
1695
|
+
/** Registration body for `POST /v1/trigger-subscriptions`
|
|
1696
|
+
* (`schemas/trigger-subscription-registration.schema.json`). */
|
|
1697
|
+
export interface TriggerSubscriptionRegistration {
|
|
1698
|
+
/** External event source descriptor (host-defined: webhook / email / form …). */
|
|
1699
|
+
source: Record<string, unknown>;
|
|
1700
|
+
workflowId: string;
|
|
1701
|
+
dedupEnabled?: boolean;
|
|
1702
|
+
inputMapping?: Record<string, unknown>;
|
|
1703
|
+
retryPolicy?: Record<string, unknown>;
|
|
1704
|
+
verification?: Record<string, unknown>;
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
/** The persisted trigger subscription the host assigns
|
|
1708
|
+
* (`schemas/trigger-subscription.schema.json`). Kept open beyond the
|
|
1709
|
+
* registration fields the host echoes back. */
|
|
1710
|
+
export type TriggerSubscription = Record<string, unknown>;
|
|
1711
|
+
|
|
1712
|
+
/** `201` response for `POST /v1/trigger-subscriptions`. `binding` carries the
|
|
1713
|
+
* source-specific wiring the caller needs (e.g. `{ ingestUrl,
|
|
1714
|
+
* secretFingerprint }` for webhook); the secret is returned ONCE at creation
|
|
1715
|
+
* (SR-1) — persist it, it is not retrievable again. */
|
|
1716
|
+
export interface CreateTriggerSubscriptionResponse {
|
|
1717
|
+
subscription: TriggerSubscription;
|
|
1718
|
+
binding: Record<string, unknown>;
|
|
1719
|
+
}
|