@dyyz1993/pi-coding-agent 0.74.24 → 0.74.25
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/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +3 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/extensions/agent-permissions/index.ts +235 -0
- package/dist/extensions/ask-tools/index.ts +115 -0
- package/dist/extensions/auto-memory/contract.d.ts +51 -0
- package/dist/extensions/auto-memory/contract.d.ts.map +1 -0
- package/dist/extensions/auto-memory/contract.js +2 -0
- package/dist/extensions/auto-memory/contract.js.map +1 -0
- package/dist/extensions/auto-memory/contract.ts +56 -0
- package/dist/extensions/auto-memory/index.ts +969 -0
- package/dist/extensions/auto-memory/prompts.ts +202 -0
- package/dist/extensions/auto-memory/skip-rules.ts +297 -0
- package/dist/extensions/auto-memory/utils.ts +208 -0
- package/dist/extensions/auto-session-title/index.ts +83 -0
- package/dist/extensions/bash-ext/contract.d.ts +79 -0
- package/dist/extensions/bash-ext/contract.d.ts.map +1 -0
- package/dist/extensions/bash-ext/contract.js +2 -0
- package/dist/extensions/bash-ext/contract.js.map +1 -0
- package/dist/extensions/bash-ext/contract.ts +69 -0
- package/dist/extensions/bash-ext/index.ts +858 -0
- package/dist/extensions/claude-hooks-compat/config-loader.ts +49 -0
- package/dist/extensions/claude-hooks-compat/handler-runner.ts +377 -0
- package/dist/extensions/claude-hooks-compat/if-parser.ts +53 -0
- package/dist/extensions/claude-hooks-compat/index.ts +178 -0
- package/dist/extensions/claude-hooks-compat/matcher.ts +17 -0
- package/dist/extensions/claude-hooks-compat/stdin-builder.ts +27 -0
- package/dist/extensions/claude-hooks-compat/types.ts +77 -0
- package/dist/extensions/compaction-manager/config.ts +47 -0
- package/dist/extensions/compaction-manager/context-fold.ts +63 -0
- package/dist/extensions/compaction-manager/index.ts +151 -0
- package/dist/extensions/compaction-manager/microcompact.ts +49 -0
- package/dist/extensions/compaction-manager/reactive.ts +9 -0
- package/dist/extensions/compaction-manager/session-memory.ts +48 -0
- package/dist/extensions/coordinator/INTEGRATION.md +376 -0
- package/dist/extensions/coordinator/handler.test.ts +277 -0
- package/dist/extensions/coordinator/handler.ts +189 -0
- package/dist/extensions/coordinator/index.ts +261 -0
- package/dist/extensions/coordinator/types.d.ts +100 -0
- package/dist/extensions/coordinator/types.d.ts.map +1 -0
- package/dist/extensions/coordinator/types.js +2 -0
- package/dist/extensions/coordinator/types.js.map +1 -0
- package/dist/extensions/coordinator/types.ts +72 -0
- package/dist/extensions/file-snapshot/index.ts +131 -0
- package/dist/extensions/file-time-guard/README.md +133 -0
- package/dist/extensions/file-time-guard/config.ts +13 -0
- package/dist/extensions/file-time-guard/index.ts +171 -0
- package/dist/extensions/hooks-engine/index.ts +117 -0
- package/dist/extensions/lsp/lsp/client/file-tracker.ts +70 -0
- package/dist/extensions/lsp/lsp/client/registry.ts +305 -0
- package/dist/extensions/lsp/lsp/client/runtime.ts +832 -0
- package/dist/extensions/lsp/lsp/config/resolver.ts +573 -0
- package/dist/extensions/lsp/lsp/contract.d.ts +101 -0
- package/dist/extensions/lsp/lsp/contract.d.ts.map +1 -0
- package/dist/extensions/lsp/lsp/contract.js +2 -0
- package/dist/extensions/lsp/lsp/contract.js.map +1 -0
- package/dist/extensions/lsp/lsp/contract.ts +103 -0
- package/dist/extensions/lsp/lsp/hooks/agent-end.ts +169 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.d.ts +10 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.d.ts.map +1 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.js +30 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.js.map +1 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.ts +41 -0
- package/dist/extensions/lsp/lsp/hooks/writethrough.ts +342 -0
- package/dist/extensions/lsp/lsp/index.ts +307 -0
- package/dist/extensions/lsp/lsp/lsp.test.ts +684 -0
- package/dist/extensions/lsp/lsp/monitoring/server-metrics.ts +176 -0
- package/dist/extensions/lsp/lsp/tools/lsp-tool.ts +402 -0
- package/dist/extensions/lsp/lsp/utils/dependency-resolver.ts +147 -0
- package/dist/extensions/lsp/lsp/utils/diagnostics-wait.ts +41 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.d.ts +20 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.d.ts.map +1 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.js +64 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.js.map +1 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.ts +76 -0
- package/dist/extensions/message-bridge/GUIDE.md +210 -0
- package/dist/extensions/message-bridge/index.ts +222 -0
- package/dist/extensions/output-guard/index.ts +384 -0
- package/dist/extensions/preview/index.ts +278 -0
- package/dist/extensions/rules-engine/MATCH_HISTORY_RECONCILIATION.md +111 -0
- package/dist/extensions/rules-engine/RULES-ENGINE-GUIDE.md +470 -0
- package/dist/extensions/rules-engine/cache.js +232 -0
- package/dist/extensions/rules-engine/cache.ts +38 -0
- package/dist/extensions/rules-engine/config.js +63 -0
- package/dist/extensions/rules-engine/config.ts +70 -0
- package/dist/extensions/rules-engine/index.js +1530 -0
- package/dist/extensions/rules-engine/index.ts +552 -0
- package/dist/extensions/rules-engine/injector.js +68 -0
- package/dist/extensions/rules-engine/injector.ts +74 -0
- package/dist/extensions/rules-engine/loader.js +179 -0
- package/dist/extensions/rules-engine/loader.ts +205 -0
- package/dist/extensions/rules-engine/matcher.js +534 -0
- package/dist/extensions/rules-engine/matcher.ts +52 -0
- package/dist/extensions/rules-engine/types.d.ts +156 -0
- package/dist/extensions/rules-engine/types.d.ts.map +1 -0
- package/dist/extensions/rules-engine/types.js +2 -0
- package/dist/extensions/rules-engine/types.js.map +1 -0
- package/dist/extensions/rules-engine/types.ts +169 -0
- package/dist/extensions/session-supervisor/checker.ts +116 -0
- package/dist/extensions/session-supervisor/config.ts +45 -0
- package/dist/extensions/session-supervisor/index.ts +726 -0
- package/dist/extensions/session-supervisor/prompts.ts +132 -0
- package/dist/extensions/session-supervisor/scheduler.ts +69 -0
- package/dist/extensions/session-supervisor/types.ts +215 -0
- package/dist/extensions/subagent/README.md +172 -0
- package/dist/extensions/subagent/agents/explorer.md +25 -0
- package/dist/extensions/subagent/agents/guide.md +27 -0
- package/dist/extensions/subagent/agents/planner.md +37 -0
- package/dist/extensions/subagent/agents/reviewer.md +35 -0
- package/dist/extensions/subagent/agents/scout.md +50 -0
- package/dist/extensions/subagent/agents/verification.md +35 -0
- package/dist/extensions/subagent/agents/worker.md +24 -0
- package/dist/extensions/subagent/agents.ts +25 -0
- package/dist/extensions/subagent/index.ts +987 -0
- package/dist/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/dist/extensions/subagent/prompts/implement.md +10 -0
- package/dist/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/dist/extensions/subagent-ext/contract.d.ts +2 -0
- package/dist/extensions/subagent-ext/contract.d.ts.map +1 -0
- package/dist/extensions/subagent-ext/contract.js +2 -0
- package/dist/extensions/subagent-ext/contract.js.map +1 -0
- package/dist/extensions/subagent-ext/contract.ts +1 -0
- package/dist/extensions/subagent-ext/index.ts +347 -0
- package/dist/extensions/subagent-shared/contract.d.ts +25 -0
- package/dist/extensions/subagent-shared/contract.d.ts.map +1 -0
- package/dist/extensions/subagent-shared/contract.js +2 -0
- package/dist/extensions/subagent-shared/contract.js.map +1 -0
- package/dist/extensions/subagent-shared/contract.ts +28 -0
- package/dist/extensions/subagent-shared/index.ts +4 -0
- package/dist/extensions/subagent-shared/render.ts +166 -0
- package/dist/extensions/subagent-shared/types.ts +35 -0
- package/dist/extensions/subagent-shared/utils.ts +112 -0
- package/dist/extensions/subagent-v2/contract.d.ts +2 -0
- package/dist/extensions/subagent-v2/contract.d.ts.map +1 -0
- package/dist/extensions/subagent-v2/contract.js +2 -0
- package/dist/extensions/subagent-v2/contract.js.map +1 -0
- package/dist/extensions/subagent-v2/contract.ts +1 -0
- package/dist/extensions/subagent-v2/index.ts +599 -0
- package/dist/extensions/todo-ext/contract.d.ts +27 -0
- package/dist/extensions/todo-ext/contract.d.ts.map +1 -0
- package/dist/extensions/todo-ext/contract.js +2 -0
- package/dist/extensions/todo-ext/contract.js.map +1 -0
- package/dist/extensions/todo-ext/contract.ts +30 -0
- package/dist/extensions/todo-ext/index.ts +419 -0
- package/package.json +6 -5
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import type { ServerChannel } from "@dyyz1993/pi-coding-agent";
|
|
4
|
+
import type { CoordinatorChannelContract, DelegatedTask, SessionStatus } from "./types.js";
|
|
5
|
+
|
|
6
|
+
export interface ProcessManagerApi {
|
|
7
|
+
delegate(task: string, projectPath: string): Promise<{ sessionId: string; status: "started" | "already_running" }>;
|
|
8
|
+
delegate_send(fromSessionId: string, toSessionId: string, message: string): Promise<{ delivered: boolean; targetStatus: "active" | "started" | "not_found" }>;
|
|
9
|
+
delegate_status(sessionId: string): Promise<{ status: SessionStatus }>;
|
|
10
|
+
delegate_list(): Promise<Array<{ sessionId: string; status: SessionStatus; projectPath: string }>>;
|
|
11
|
+
delegate_stop(sessionId: string): Promise<boolean>;
|
|
12
|
+
delegate_fork(sessionId: string, task: string, title?: string): Promise<{ sessionId: string; status: "started" | "already_running" }>;
|
|
13
|
+
delegate_compact_status(sessionId: string): Promise<{ isCompacting: boolean; contextUsage: { tokens: number | null; contextWindow: number; percent: number | null } }>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class TaskStore {
|
|
17
|
+
private filePath: string;
|
|
18
|
+
private tasks = new Map<string, DelegatedTask>();
|
|
19
|
+
|
|
20
|
+
constructor(sessionDir: string) {
|
|
21
|
+
this.filePath = path.join(sessionDir, "coordinator-tasks.json");
|
|
22
|
+
this.load();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private load(): void {
|
|
26
|
+
try {
|
|
27
|
+
if (fs.existsSync(this.filePath)) {
|
|
28
|
+
const raw = fs.readFileSync(this.filePath, "utf-8");
|
|
29
|
+
const arr = JSON.parse(raw) as DelegatedTask[];
|
|
30
|
+
for (const task of arr) {
|
|
31
|
+
this.tasks.set(task.sessionId, task);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
console.debug("[coordinator] task file load failed:", err instanceof Error ? err.message : err);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private save(): void {
|
|
41
|
+
const arr = Array.from(this.tasks.values());
|
|
42
|
+
fs.writeFileSync(this.filePath, JSON.stringify(arr, null, 2), "utf-8");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
add(task: DelegatedTask): void {
|
|
46
|
+
this.tasks.set(task.sessionId, task);
|
|
47
|
+
this.save();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get(sessionId: string): DelegatedTask | undefined {
|
|
51
|
+
return this.tasks.get(sessionId);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
update(sessionId: string, patch: Partial<DelegatedTask>): void {
|
|
55
|
+
const existing = this.tasks.get(sessionId);
|
|
56
|
+
if (!existing) return;
|
|
57
|
+
Object.assign(existing, patch);
|
|
58
|
+
this.save();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
remove(sessionId: string): void {
|
|
62
|
+
this.tasks.delete(sessionId);
|
|
63
|
+
this.save();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
list(): DelegatedTask[] {
|
|
67
|
+
return Array.from(this.tasks.values());
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
buildPrompt(): string {
|
|
71
|
+
const tasks = this.list();
|
|
72
|
+
if (tasks.length === 0) return "";
|
|
73
|
+
|
|
74
|
+
const lines = ["## Delegated Tasks", ""];
|
|
75
|
+
for (const t of tasks) {
|
|
76
|
+
const status = t.status === "completed" ? "DONE" : t.status === "stopped" ? "STOPPED" : t.status.toUpperCase();
|
|
77
|
+
const compactTag = (t as any).isCompacting ? " COMPACTING" : "";
|
|
78
|
+
const ctxTag = (t as any).contextUsage?.percent != null ? ` ctx:${Math.round((t as any).contextUsage.percent)}%` : "";
|
|
79
|
+
const elapsed = t.completedAt
|
|
80
|
+
? `${((t.completedAt - t.dispatchedAt) / 1000).toFixed(1)}s`
|
|
81
|
+
: `${((Date.now() - t.dispatchedAt) / 1000).toFixed(0)}s elapsed`;
|
|
82
|
+
lines.push(`- **${t.title}** (id: \`${t.sessionId}\`) — ${status}${compactTag}${ctxTag} — ${elapsed}`);
|
|
83
|
+
if (t.result) {
|
|
84
|
+
const preview = t.result.length > 200 ? `${t.result.slice(0, 200)}...` : t.result;
|
|
85
|
+
lines.push(` > ${preview}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return lines.join("\n");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function createCoordinatorHandler(
|
|
93
|
+
channel: ServerChannel<CoordinatorChannelContract>,
|
|
94
|
+
pm: ProcessManagerApi,
|
|
95
|
+
getSessionId: () => string,
|
|
96
|
+
getStore: () => TaskStore,
|
|
97
|
+
): void {
|
|
98
|
+
channel.handle("session_delegate", async (params: unknown) => {
|
|
99
|
+
const { task, title } = params as { task: string; title?: string };
|
|
100
|
+
const projectPath = process.cwd();
|
|
101
|
+
const result = await pm.delegate(task, projectPath);
|
|
102
|
+
|
|
103
|
+
getStore().add({
|
|
104
|
+
sessionId: result.sessionId,
|
|
105
|
+
title: title || task.slice(0, 60),
|
|
106
|
+
task,
|
|
107
|
+
projectPath,
|
|
108
|
+
dispatchedAt: Date.now(),
|
|
109
|
+
status: "idle",
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
channel.emit("task_started", {
|
|
113
|
+
sessionId: result.sessionId,
|
|
114
|
+
title: title || task.slice(0, 60),
|
|
115
|
+
task,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return result;
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
channel.handle("session_delegate_send", async (params: unknown) => {
|
|
122
|
+
const { targetSessionId, message } = params as { targetSessionId: string; message: string };
|
|
123
|
+
const result = await pm.delegate_send(getSessionId(), targetSessionId, message);
|
|
124
|
+
|
|
125
|
+
if (result.delivered) {
|
|
126
|
+
const store = getStore();
|
|
127
|
+
const task = store.get(targetSessionId);
|
|
128
|
+
if (task && task.status === "stopped") {
|
|
129
|
+
store.update(targetSessionId, { status: "idle" });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return result;
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
channel.handle("session_delegate_status", async (params: unknown) => {
|
|
137
|
+
const { sessionId } = params as { sessionId: string };
|
|
138
|
+
const store = getStore();
|
|
139
|
+
const task = store.get(sessionId);
|
|
140
|
+
if (!task) {
|
|
141
|
+
await pm.delegate_status(sessionId);
|
|
142
|
+
return { task: null };
|
|
143
|
+
}
|
|
144
|
+
const remote = await pm.delegate_status(sessionId);
|
|
145
|
+
store.update(sessionId, { status: remote.status });
|
|
146
|
+
const compactInfo = await pm.delegate_compact_status(sessionId);
|
|
147
|
+
return { task: store.get(sessionId) ?? null, isCompacting: compactInfo.isCompacting, contextUsage: compactInfo.contextUsage };
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
channel.handle("session_delegate_list", async () => {
|
|
151
|
+
const store = getStore();
|
|
152
|
+
for (const t of store.list()) {
|
|
153
|
+
const remote = await pm.delegate_status(t.sessionId);
|
|
154
|
+
store.update(t.sessionId, { status: remote.status });
|
|
155
|
+
}
|
|
156
|
+
return { tasks: store.list() };
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
channel.handle("session_delegate_stop", async (params: unknown) => {
|
|
160
|
+
const { sessionId } = params as { sessionId: string };
|
|
161
|
+
const ok = await pm.delegate_stop(sessionId);
|
|
162
|
+
if (ok) {
|
|
163
|
+
getStore().update(sessionId, { status: "stopped" });
|
|
164
|
+
channel.emit("task_stopped", { sessionId });
|
|
165
|
+
}
|
|
166
|
+
return { ok };
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
channel.handle("session_delegate_fork", async (params: unknown) => {
|
|
170
|
+
const { sessionId, task, title } = params as { sessionId: string; task: string; title?: string };
|
|
171
|
+
const result = await pm.delegate_fork(sessionId, task, title);
|
|
172
|
+
getStore().add({
|
|
173
|
+
sessionId: result.sessionId,
|
|
174
|
+
title: title || task.slice(0, 60),
|
|
175
|
+
task,
|
|
176
|
+
projectPath: process.cwd(),
|
|
177
|
+
dispatchedAt: Date.now(),
|
|
178
|
+
status: "idle",
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
channel.emit("task_started", {
|
|
182
|
+
sessionId: result.sessionId,
|
|
183
|
+
title: title || task.slice(0, 60),
|
|
184
|
+
task,
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
return result;
|
|
188
|
+
});
|
|
189
|
+
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createTypedChannel,
|
|
3
|
+
type ExtensionAPI,
|
|
4
|
+
} from "@dyyz1993/pi-coding-agent";
|
|
5
|
+
import { Type } from "typebox";
|
|
6
|
+
import { COORDINATOR_CHANNEL_NAME, type CoordinatorChannelContract, type SessionStatus } from "./types.js";
|
|
7
|
+
import { createCoordinatorHandler, TaskStore, type ProcessManagerApi } from "./handler.js";
|
|
8
|
+
|
|
9
|
+
const DelegateParams = Type.Object({
|
|
10
|
+
task: Type.String({ description: "Task description to delegate to the background session" }),
|
|
11
|
+
title: Type.Optional(Type.String({ description: "Short title for this delegated task" })),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const DelegateSendParams = Type.Object({
|
|
15
|
+
targetSessionId: Type.String({ description: "Session ID to send the message to" }),
|
|
16
|
+
message: Type.String({ description: "Message content to send" }),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const DelegateStatusParams = Type.Object({
|
|
20
|
+
sessionId: Type.String({ description: "Session ID to check status for" }),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const DelegateStopParams = Type.Object({
|
|
24
|
+
sessionId: Type.String({ description: "Session ID to stop" }),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const DelegateForkParams = Type.Object({
|
|
28
|
+
sessionId: Type.String({ description: "Source session ID to fork from" }),
|
|
29
|
+
task: Type.String({ description: "Task description for the forked session" }),
|
|
30
|
+
title: Type.Optional(Type.String({ description: "Short title for the forked task" })),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export default function coordinatorExtension(pi: ExtensionAPI) {
|
|
34
|
+
const rawChannel = pi.registerChannel(COORDINATOR_CHANNEL_NAME);
|
|
35
|
+
|
|
36
|
+
const { server: serverChannel, client } = createTypedChannel<CoordinatorChannelContract>(rawChannel);
|
|
37
|
+
|
|
38
|
+
let currentSessionId = "";
|
|
39
|
+
let store: TaskStore | null = null;
|
|
40
|
+
|
|
41
|
+
pi.on("session_start", (_event, ctx) => {
|
|
42
|
+
currentSessionId = ctx.sessionManager.getSessionId();
|
|
43
|
+
store = new TaskStore(ctx.sessionManager.getSessionDir());
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const serverProxy: ProcessManagerApi = {
|
|
47
|
+
async delegate(task, _projectPath) {
|
|
48
|
+
return client.call("session_delegate", { task }) as Promise<{ sessionId: string; status: "started" | "already_running" }>;
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
async delegate_send(fromSessionId, toSessionId, message) {
|
|
52
|
+
return client.call("session_delegate_send", {
|
|
53
|
+
targetSessionId: toSessionId,
|
|
54
|
+
message,
|
|
55
|
+
}) as Promise<{ delivered: boolean; targetStatus: "active" | "started" | "not_found" }>;
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
async delegate_status(sessionId) {
|
|
59
|
+
try {
|
|
60
|
+
const result = await client.call("session_delegate_status", { sessionId }) as { task: { status: string } | null };
|
|
61
|
+
return result.task ? { status: result.task.status as SessionStatus } : { status: "stopped" as const };
|
|
62
|
+
} catch (err) {
|
|
63
|
+
console.debug("[coordinator] delegate_status failed:", err instanceof Error ? err.message : err);
|
|
64
|
+
return { status: "stopped" as const };
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
async delegate_list() {
|
|
69
|
+
try {
|
|
70
|
+
const result = await client.call("session_delegate_list", {}) as { tasks: Array<{ sessionId: string; status: SessionStatus; projectPath: string }> };
|
|
71
|
+
return result.tasks;
|
|
72
|
+
} catch (err) {
|
|
73
|
+
console.debug("[coordinator] delegate_list failed:", err instanceof Error ? err.message : err);
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
async delegate_stop(sessionId) {
|
|
79
|
+
try {
|
|
80
|
+
const result = await client.call("session_delegate_stop", { sessionId }) as { ok: boolean };
|
|
81
|
+
return result.ok;
|
|
82
|
+
} catch (err) {
|
|
83
|
+
console.debug("[coordinator] delegate_stop failed:", err instanceof Error ? err.message : err);
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
async delegate_fork(sessionId, task, title) {
|
|
89
|
+
return client.call("session_delegate_fork", { sessionId, task, title }) as Promise<{ sessionId: string; status: "started" | "already_running" }>;
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
async delegate_compact_status(sessionId: string) {
|
|
93
|
+
try {
|
|
94
|
+
const result = await client.call("session_delegate_status", { sessionId }) as { isCompacting?: boolean; contextUsage?: { tokens: number | null; contextWindow: number; percent: number | null } };
|
|
95
|
+
return {
|
|
96
|
+
isCompacting: result.isCompacting ?? false,
|
|
97
|
+
contextUsage: result.contextUsage ?? { tokens: null as number | null, contextWindow: 0, percent: null as number | null },
|
|
98
|
+
};
|
|
99
|
+
} catch (err) {
|
|
100
|
+
console.debug("[coordinator] delegate_compact_status failed:", err instanceof Error ? err.message : err);
|
|
101
|
+
return { isCompacting: false, contextUsage: { tokens: null as number | null, contextWindow: 0, percent: null as number | null } };
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
createCoordinatorHandler(
|
|
107
|
+
serverChannel,
|
|
108
|
+
serverProxy,
|
|
109
|
+
() => currentSessionId,
|
|
110
|
+
() => store ?? new TaskStore("/tmp/coordinator-fallback"),
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
pi.on("context", (event, _ctx) => {
|
|
114
|
+
if (!store) return;
|
|
115
|
+
const prompt = store.buildPrompt();
|
|
116
|
+
if (prompt) {
|
|
117
|
+
event.messages.push({
|
|
118
|
+
role: "user",
|
|
119
|
+
content: [{ type: "text", text: prompt }],
|
|
120
|
+
timestamp: Date.now(),
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
pi.registerTool({
|
|
126
|
+
name: "session_delegate",
|
|
127
|
+
label: "Session Delegate",
|
|
128
|
+
description: [
|
|
129
|
+
"Delegate a task to a background pi session.",
|
|
130
|
+
"Returns a sessionId for communication via session_delegate_send.",
|
|
131
|
+
"The delegated session can message back using its own coordinator channel.",
|
|
132
|
+
"The delegate session is automatically restarted if inactive when receiving messages.",
|
|
133
|
+
].join(" "),
|
|
134
|
+
parameters: DelegateParams,
|
|
135
|
+
async execute(toolCallId, params, _signal, _onUpdate, ctx) {
|
|
136
|
+
const sid = currentSessionId || ctx.sessionManager.getSessionId();
|
|
137
|
+
const result = await serverProxy.delegate(params.task, ctx.cwd);
|
|
138
|
+
|
|
139
|
+
if (store) {
|
|
140
|
+
store.add({
|
|
141
|
+
sessionId: result.sessionId,
|
|
142
|
+
title: params.title || params.task.slice(0, 60),
|
|
143
|
+
task: params.task,
|
|
144
|
+
projectPath: ctx.cwd,
|
|
145
|
+
dispatchedAt: Date.now(),
|
|
146
|
+
status: "idle",
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
content: [{ type: "text" as const, text: `Delegated task to session ${result.sessionId} (status: ${result.status}). Use session_delegate_send to communicate.` }],
|
|
152
|
+
details: { ...result, dispatchedBy: sid },
|
|
153
|
+
};
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
pi.registerTool({
|
|
158
|
+
name: "session_delegate_send",
|
|
159
|
+
label: "Session Delegate Send",
|
|
160
|
+
description: [
|
|
161
|
+
"Send a message to a delegated session by sessionId.",
|
|
162
|
+
"If the target session is not active, the server will automatically restart it",
|
|
163
|
+
"(same as clicking on the session in the UI) and deliver the message.",
|
|
164
|
+
"The message is injected as a followUp into the target session.",
|
|
165
|
+
"This tool only fails if the session file has been physically deleted from disk.",
|
|
166
|
+
].join(" "),
|
|
167
|
+
parameters: DelegateSendParams,
|
|
168
|
+
async execute(toolCallId, params, _signal, _onUpdate, ctx) {
|
|
169
|
+
const sid = currentSessionId || ctx.sessionManager.getSessionId();
|
|
170
|
+
const result = await serverProxy.delegate_send(sid, params.targetSessionId, params.message);
|
|
171
|
+
|
|
172
|
+
if (!result.delivered) {
|
|
173
|
+
return {
|
|
174
|
+
content: [{ type: "text" as const, text: `Could not deliver message to ${params.targetSessionId}: session not found (the session file may have been deleted from disk)` }],
|
|
175
|
+
details: { delivered: false, targetSessionId: params.targetSessionId },
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
content: [{ type: "text" as const, text: `Message delivered to ${params.targetSessionId} (status: ${result.targetStatus})` }],
|
|
181
|
+
details: result,
|
|
182
|
+
};
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
pi.registerTool({
|
|
187
|
+
name: "session_delegate_status",
|
|
188
|
+
label: "Session Delegate Status",
|
|
189
|
+
description: "Check the status of a delegated task session.",
|
|
190
|
+
parameters: DelegateStatusParams,
|
|
191
|
+
async execute(toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
192
|
+
const task = store?.get(params.sessionId);
|
|
193
|
+
if (task) {
|
|
194
|
+
const status = task.status === "completed" ? "DONE" : task.status.toUpperCase();
|
|
195
|
+
return {
|
|
196
|
+
content: [{ type: "text" as const, text: `Task "${task.title}" (${params.sessionId}): ${status}` }],
|
|
197
|
+
details: { task },
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
const remote = await serverProxy.delegate_status(params.sessionId);
|
|
201
|
+
return {
|
|
202
|
+
content: [{ type: "text" as const, text: `Session ${params.sessionId} status: ${remote.status}` }],
|
|
203
|
+
details: { task: null },
|
|
204
|
+
};
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
pi.registerTool({
|
|
209
|
+
name: "session_delegate_stop",
|
|
210
|
+
label: "Session Delegate Stop",
|
|
211
|
+
description: "Stop a delegated task session.",
|
|
212
|
+
parameters: DelegateStopParams,
|
|
213
|
+
async execute(toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
214
|
+
const ok = await serverProxy.delegate_stop(params.sessionId);
|
|
215
|
+
if (ok && store) {
|
|
216
|
+
store.update(params.sessionId, { status: "stopped" });
|
|
217
|
+
}
|
|
218
|
+
return {
|
|
219
|
+
content: [{ type: "text" as const, text: ok ? `Session ${params.sessionId} stopped.` : `Session ${params.sessionId} not found or already stopped.` }],
|
|
220
|
+
details: { ok },
|
|
221
|
+
};
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
pi.registerTool({
|
|
226
|
+
name: "session_delegate_fork",
|
|
227
|
+
label: "Session Delegate Fork",
|
|
228
|
+
description: [
|
|
229
|
+
"Fork an existing session and delegate a new task to the forked session.",
|
|
230
|
+
"The forked session starts with a copy of the source session's conversation history.",
|
|
231
|
+
"The original session continues running unchanged.",
|
|
232
|
+
].join(" "),
|
|
233
|
+
parameters: DelegateForkParams,
|
|
234
|
+
async execute(toolCallId, params, _signal, _onUpdate, ctx) {
|
|
235
|
+
const sid = currentSessionId || ctx.sessionManager.getSessionId();
|
|
236
|
+
const result = await serverProxy.delegate_fork(params.sessionId, params.task, params.title);
|
|
237
|
+
if (store) {
|
|
238
|
+
store.add({
|
|
239
|
+
sessionId: result.sessionId,
|
|
240
|
+
title: params.title || params.task.slice(0, 60),
|
|
241
|
+
task: params.task,
|
|
242
|
+
projectPath: ctx.cwd,
|
|
243
|
+
dispatchedAt: Date.now(),
|
|
244
|
+
status: "idle",
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
content: [{ type: "text" as const, text: `Forked session ${params.sessionId} → ${result.sessionId} (status: ${result.status}). Task: ${params.task}` }],
|
|
249
|
+
details: { ...result, forkedFrom: params.sessionId, dispatchedBy: sid },
|
|
250
|
+
};
|
|
251
|
+
},
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
client.on("message_received", (data: unknown) => {
|
|
255
|
+
const d = data as { fromSessionId: string; message: string };
|
|
256
|
+
pi.sendUserMessage(
|
|
257
|
+
`[Coordinator] Message from session ${d.fromSessionId}:\n${d.message}`,
|
|
258
|
+
{ deliverAs: "followUp" },
|
|
259
|
+
);
|
|
260
|
+
});
|
|
261
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { ChannelContract } from "@dyyz1993/pi-coding-agent";
|
|
2
|
+
export declare const COORDINATOR_CHANNEL_NAME = "coordinator";
|
|
3
|
+
export type SessionStatus = "idle" | "streaming" | "stopped" | "completed";
|
|
4
|
+
export interface DelegatedTask {
|
|
5
|
+
sessionId: string;
|
|
6
|
+
title: string;
|
|
7
|
+
task: string;
|
|
8
|
+
projectPath: string;
|
|
9
|
+
dispatchedAt: number;
|
|
10
|
+
status: SessionStatus;
|
|
11
|
+
completedAt?: number;
|
|
12
|
+
result?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface DelegateCreateResult {
|
|
15
|
+
sessionId: string;
|
|
16
|
+
status: "started" | "already_running";
|
|
17
|
+
}
|
|
18
|
+
export interface DelegateSendResult {
|
|
19
|
+
delivered: boolean;
|
|
20
|
+
targetStatus: "active" | "started" | "not_found";
|
|
21
|
+
}
|
|
22
|
+
export interface DelegateListResult {
|
|
23
|
+
tasks: DelegatedTask[];
|
|
24
|
+
}
|
|
25
|
+
export interface DelegateStatusExt {
|
|
26
|
+
task: DelegatedTask | null;
|
|
27
|
+
isCompacting?: boolean;
|
|
28
|
+
contextUsage?: {
|
|
29
|
+
tokens: number | null;
|
|
30
|
+
contextWindow: number;
|
|
31
|
+
percent: number | null;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export interface CoordinatorChannelContract extends ChannelContract {
|
|
35
|
+
methods: {
|
|
36
|
+
session_delegate: {
|
|
37
|
+
params: {
|
|
38
|
+
task: string;
|
|
39
|
+
title?: string;
|
|
40
|
+
};
|
|
41
|
+
return: DelegateCreateResult;
|
|
42
|
+
};
|
|
43
|
+
session_delegate_send: {
|
|
44
|
+
params: {
|
|
45
|
+
targetSessionId: string;
|
|
46
|
+
message: string;
|
|
47
|
+
};
|
|
48
|
+
return: DelegateSendResult;
|
|
49
|
+
};
|
|
50
|
+
session_delegate_status: {
|
|
51
|
+
params: {
|
|
52
|
+
sessionId: string;
|
|
53
|
+
};
|
|
54
|
+
return: DelegateStatusExt;
|
|
55
|
+
};
|
|
56
|
+
session_delegate_list: {
|
|
57
|
+
params: Record<string, never>;
|
|
58
|
+
return: DelegateListResult;
|
|
59
|
+
};
|
|
60
|
+
session_delegate_stop: {
|
|
61
|
+
params: {
|
|
62
|
+
sessionId: string;
|
|
63
|
+
};
|
|
64
|
+
return: {
|
|
65
|
+
ok: boolean;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
session_delegate_fork: {
|
|
69
|
+
params: {
|
|
70
|
+
sessionId: string;
|
|
71
|
+
task: string;
|
|
72
|
+
title?: string;
|
|
73
|
+
};
|
|
74
|
+
return: DelegateCreateResult;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
events: {
|
|
78
|
+
message_received: {
|
|
79
|
+
fromSessionId: string;
|
|
80
|
+
message: string;
|
|
81
|
+
};
|
|
82
|
+
task_started: {
|
|
83
|
+
sessionId: string;
|
|
84
|
+
title: string;
|
|
85
|
+
task: string;
|
|
86
|
+
};
|
|
87
|
+
task_stopped: {
|
|
88
|
+
sessionId: string;
|
|
89
|
+
};
|
|
90
|
+
task_completed: {
|
|
91
|
+
sessionId: string;
|
|
92
|
+
result?: string;
|
|
93
|
+
};
|
|
94
|
+
task_error: {
|
|
95
|
+
sessionId: string;
|
|
96
|
+
error: string;
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ChannelContract } from \"@dyyz1993/pi-coding-agent\";\n\nexport const COORDINATOR_CHANNEL_NAME = \"coordinator\";\n\nexport type SessionStatus = \"idle\" | \"streaming\" | \"stopped\" | \"completed\";\n\nexport interface DelegatedTask {\n\tsessionId: string;\n\ttitle: string;\n\ttask: string;\n\tprojectPath: string;\n\tdispatchedAt: number;\n\tstatus: SessionStatus;\n\tcompletedAt?: number;\n\tresult?: string;\n}\n\nexport interface DelegateCreateResult {\n\tsessionId: string;\n\tstatus: \"started\" | \"already_running\";\n}\n\nexport interface DelegateSendResult {\n\tdelivered: boolean;\n\ttargetStatus: \"active\" | \"started\" | \"not_found\";\n}\n\nexport interface DelegateListResult {\n\ttasks: DelegatedTask[];\n}\n\nexport interface DelegateStatusExt {\n\ttask: DelegatedTask | null;\n\tisCompacting?: boolean;\n\tcontextUsage?: { tokens: number | null; contextWindow: number; percent: number | null };\n}\n\nexport interface CoordinatorChannelContract extends ChannelContract {\n\tmethods: {\n\t\tsession_delegate: {\n\t\t\tparams: { task: string; title?: string };\n\t\t\treturn: DelegateCreateResult;\n\t\t};\n\t\tsession_delegate_send: {\n\t\t\tparams: { targetSessionId: string; message: string };\n\t\t\treturn: DelegateSendResult;\n\t\t};\n\t\tsession_delegate_status: {\n\t\t\tparams: { sessionId: string };\n\t\t\treturn: DelegateStatusExt;\n\t\t};\n\t\tsession_delegate_list: {\n\t\t\tparams: Record<string, never>;\n\t\t\treturn: DelegateListResult;\n\t\t};\n\t\tsession_delegate_stop: {\n\t\t\tparams: { sessionId: string };\n\t\t\treturn: { ok: boolean };\n\t\t};\n\t\tsession_delegate_fork: {\n\t\t\tparams: { sessionId: string; task: string; title?: string };\n\t\t\treturn: DelegateCreateResult;\n\t\t};\n\t};\n\tevents: {\n\t\tmessage_received: { fromSessionId: string; message: string };\n\t\ttask_started: { sessionId: string; title: string; task: string };\n\t\ttask_stopped: { sessionId: string };\n\t\ttask_completed: { sessionId: string; result?: string };\n\t\ttask_error: { sessionId: string; error: string };\n\t};\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,wBAAwB,GAAG,aAAa,CAAC","sourcesContent":["import type { ChannelContract } from \"@dyyz1993/pi-coding-agent\";\n\nexport const COORDINATOR_CHANNEL_NAME = \"coordinator\";\n\nexport type SessionStatus = \"idle\" | \"streaming\" | \"stopped\" | \"completed\";\n\nexport interface DelegatedTask {\n\tsessionId: string;\n\ttitle: string;\n\ttask: string;\n\tprojectPath: string;\n\tdispatchedAt: number;\n\tstatus: SessionStatus;\n\tcompletedAt?: number;\n\tresult?: string;\n}\n\nexport interface DelegateCreateResult {\n\tsessionId: string;\n\tstatus: \"started\" | \"already_running\";\n}\n\nexport interface DelegateSendResult {\n\tdelivered: boolean;\n\ttargetStatus: \"active\" | \"started\" | \"not_found\";\n}\n\nexport interface DelegateListResult {\n\ttasks: DelegatedTask[];\n}\n\nexport interface DelegateStatusExt {\n\ttask: DelegatedTask | null;\n\tisCompacting?: boolean;\n\tcontextUsage?: { tokens: number | null; contextWindow: number; percent: number | null };\n}\n\nexport interface CoordinatorChannelContract extends ChannelContract {\n\tmethods: {\n\t\tsession_delegate: {\n\t\t\tparams: { task: string; title?: string };\n\t\t\treturn: DelegateCreateResult;\n\t\t};\n\t\tsession_delegate_send: {\n\t\t\tparams: { targetSessionId: string; message: string };\n\t\t\treturn: DelegateSendResult;\n\t\t};\n\t\tsession_delegate_status: {\n\t\t\tparams: { sessionId: string };\n\t\t\treturn: DelegateStatusExt;\n\t\t};\n\t\tsession_delegate_list: {\n\t\t\tparams: Record<string, never>;\n\t\t\treturn: DelegateListResult;\n\t\t};\n\t\tsession_delegate_stop: {\n\t\t\tparams: { sessionId: string };\n\t\t\treturn: { ok: boolean };\n\t\t};\n\t\tsession_delegate_fork: {\n\t\t\tparams: { sessionId: string; task: string; title?: string };\n\t\t\treturn: DelegateCreateResult;\n\t\t};\n\t};\n\tevents: {\n\t\tmessage_received: { fromSessionId: string; message: string };\n\t\ttask_started: { sessionId: string; title: string; task: string };\n\t\ttask_stopped: { sessionId: string };\n\t\ttask_completed: { sessionId: string; result?: string };\n\t\ttask_error: { sessionId: string; error: string };\n\t};\n}\n"]}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { ChannelContract } from "@dyyz1993/pi-coding-agent";
|
|
2
|
+
|
|
3
|
+
export const COORDINATOR_CHANNEL_NAME = "coordinator";
|
|
4
|
+
|
|
5
|
+
export type SessionStatus = "idle" | "streaming" | "stopped" | "completed";
|
|
6
|
+
|
|
7
|
+
export interface DelegatedTask {
|
|
8
|
+
sessionId: string;
|
|
9
|
+
title: string;
|
|
10
|
+
task: string;
|
|
11
|
+
projectPath: string;
|
|
12
|
+
dispatchedAt: number;
|
|
13
|
+
status: SessionStatus;
|
|
14
|
+
completedAt?: number;
|
|
15
|
+
result?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface DelegateCreateResult {
|
|
19
|
+
sessionId: string;
|
|
20
|
+
status: "started" | "already_running";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface DelegateSendResult {
|
|
24
|
+
delivered: boolean;
|
|
25
|
+
targetStatus: "active" | "started" | "not_found";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface DelegateListResult {
|
|
29
|
+
tasks: DelegatedTask[];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface DelegateStatusExt {
|
|
33
|
+
task: DelegatedTask | null;
|
|
34
|
+
isCompacting?: boolean;
|
|
35
|
+
contextUsage?: { tokens: number | null; contextWindow: number; percent: number | null };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface CoordinatorChannelContract extends ChannelContract {
|
|
39
|
+
methods: {
|
|
40
|
+
session_delegate: {
|
|
41
|
+
params: { task: string; title?: string };
|
|
42
|
+
return: DelegateCreateResult;
|
|
43
|
+
};
|
|
44
|
+
session_delegate_send: {
|
|
45
|
+
params: { targetSessionId: string; message: string };
|
|
46
|
+
return: DelegateSendResult;
|
|
47
|
+
};
|
|
48
|
+
session_delegate_status: {
|
|
49
|
+
params: { sessionId: string };
|
|
50
|
+
return: DelegateStatusExt;
|
|
51
|
+
};
|
|
52
|
+
session_delegate_list: {
|
|
53
|
+
params: Record<string, never>;
|
|
54
|
+
return: DelegateListResult;
|
|
55
|
+
};
|
|
56
|
+
session_delegate_stop: {
|
|
57
|
+
params: { sessionId: string };
|
|
58
|
+
return: { ok: boolean };
|
|
59
|
+
};
|
|
60
|
+
session_delegate_fork: {
|
|
61
|
+
params: { sessionId: string; task: string; title?: string };
|
|
62
|
+
return: DelegateCreateResult;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
events: {
|
|
66
|
+
message_received: { fromSessionId: string; message: string };
|
|
67
|
+
task_started: { sessionId: string; title: string; task: string };
|
|
68
|
+
task_stopped: { sessionId: string };
|
|
69
|
+
task_completed: { sessionId: string; result?: string };
|
|
70
|
+
task_error: { sessionId: string; error: string };
|
|
71
|
+
};
|
|
72
|
+
}
|