feat(vela): retire mocked.turn.trigger from shared contract
This commit is contained in:
@@ -206,6 +206,14 @@ function validateClientMessage(message) {
|
|||||||
return 'message must match the shared envelope shape';
|
return 'message must match the shared envelope shape';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message.type === 'mocked.turn.trigger') {
|
||||||
|
if (!message.payload || typeof message.payload !== 'object' || Array.isArray(message.payload)) {
|
||||||
|
return 'message payload must be an object';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isClientEventType(message.type)) {
|
if (!isClientEventType(message.type)) {
|
||||||
return `unsupported client event type: ${message.type}`;
|
return `unsupported client event type: ${message.type}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,6 +256,15 @@ test('http routes stay available and preserve the root response contract', async
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('shared protocol only exposes currently supported client event types', () => {
|
||||||
|
assert.deepEqual(CLIENT_EVENT_TYPES, [
|
||||||
|
'session.start',
|
||||||
|
'input_audio.append',
|
||||||
|
'input_audio.commit',
|
||||||
|
'response.cancel'
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
test('websocket connect creates and cleans up an ephemeral session', async () => {
|
test('websocket connect creates and cleans up an ephemeral session', async () => {
|
||||||
const server = await startServer();
|
const server = await startServer();
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ const SESSION_STATES = Object.freeze(['idle', 'listening', 'thinking', 'speaking
|
|||||||
|
|
||||||
const CLIENT_EVENT_TYPES = Object.freeze([
|
const CLIENT_EVENT_TYPES = Object.freeze([
|
||||||
'session.start',
|
'session.start',
|
||||||
'mocked.turn.trigger',
|
|
||||||
'input_audio.append',
|
'input_audio.append',
|
||||||
'input_audio.commit',
|
'input_audio.commit',
|
||||||
'response.cancel'
|
'response.cancel'
|
||||||
|
|||||||
1
apps/vela-protocol/src/index.d.ts
vendored
1
apps/vela-protocol/src/index.d.ts
vendored
@@ -7,7 +7,6 @@ export type MessageEnvelope<TType extends string, TPayload> = {
|
|||||||
|
|
||||||
export type ClientEventPayloads = {
|
export type ClientEventPayloads = {
|
||||||
'session.start': Record<string, never>;
|
'session.start': Record<string, never>;
|
||||||
'mocked.turn.trigger': Record<string, never>;
|
|
||||||
'input_audio.append': {
|
'input_audio.append': {
|
||||||
chunk: string;
|
chunk: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ export const SESSION_STATES = Object.freeze(['idle', 'listening', 'thinking', 's
|
|||||||
|
|
||||||
export const CLIENT_EVENT_TYPES = Object.freeze([
|
export const CLIENT_EVENT_TYPES = Object.freeze([
|
||||||
'session.start',
|
'session.start',
|
||||||
'mocked.turn.trigger',
|
|
||||||
'input_audio.append',
|
'input_audio.append',
|
||||||
'input_audio.commit',
|
'input_audio.commit',
|
||||||
'response.cancel'
|
'response.cancel'
|
||||||
|
|||||||
@@ -184,6 +184,7 @@ Polish the system after the core voice loop is reliable.
|
|||||||
- `apps/vela-ui` now boots as a minimal SvelteKit app with a starter page
|
- `apps/vela-ui` now boots as a minimal SvelteKit app with a starter page
|
||||||
- `apps/vela-ui` now includes a minimal voice-session shell that can connect to the gateway `/ws` endpoint and display developer-visible session status
|
- `apps/vela-ui` now includes a minimal voice-session shell that can connect to the gateway `/ws` endpoint and display developer-visible session status
|
||||||
- `apps/vela-ui` now exposes a visible push-to-talk mic control shell that sends placeholder `input_audio.append` / `input_audio.commit` events without requesting browser mic permission or capturing real audio
|
- `apps/vela-ui` now exposes a visible push-to-talk mic control shell that sends placeholder `input_audio.append` / `input_audio.commit` events without requesting browser mic permission or capturing real audio
|
||||||
|
- placeholder push-to-talk via `input_audio.append` + `input_audio.commit` is now the only supported mocked turn entry path in the shared client protocol contract
|
||||||
- `apps/vela-ui` now includes browser-level coverage for the placeholder push-to-talk mocked transcript/response slice, including connect, disconnect, and cancel behavior
|
- `apps/vela-ui` now includes browser-level coverage for the placeholder push-to-talk mocked transcript/response slice, including connect, disconnect, and cancel behavior
|
||||||
- `apps/vela-gateway` now boots as a minimal Fastify app with `/` and `/health` endpoints
|
- `apps/vela-gateway` now boots as a minimal Fastify app with `/` and `/health` endpoints
|
||||||
- `apps/vela-gateway` now exposes a minimal `/ws` WebSocket session skeleton with ephemeral in-memory sessions and defensive message handling
|
- `apps/vela-gateway` now exposes a minimal `/ws` WebSocket session skeleton with ephemeral in-memory sessions and defensive message handling
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ This increment intentionally keeps the envelope minimal:
|
|||||||
```ts
|
```ts
|
||||||
type ClientEvent =
|
type ClientEvent =
|
||||||
| { type: "session.start"; payload: {} }
|
| { type: "session.start"; payload: {} }
|
||||||
| { type: "mocked.turn.trigger"; payload: {} }
|
|
||||||
| { type: "input_audio.append"; payload: { chunk: string } }
|
| { type: "input_audio.append"; payload: { chunk: string } }
|
||||||
| { type: "input_audio.commit"; payload: {} }
|
| { type: "input_audio.commit"; payload: {} }
|
||||||
| { type: "response.cancel"; payload: {} };
|
| { type: "response.cancel"; payload: {} };
|
||||||
@@ -50,11 +49,15 @@ type ClientEvent =
|
|||||||
#### Client event intent
|
#### Client event intent
|
||||||
|
|
||||||
- `session.start` initializes a voice session without locking in transport or auth details yet
|
- `session.start` initializes a voice session without locking in transport or auth details yet
|
||||||
- `mocked.turn.trigger` is a retired legacy event name that the gateway now rejects with a deterministic recoverable error
|
|
||||||
- `input_audio.append` carries a chunk of captured input audio as an encoded string
|
- `input_audio.append` carries a chunk of captured input audio as an encoded string
|
||||||
- `input_audio.commit` marks the current buffered user turn as ready for downstream processing
|
- `input_audio.commit` marks the current buffered user turn as ready for downstream processing
|
||||||
- `response.cancel` interrupts the active listen/think/speak flow
|
- `response.cancel` interrupts the active listen/think/speak flow
|
||||||
|
|
||||||
|
Legacy compatibility note:
|
||||||
|
|
||||||
|
- `mocked.turn.trigger` is no longer part of the active shared client contract
|
||||||
|
- the gateway still handles raw incoming `mocked.turn.trigger` envelopes explicitly and rejects them with a deterministic recoverable error for backward compatibility
|
||||||
|
|
||||||
### Current skeleton behavior
|
### Current skeleton behavior
|
||||||
|
|
||||||
- on connect, the gateway creates an ephemeral in-memory session and emits `session.ready` plus `session.state`
|
- on connect, the gateway creates an ephemeral in-memory session and emits `session.ready` plus `session.state`
|
||||||
|
|||||||
Reference in New Issue
Block a user