forked from nicobailon/pi-mcp-adapter
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathui-stream-types.ts
More file actions
89 lines (75 loc) · 3.79 KB
/
ui-stream-types.ts
File metadata and controls
89 lines (75 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { z } from "zod";
export const UI_STREAM_HOST_CONTEXT_KEY = "pi-mcp-adapter/stream";
export const UI_STREAM_REQUEST_META_KEY = "pi-mcp-adapter/stream-token";
export const UI_STREAM_RESULT_PATCH_METHOD = "notifications/pi-mcp-adapter/ui-result-patch";
export const SERVER_STREAM_RESULT_PATCH_METHOD = "notifications/pi-mcp-adapter/result-patch";
export const UI_STREAM_STRUCTURED_CONTENT_KEY = "pi-mcp-adapter/stream";
export const uiStreamModeSchema = z.enum(["eager", "stream-first"]);
export type UiStreamMode = z.infer<typeof uiStreamModeSchema>;
export const visualizationStreamPhaseSchema = z.enum(["shell", "narrative", "structure", "detail", "settled"]);
export type VisualizationStreamPhase = z.infer<typeof visualizationStreamPhaseSchema>;
export const visualizationStreamFrameTypeSchema = z.enum(["patch", "checkpoint", "final"]);
export type VisualizationStreamFrameType = z.infer<typeof visualizationStreamFrameTypeSchema>;
export const visualizationStreamStatusSchema = z.enum(["ok", "error"]);
export type VisualizationStreamStatus = z.infer<typeof visualizationStreamStatusSchema>;
const looseRecordSchema = z.record(z.string(), z.unknown());
const looseArraySchema = z.array(z.unknown());
export const uiStreamHostContextSchema = z.object({
mode: uiStreamModeSchema,
streamId: z.string().min(1),
intermediateResultPatches: z.boolean(),
partialInput: z.boolean(),
});
export type UiStreamHostContext = z.infer<typeof uiStreamHostContextSchema>;
export const visualizationStreamEnvelopeSchema = z.object({
streamId: z.string().min(1),
sequence: z.number().int().nonnegative(),
frameType: visualizationStreamFrameTypeSchema,
phase: visualizationStreamPhaseSchema,
status: visualizationStreamStatusSchema,
message: z.string().optional(),
spec: looseRecordSchema.optional(),
checkpoint: looseRecordSchema.optional(),
});
export type VisualizationStreamEnvelope = z.infer<typeof visualizationStreamEnvelopeSchema>;
export const uiStreamCallToolResultSchema = z.object({
content: looseArraySchema.optional(),
structuredContent: looseRecordSchema.optional(),
isError: z.boolean().optional(),
_meta: looseRecordSchema.optional(),
}).passthrough();
export type UiStreamCallToolResult = z.infer<typeof uiStreamCallToolResultSchema>;
export const uiStreamResultPatchNotificationSchema = z.object({
method: z.literal(UI_STREAM_RESULT_PATCH_METHOD),
params: uiStreamCallToolResultSchema,
});
export type UiStreamResultPatchNotification = z.infer<typeof uiStreamResultPatchNotificationSchema>;
export const serverStreamResultPatchNotificationSchema = z.object({
method: z.literal(SERVER_STREAM_RESULT_PATCH_METHOD),
params: z.object({
streamToken: z.string().min(1),
result: uiStreamCallToolResultSchema,
}),
});
export type ServerStreamResultPatchNotification = z.infer<typeof serverStreamResultPatchNotificationSchema>;
export interface UiStreamSummary {
streamId: string;
mode: UiStreamMode;
frames: number;
phases: VisualizationStreamPhase[];
finalStatus?: VisualizationStreamStatus;
lastMessage?: string;
}
export function getUiStreamHostContext(hostContext: Record<string, unknown> | undefined): UiStreamHostContext | undefined {
const candidate = hostContext?.[UI_STREAM_HOST_CONTEXT_KEY];
const parsed = uiStreamHostContextSchema.safeParse(candidate);
return parsed.success ? parsed.data : undefined;
}
export function getVisualizationStreamEnvelope(structuredContent: unknown): VisualizationStreamEnvelope | undefined {
if (!structuredContent || typeof structuredContent !== "object" || Array.isArray(structuredContent)) {
return undefined;
}
const candidate = (structuredContent as Record<string, unknown>)[UI_STREAM_STRUCTURED_CONTENT_KEY];
const parsed = visualizationStreamEnvelopeSchema.safeParse(candidate);
return parsed.success ? parsed.data : undefined;
}