@linkshell/wire 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +11 -2
- package/dist/crypto.d.ts +65 -0
- package/dist/crypto.js +253 -0
- package/dist/crypto.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/model.d.ts +704 -0
- package/dist/model.js +163 -0
- package/dist/model.js.map +1 -0
- package/dist/peer.d.ts +42 -0
- package/dist/peer.js +143 -0
- package/dist/peer.js.map +1 -0
- package/dist/relay-client.d.ts +82 -0
- package/dist/relay-client.js +259 -0
- package/dist/relay-client.js.map +1 -0
- package/dist/relay.d.ts +481 -0
- package/dist/relay.js +129 -0
- package/dist/relay.js.map +1 -0
- package/dist/rpc.d.ts +4170 -0
- package/dist/rpc.js +332 -0
- package/dist/rpc.js.map +1 -0
- package/dist/shell.d.ts +2 -0
- package/dist/shell.js +62 -0
- package/dist/shell.js.map +1 -0
- package/dist/updates.d.ts +3325 -0
- package/dist/updates.js +210 -0
- package/dist/updates.js.map +1 -0
- package/package.json +46 -3
- package/src/crypto.ts +290 -0
- package/src/index.ts +8 -0
- package/src/model.ts +195 -0
- package/src/peer.ts +170 -0
- package/src/relay-client.ts +289 -0
- package/src/relay.ts +206 -0
- package/src/rpc.ts +364 -0
- package/src/shell.ts +53 -0
- package/src/updates.ts +233 -0
package/src/updates.ts
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { permissionOptionSchema, sessionDriverSchema, sessionStateSchema, toolKindSchema } from "./model.js";
|
|
3
|
+
|
|
4
|
+
// Session updates mirror ACP's `SessionUpdate` shapes (discriminated by
|
|
5
|
+
// `sessionUpdate`) so one renderer works for every agent. LinkShell-specific
|
|
6
|
+
// updates use the `ls_` prefix.
|
|
7
|
+
|
|
8
|
+
export const contentBlockSchema = z.discriminatedUnion("type", [
|
|
9
|
+
z.object({ type: z.literal("text"), text: z.string() }),
|
|
10
|
+
z.object({
|
|
11
|
+
type: z.literal("image"),
|
|
12
|
+
mimeType: z.string(),
|
|
13
|
+
data: z.string().optional(),
|
|
14
|
+
uri: z.string().optional(),
|
|
15
|
+
}),
|
|
16
|
+
z.object({
|
|
17
|
+
type: z.literal("resource_link"),
|
|
18
|
+
uri: z.string(),
|
|
19
|
+
name: z.string(),
|
|
20
|
+
/** What the link names: a file (default), a skill the user invoked, or another agent. */
|
|
21
|
+
kind: z.enum(["file", "skill", "agent"]).optional(),
|
|
22
|
+
}),
|
|
23
|
+
]);
|
|
24
|
+
export type ContentBlock = z.infer<typeof contentBlockSchema>;
|
|
25
|
+
|
|
26
|
+
export const toolCallStatusSchema = z.enum(["pending", "in_progress", "completed", "failed"]);
|
|
27
|
+
export type ToolCallStatus = z.infer<typeof toolCallStatusSchema>;
|
|
28
|
+
|
|
29
|
+
export const toolCallContentSchema = z.discriminatedUnion("type", [
|
|
30
|
+
z.object({ type: z.literal("content"), content: contentBlockSchema }),
|
|
31
|
+
/** ACP diff: full before/after text. */
|
|
32
|
+
z.object({
|
|
33
|
+
type: z.literal("diff"),
|
|
34
|
+
path: z.string(),
|
|
35
|
+
oldText: z.string().nullable().optional(),
|
|
36
|
+
newText: z.string(),
|
|
37
|
+
}),
|
|
38
|
+
/** Unified diff, for agents (Codex) that report patches rather than file text. */
|
|
39
|
+
z.object({
|
|
40
|
+
type: z.literal("patch"),
|
|
41
|
+
path: z.string(),
|
|
42
|
+
change: z.enum(["add", "delete", "update"]),
|
|
43
|
+
movePath: z.string().optional(),
|
|
44
|
+
diff: z.string(),
|
|
45
|
+
}),
|
|
46
|
+
z.object({ type: z.literal("terminal"), terminalId: z.string() }),
|
|
47
|
+
]);
|
|
48
|
+
export type ToolCallContent = z.infer<typeof toolCallContentSchema>;
|
|
49
|
+
|
|
50
|
+
export const toolCallLocationSchema = z.object({
|
|
51
|
+
path: z.string(),
|
|
52
|
+
line: z.number().int().optional(),
|
|
53
|
+
});
|
|
54
|
+
export type ToolCallLocation = z.infer<typeof toolCallLocationSchema>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* What a tool call is, when the agent tells us more than ACP's coarse `kind`.
|
|
58
|
+
* Host drivers fill it from each agent's own tool names; clients render it the
|
|
59
|
+
* same way for every agent and fall back to `title` + `kind` without it.
|
|
60
|
+
*/
|
|
61
|
+
export const toolDetailSchema = z.discriminatedUnion("type", [
|
|
62
|
+
z.object({ type: z.literal("mcp"), server: z.string(), tool: z.string() }),
|
|
63
|
+
z.object({
|
|
64
|
+
type: z.literal("subagent"),
|
|
65
|
+
/** spawn starts a sub-agent (its work nests under this call); the rest talk to one. */
|
|
66
|
+
action: z.enum(["spawn", "message", "wait", "stop", "resume", "list"]).default("spawn"),
|
|
67
|
+
task: z.string().optional(),
|
|
68
|
+
/** The sub-agent's role or type, e.g. "Explore". */
|
|
69
|
+
agentType: z.string().optional(),
|
|
70
|
+
model: z.string().optional(),
|
|
71
|
+
}),
|
|
72
|
+
z.object({ type: z.literal("skill"), name: z.string(), description: z.string().optional() }),
|
|
73
|
+
z.object({ type: z.literal("web_search"), query: z.string().optional() }),
|
|
74
|
+
z.object({ type: z.literal("image_generation"), prompt: z.string().optional() }),
|
|
75
|
+
z.object({ type: z.literal("compaction") }),
|
|
76
|
+
z.object({ type: z.literal("review"), phase: z.enum(["started", "finished"]) }),
|
|
77
|
+
]);
|
|
78
|
+
export type ToolDetail = z.infer<typeof toolDetailSchema>;
|
|
79
|
+
|
|
80
|
+
export const planEntrySchema = z.object({
|
|
81
|
+
content: z.string(),
|
|
82
|
+
priority: z.enum(["high", "medium", "low"]).default("medium"),
|
|
83
|
+
status: z.enum(["pending", "in_progress", "completed"]),
|
|
84
|
+
});
|
|
85
|
+
export type PlanEntry = z.infer<typeof planEntrySchema>;
|
|
86
|
+
|
|
87
|
+
export const stopReasonSchema = z.enum(["end_turn", "cancelled", "error", "max_tokens", "refusal"]);
|
|
88
|
+
export type StopReason = z.infer<typeof stopReasonSchema>;
|
|
89
|
+
|
|
90
|
+
export const sessionConfigOptionSchema = z.object({
|
|
91
|
+
/** Agent-defined id; "model" and "mode" are the common ones. */
|
|
92
|
+
id: z.string(),
|
|
93
|
+
name: z.string(),
|
|
94
|
+
category: z.enum(["model", "mode", "effort", "other"]).default("other"),
|
|
95
|
+
current: z.string(),
|
|
96
|
+
values: z.array(z.object({ value: z.string(), name: z.string(), description: z.string().optional() })),
|
|
97
|
+
});
|
|
98
|
+
export type SessionConfigOption = z.infer<typeof sessionConfigOptionSchema>;
|
|
99
|
+
|
|
100
|
+
export const sessionUpdateSchema = z.discriminatedUnion("sessionUpdate", [
|
|
101
|
+
z.object({
|
|
102
|
+
sessionUpdate: z.literal("user_message_chunk"),
|
|
103
|
+
messageId: z.string().optional(),
|
|
104
|
+
content: contentBlockSchema,
|
|
105
|
+
}),
|
|
106
|
+
z.object({
|
|
107
|
+
sessionUpdate: z.literal("agent_message_chunk"),
|
|
108
|
+
parentToolCallId: z.string().optional(),
|
|
109
|
+
messageId: z.string(),
|
|
110
|
+
content: contentBlockSchema,
|
|
111
|
+
}),
|
|
112
|
+
z.object({
|
|
113
|
+
sessionUpdate: z.literal("agent_thought_chunk"),
|
|
114
|
+
parentToolCallId: z.string().optional(),
|
|
115
|
+
messageId: z.string(),
|
|
116
|
+
content: contentBlockSchema,
|
|
117
|
+
}),
|
|
118
|
+
z.object({
|
|
119
|
+
sessionUpdate: z.literal("tool_call"),
|
|
120
|
+
toolCallId: z.string(),
|
|
121
|
+
/** Set when a sub-agent made this call: the sub-agent's own (spawn) tool call. */
|
|
122
|
+
parentToolCallId: z.string().optional(),
|
|
123
|
+
title: z.string(),
|
|
124
|
+
kind: toolKindSchema,
|
|
125
|
+
status: toolCallStatusSchema,
|
|
126
|
+
rawInput: z.unknown().optional(),
|
|
127
|
+
content: z.array(toolCallContentSchema).optional(),
|
|
128
|
+
locations: z.array(toolCallLocationSchema).optional(),
|
|
129
|
+
detail: toolDetailSchema.optional(),
|
|
130
|
+
}),
|
|
131
|
+
z.object({
|
|
132
|
+
sessionUpdate: z.literal("tool_call_update"),
|
|
133
|
+
toolCallId: z.string(),
|
|
134
|
+
parentToolCallId: z.string().optional(),
|
|
135
|
+
status: toolCallStatusSchema.optional(),
|
|
136
|
+
title: z.string().optional(),
|
|
137
|
+
detail: toolDetailSchema.optional(),
|
|
138
|
+
/** Replaces the tool call's content when present. */
|
|
139
|
+
content: z.array(toolCallContentSchema).optional(),
|
|
140
|
+
/** Streamed output appended to the tool call's running output. */
|
|
141
|
+
appendOutput: z.string().optional(),
|
|
142
|
+
rawOutput: z.unknown().optional(),
|
|
143
|
+
}),
|
|
144
|
+
z.object({
|
|
145
|
+
sessionUpdate: z.literal("plan"),
|
|
146
|
+
entries: z.array(planEntrySchema),
|
|
147
|
+
}),
|
|
148
|
+
z.object({
|
|
149
|
+
sessionUpdate: z.literal("available_commands_update"),
|
|
150
|
+
availableCommands: z.array(
|
|
151
|
+
z.object({ name: z.string(), description: z.string(), hint: z.string().optional() }),
|
|
152
|
+
),
|
|
153
|
+
}),
|
|
154
|
+
z.object({
|
|
155
|
+
sessionUpdate: z.literal("current_mode_update"),
|
|
156
|
+
currentModeId: z.string(),
|
|
157
|
+
}),
|
|
158
|
+
z.object({
|
|
159
|
+
sessionUpdate: z.literal("session_info_update"),
|
|
160
|
+
title: z.string().optional(),
|
|
161
|
+
model: z.string().optional(),
|
|
162
|
+
}),
|
|
163
|
+
z.object({
|
|
164
|
+
sessionUpdate: z.literal("usage_update"),
|
|
165
|
+
usedTokens: z.number().optional(),
|
|
166
|
+
contextWindow: z.number().optional(),
|
|
167
|
+
}),
|
|
168
|
+
// ── LinkShell extensions ──
|
|
169
|
+
z.object({
|
|
170
|
+
sessionUpdate: z.literal("ls_message_done"),
|
|
171
|
+
parentToolCallId: z.string().optional(),
|
|
172
|
+
messageId: z.string(),
|
|
173
|
+
role: z.enum(["agent", "thought", "user"]),
|
|
174
|
+
}),
|
|
175
|
+
/** Selectable session settings (model, permission mode, effort…) as the agent reports them. */
|
|
176
|
+
z.object({
|
|
177
|
+
sessionUpdate: z.literal("ls_config"),
|
|
178
|
+
options: z.array(sessionConfigOptionSchema),
|
|
179
|
+
}),
|
|
180
|
+
z.object({
|
|
181
|
+
sessionUpdate: z.literal("ls_notice"),
|
|
182
|
+
level: z.enum(["info", "warning"]),
|
|
183
|
+
title: z.string(),
|
|
184
|
+
detail: z.string().optional(),
|
|
185
|
+
}),
|
|
186
|
+
z.object({
|
|
187
|
+
sessionUpdate: z.literal("ls_turn"),
|
|
188
|
+
/** A sub-agent's turn: whether the sub-agent under this call is working. */
|
|
189
|
+
parentToolCallId: z.string().optional(),
|
|
190
|
+
state: z.enum(["started", "ended"]),
|
|
191
|
+
turnId: z.string().optional(),
|
|
192
|
+
stopReason: stopReasonSchema.optional(),
|
|
193
|
+
}),
|
|
194
|
+
z.object({
|
|
195
|
+
sessionUpdate: z.literal("ls_permission"),
|
|
196
|
+
requestId: z.string(),
|
|
197
|
+
toolCallId: z.string().optional(),
|
|
198
|
+
title: z.string(),
|
|
199
|
+
detail: z.string().optional(),
|
|
200
|
+
options: z.array(permissionOptionSchema).min(1),
|
|
201
|
+
}),
|
|
202
|
+
z.object({
|
|
203
|
+
sessionUpdate: z.literal("ls_permission_resolved"),
|
|
204
|
+
requestId: z.string(),
|
|
205
|
+
optionId: z.string().optional(),
|
|
206
|
+
}),
|
|
207
|
+
z.object({
|
|
208
|
+
sessionUpdate: z.literal("ls_driver"),
|
|
209
|
+
driver: sessionDriverSchema,
|
|
210
|
+
deviceId: z.string().optional(),
|
|
211
|
+
}),
|
|
212
|
+
z.object({
|
|
213
|
+
sessionUpdate: z.literal("ls_status"),
|
|
214
|
+
state: sessionStateSchema,
|
|
215
|
+
}),
|
|
216
|
+
z.object({
|
|
217
|
+
sessionUpdate: z.literal("ls_error"),
|
|
218
|
+
code: z.string(),
|
|
219
|
+
message: z.string(),
|
|
220
|
+
hint: z.string().optional(),
|
|
221
|
+
}),
|
|
222
|
+
]);
|
|
223
|
+
export type SessionUpdate = z.infer<typeof sessionUpdateSchema>;
|
|
224
|
+
export type SessionUpdateKind = SessionUpdate["sessionUpdate"];
|
|
225
|
+
|
|
226
|
+
/** One entry in a session's append-only event log. */
|
|
227
|
+
export const sessionEventSchema = z.object({
|
|
228
|
+
sessionId: z.string(),
|
|
229
|
+
seq: z.number().int().positive(),
|
|
230
|
+
ts: z.number(),
|
|
231
|
+
update: sessionUpdateSchema,
|
|
232
|
+
});
|
|
233
|
+
export type SessionEvent = z.infer<typeof sessionEventSchema>;
|