@company-semantics/contracts 0.27.0 → 0.29.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/guards/config.ts +56 -0
- package/src/guards/index.ts +3 -0
- package/src/index.ts +16 -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/guards/config.ts
CHANGED
|
@@ -325,6 +325,62 @@ export interface EvolutionBaselines {
|
|
|
325
325
|
subdirectoryAffinity?: SubdirectoryAffinityBaseline;
|
|
326
326
|
}
|
|
327
327
|
|
|
328
|
+
// =============================================================================
|
|
329
|
+
// Aggregate Evolution Types
|
|
330
|
+
// =============================================================================
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Domain-level aggregate baseline for evolution tracking.
|
|
334
|
+
* Replaces per-file baselines with domain-aggregated metrics.
|
|
335
|
+
*
|
|
336
|
+
* Design: Domains are extracted from file paths (first 2 segments).
|
|
337
|
+
* Example: 'src/chat/execution/types.ts' → domain 'chat/execution'
|
|
338
|
+
*/
|
|
339
|
+
export interface DomainAggregateBaseline {
|
|
340
|
+
/** Total exports across all files in domain */
|
|
341
|
+
exports: number;
|
|
342
|
+
/** Total imports across all files in domain */
|
|
343
|
+
imports: number;
|
|
344
|
+
/** Diagnostic only, not thresholded */
|
|
345
|
+
fileCount: number;
|
|
346
|
+
/** ISO timestamp when baseline was captured */
|
|
347
|
+
capturedAt?: string;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Configuration for aggregate evolution guard.
|
|
352
|
+
* Uses domain-level metrics instead of per-file tracking.
|
|
353
|
+
*
|
|
354
|
+
* Benefits over per-file:
|
|
355
|
+
* - ~22 entries vs ~300 entries
|
|
356
|
+
* - Stable under refactors within domains
|
|
357
|
+
* - Grows O(domains) not O(files)
|
|
358
|
+
*/
|
|
359
|
+
export interface AggregateEvolutionConfig {
|
|
360
|
+
/** Source directory to scan */
|
|
361
|
+
srcDir: string;
|
|
362
|
+
/** Domain baselines keyed by domain path */
|
|
363
|
+
domains: Record<string, DomainAggregateBaseline>;
|
|
364
|
+
/** Global totals for sanity checking */
|
|
365
|
+
totals?: {
|
|
366
|
+
exports: number;
|
|
367
|
+
imports: number;
|
|
368
|
+
files: number;
|
|
369
|
+
capturedAt?: string;
|
|
370
|
+
};
|
|
371
|
+
/** Warning thresholds (sensible defaults applied if omitted) */
|
|
372
|
+
thresholds?: {
|
|
373
|
+
/** Absolute export growth before warning (default: 10) */
|
|
374
|
+
domainExportGrowth?: number;
|
|
375
|
+
/** Percentage growth before warning (default: 0.25 = 25%) */
|
|
376
|
+
domainGrowthPercent?: number;
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// =============================================================================
|
|
381
|
+
// Coverage Baseline Types
|
|
382
|
+
// =============================================================================
|
|
383
|
+
|
|
328
384
|
/**
|
|
329
385
|
* Coverage baseline configuration.
|
|
330
386
|
* Used by CI orchestrator to inject coverage drift guard.
|
package/src/guards/index.ts
CHANGED
|
@@ -54,6 +54,9 @@ export type {
|
|
|
54
54
|
FileClusterBaseline,
|
|
55
55
|
SubdirectoryAffinityBaseline,
|
|
56
56
|
MetaBaselines,
|
|
57
|
+
// Aggregate evolution types
|
|
58
|
+
DomainAggregateBaseline,
|
|
59
|
+
AggregateEvolutionConfig,
|
|
57
60
|
// SOC 2 Guard Configuration types
|
|
58
61
|
SecretsDetectionConfig,
|
|
59
62
|
StructuredLoggingConfig,
|
package/src/index.ts
CHANGED
|
@@ -70,6 +70,9 @@ export type {
|
|
|
70
70
|
ContractsFreshnessBaseline,
|
|
71
71
|
CoverageBaseline,
|
|
72
72
|
MetaBaselines,
|
|
73
|
+
// Aggregate evolution types
|
|
74
|
+
DomainAggregateBaseline,
|
|
75
|
+
AggregateEvolutionConfig,
|
|
73
76
|
// SOC 2 Compliance types
|
|
74
77
|
Soc2ControlArea,
|
|
75
78
|
Soc2ControlStatus,
|
|
@@ -152,6 +155,19 @@ export type {
|
|
|
152
155
|
ExecutionResultData,
|
|
153
156
|
ExecutionResultPart,
|
|
154
157
|
ExecutionResultDataPart,
|
|
158
|
+
// Message lifecycle types (Phase 1 streaming)
|
|
159
|
+
// @see ADR-CONT-027 for design rationale
|
|
160
|
+
StreamPhase,
|
|
161
|
+
MessageLifecycleEventType,
|
|
162
|
+
MessageLifecycleEvent,
|
|
163
|
+
MessageStartEvent,
|
|
164
|
+
MessageDeltaEvent,
|
|
165
|
+
MessageCompleteEvent,
|
|
166
|
+
ToolResultRenderClass,
|
|
167
|
+
ToolResultPart,
|
|
168
|
+
MessageStartDataPart,
|
|
169
|
+
MessageDeltaDataPart,
|
|
170
|
+
MessageCompleteDataPart,
|
|
155
171
|
} from './message-parts/index.js'
|
|
156
172
|
|
|
157
173
|
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
|