@company-semantics/contracts 0.27.0 → 0.28.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/package.json +1 -1
- package/src/index.ts +13 -0
- package/src/message-parts/index.ts +15 -0
- package/src/message-parts/lifecycle.ts +147 -0
- package/src/message-parts/wire.ts +55 -0
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -152,6 +152,19 @@ export type {
|
|
|
152
152
|
ExecutionResultData,
|
|
153
153
|
ExecutionResultPart,
|
|
154
154
|
ExecutionResultDataPart,
|
|
155
|
+
// Message lifecycle types (Phase 1 streaming)
|
|
156
|
+
// @see ADR-CONT-027 for design rationale
|
|
157
|
+
StreamPhase,
|
|
158
|
+
MessageLifecycleEventType,
|
|
159
|
+
MessageLifecycleEvent,
|
|
160
|
+
MessageStartEvent,
|
|
161
|
+
MessageDeltaEvent,
|
|
162
|
+
MessageCompleteEvent,
|
|
163
|
+
ToolResultRenderClass,
|
|
164
|
+
ToolResultPart,
|
|
165
|
+
MessageStartDataPart,
|
|
166
|
+
MessageDeltaDataPart,
|
|
167
|
+
MessageCompleteDataPart,
|
|
155
168
|
} from './message-parts/index.js'
|
|
156
169
|
|
|
157
170
|
export {
|
|
@@ -47,6 +47,21 @@ export type {
|
|
|
47
47
|
ExecutionResultDataPart,
|
|
48
48
|
} from './execution.js'
|
|
49
49
|
|
|
50
|
+
// Lifecycle types (Phase 1 streaming)
|
|
51
|
+
export type {
|
|
52
|
+
StreamPhase,
|
|
53
|
+
MessageLifecycleEventType,
|
|
54
|
+
MessageLifecycleEvent,
|
|
55
|
+
MessageStartEvent,
|
|
56
|
+
MessageDeltaEvent,
|
|
57
|
+
MessageCompleteEvent,
|
|
58
|
+
ToolResultRenderClass,
|
|
59
|
+
ToolResultPart,
|
|
60
|
+
MessageStartDataPart,
|
|
61
|
+
MessageDeltaDataPart,
|
|
62
|
+
MessageCompleteDataPart,
|
|
63
|
+
} from './lifecycle.js'
|
|
64
|
+
|
|
50
65
|
// Type guards
|
|
51
66
|
export { isTextPart, isSurfacePart } from './types.js'
|
|
52
67
|
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message Lifecycle Event Vocabulary
|
|
3
|
+
*
|
|
4
|
+
* Explicit lifecycle events for message streaming.
|
|
5
|
+
* Backend is the single authority for message lifecycle state.
|
|
6
|
+
*
|
|
7
|
+
* INVARIANTS:
|
|
8
|
+
* - Every message stream MUST emit: start -> delta* -> complete
|
|
9
|
+
* - messageId MUST be consistent across all events for a single message
|
|
10
|
+
* - version field enables protocol evolution without breaking changes
|
|
11
|
+
*
|
|
12
|
+
* @see ADR-CONT-027 for design rationale
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// Stream Phase
|
|
17
|
+
// =============================================================================
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Derived stream phase for UI state management.
|
|
21
|
+
* Frontend derives this from lifecycle events, not vice versa.
|
|
22
|
+
*
|
|
23
|
+
* - idle: No active stream (initial state, or after complete)
|
|
24
|
+
* - streaming: Between message.start and message.complete
|
|
25
|
+
* - complete: After message.complete received
|
|
26
|
+
*/
|
|
27
|
+
export type StreamPhase = 'idle' | 'streaming' | 'complete'
|
|
28
|
+
|
|
29
|
+
// =============================================================================
|
|
30
|
+
// Lifecycle Event Types
|
|
31
|
+
// =============================================================================
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Lifecycle event type discriminator.
|
|
35
|
+
*/
|
|
36
|
+
export type MessageLifecycleEventType =
|
|
37
|
+
| 'message.start'
|
|
38
|
+
| 'message.delta'
|
|
39
|
+
| 'message.complete'
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Base interface for all message lifecycle events.
|
|
43
|
+
*
|
|
44
|
+
* @property type - Event discriminator
|
|
45
|
+
* @property version - Protocol version (add now, expensive to retrofit later)
|
|
46
|
+
* @property messageId - Correlation identifier for the message
|
|
47
|
+
* @property timestamp - ISO 8601 timestamp of event emission
|
|
48
|
+
*/
|
|
49
|
+
export interface MessageLifecycleEvent {
|
|
50
|
+
type: MessageLifecycleEventType
|
|
51
|
+
version: 1
|
|
52
|
+
messageId: string
|
|
53
|
+
timestamp: string
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Message start event.
|
|
58
|
+
* Emitted when a new message stream begins.
|
|
59
|
+
*/
|
|
60
|
+
export interface MessageStartEvent extends MessageLifecycleEvent {
|
|
61
|
+
type: 'message.start'
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Message delta event.
|
|
66
|
+
* Emitted for each text chunk during streaming.
|
|
67
|
+
* Only contains narrative text, not surface parts.
|
|
68
|
+
*/
|
|
69
|
+
export interface MessageDeltaEvent extends MessageLifecycleEvent {
|
|
70
|
+
type: 'message.delta'
|
|
71
|
+
/** The text delta (narrative content only) */
|
|
72
|
+
delta: string
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Message complete event.
|
|
77
|
+
* Emitted when the message stream ends.
|
|
78
|
+
* Signals that all narrative content has been streamed.
|
|
79
|
+
*/
|
|
80
|
+
export interface MessageCompleteEvent extends MessageLifecycleEvent {
|
|
81
|
+
type: 'message.complete'
|
|
82
|
+
/** Total length of narrative content for validation */
|
|
83
|
+
narrativeLength: number
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// =============================================================================
|
|
87
|
+
// Tool Result Rendering Classification
|
|
88
|
+
// =============================================================================
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Tool result rendering classification.
|
|
92
|
+
* This is protocol metadata, not a UI decision.
|
|
93
|
+
*
|
|
94
|
+
* - inline: Render during streaming (narrative-like)
|
|
95
|
+
* Examples: search snippets, numbers, short text, intermediate reasoning
|
|
96
|
+
* No atomicity guarantee, safe to interleave with text
|
|
97
|
+
*
|
|
98
|
+
* - surface: Render only after message.complete (UI commitment)
|
|
99
|
+
* Examples: tool lists, cards, dashboards, MCP UI components
|
|
100
|
+
* Atomic, deterministic, never stream
|
|
101
|
+
*/
|
|
102
|
+
export type ToolResultRenderClass = 'inline' | 'surface'
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Tool result part with rendering classification.
|
|
106
|
+
*/
|
|
107
|
+
export interface ToolResultPart {
|
|
108
|
+
type: 'tool-result'
|
|
109
|
+
/** Tool identifier */
|
|
110
|
+
toolName: string
|
|
111
|
+
/** Rendering classification */
|
|
112
|
+
render: ToolResultRenderClass
|
|
113
|
+
/** Tool-specific payload */
|
|
114
|
+
payload: unknown
|
|
115
|
+
/** Optional message correlation (enables out-of-band arrival, multi-message chains) */
|
|
116
|
+
messageId?: string
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// =============================================================================
|
|
120
|
+
// Wire Format Types
|
|
121
|
+
// =============================================================================
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Wire format for message start event.
|
|
125
|
+
* Follows AI SDK's data-{name} convention.
|
|
126
|
+
*/
|
|
127
|
+
export interface MessageStartDataPart {
|
|
128
|
+
type: 'data-message-start'
|
|
129
|
+
data: Omit<MessageStartEvent, 'type'>
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Wire format for message delta event.
|
|
134
|
+
* Note: Standard text-delta may be used instead for AI SDK compatibility.
|
|
135
|
+
*/
|
|
136
|
+
export interface MessageDeltaDataPart {
|
|
137
|
+
type: 'data-message-delta'
|
|
138
|
+
data: Omit<MessageDeltaEvent, 'type'>
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Wire format for message complete event.
|
|
143
|
+
*/
|
|
144
|
+
export interface MessageCompleteDataPart {
|
|
145
|
+
type: 'data-message-complete'
|
|
146
|
+
data: Omit<MessageCompleteEvent, 'type'>
|
|
147
|
+
}
|
|
@@ -19,6 +19,10 @@ import type {
|
|
|
19
19
|
ConfirmationResponseDataPart,
|
|
20
20
|
} from './confirmation.js'
|
|
21
21
|
import type { ExecutionResultData, ExecutionResultDataPart } from './execution.js'
|
|
22
|
+
import type {
|
|
23
|
+
MessageStartDataPart,
|
|
24
|
+
MessageCompleteDataPart,
|
|
25
|
+
} from './lifecycle.js'
|
|
22
26
|
|
|
23
27
|
/**
|
|
24
28
|
* Factory for creating wire-format surface parts.
|
|
@@ -119,4 +123,55 @@ export const WireSurfaceBuilder = {
|
|
|
119
123
|
data,
|
|
120
124
|
}
|
|
121
125
|
},
|
|
126
|
+
|
|
127
|
+
// =========================================================================
|
|
128
|
+
// Message Lifecycle Events (Phase 1)
|
|
129
|
+
// =========================================================================
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Build a message start event for streaming.
|
|
133
|
+
* Emit at the beginning of a new message stream.
|
|
134
|
+
*
|
|
135
|
+
* INVARIANTS:
|
|
136
|
+
* - Must be emitted before any text-delta or surface parts
|
|
137
|
+
* - messageId must be consistent across all events for this message
|
|
138
|
+
*
|
|
139
|
+
* @param messageId - Unique identifier for this message
|
|
140
|
+
* @returns Wire-format message start event
|
|
141
|
+
*/
|
|
142
|
+
messageStart(messageId: string): MessageStartDataPart {
|
|
143
|
+
return {
|
|
144
|
+
type: 'data-message-start',
|
|
145
|
+
data: {
|
|
146
|
+
version: 1,
|
|
147
|
+
messageId,
|
|
148
|
+
timestamp: new Date().toISOString(),
|
|
149
|
+
},
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Build a message complete event for streaming.
|
|
155
|
+
* Emit after all narrative content has been streamed.
|
|
156
|
+
*
|
|
157
|
+
* INVARIANTS:
|
|
158
|
+
* - Must be emitted after all text-delta events
|
|
159
|
+
* - Surface parts (if any) should be emitted after this
|
|
160
|
+
* - narrativeLength must match total text content length
|
|
161
|
+
*
|
|
162
|
+
* @param messageId - Message identifier (must match start event)
|
|
163
|
+
* @param narrativeLength - Total length of streamed narrative text
|
|
164
|
+
* @returns Wire-format message complete event
|
|
165
|
+
*/
|
|
166
|
+
messageComplete(messageId: string, narrativeLength: number): MessageCompleteDataPart {
|
|
167
|
+
return {
|
|
168
|
+
type: 'data-message-complete',
|
|
169
|
+
data: {
|
|
170
|
+
version: 1,
|
|
171
|
+
messageId,
|
|
172
|
+
narrativeLength,
|
|
173
|
+
timestamp: new Date().toISOString(),
|
|
174
|
+
},
|
|
175
|
+
}
|
|
176
|
+
},
|
|
122
177
|
} as const
|