paseo-plugin-zcode-provider 0.0.0-stage → 0.2.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/NOTICE.md +29 -0
- package/README.md +112 -2
- package/client/account.tsx +827 -0
- package/client/diagnostics.tsx +379 -0
- package/client/runtime.tsx +296 -0
- package/client/settings.tsx +84 -0
- package/client/value.tsx +20 -0
- package/icon.svg +1 -0
- package/index.client.tsx +22 -0
- package/index.server.ts +39 -0
- package/package.json +77 -4
- package/paseo-plugin.json +6 -0
- package/server/account.ts +781 -0
- package/server/attachments.ts +150 -0
- package/server/build-info.ts +2 -0
- package/server/conversation.ts +319 -0
- package/server/diagnostics.ts +252 -0
- package/server/discovery/discover.ts +225 -0
- package/server/discovery/manifest.ts +36 -0
- package/server/discovery/types.ts +30 -0
- package/server/errors.ts +36 -0
- package/server/host/bridge.ts +490 -0
- package/server/host/schemas.ts +119 -0
- package/server/logger.ts +19 -0
- package/server/mapping.ts +270 -0
- package/server/models.ts +68 -0
- package/server/persistence.ts +146 -0
- package/server/presentation.ts +470 -0
- package/server/provider-status.ts +81 -0
- package/server/provider.ts +838 -0
- package/server/runtime/managed.ts +501 -0
- package/server/runtime/pins.ts +72 -0
- package/server/runtime-setup.ts +77 -0
- package/server/session-types.ts +49 -0
- package/server/session.ts +866 -0
- package/server/status.ts +89 -0
- package/server/timeline.ts +18 -0
- package/server/usage.ts +362 -0
- package/server/vendor/zcode/LICENSE +202 -0
- package/server/vendor/zcode/NOTICE.md +70 -0
- package/server/vendor/zcode/THIRD-PARTY-NOTICES.md +37 -0
- package/server/vendor/zcode/packages/model-option-map/src/compiler.ts +92 -0
- package/server/vendor/zcode/packages/model-option-map/src/evaluator.ts +214 -0
- package/server/vendor/zcode/packages/model-option-map/src/index.ts +5 -0
- package/server/vendor/zcode/packages/model-option-map/src/merge-patch.ts +97 -0
- package/server/vendor/zcode/packages/model-option-map/src/option-maps.ts +42 -0
- package/server/vendor/zcode/packages/model-option-map/src/parser.ts +240 -0
- package/server/vendor/zcode/packages/model-option-map/src/tokenizer.ts +141 -0
- package/server/vendor/zcode/packages/model-option-map/src/types.ts +36 -0
- package/server/vendor/zcode/packages/rpc/src/buffer.ts +88 -0
- package/server/vendor/zcode/packages/rpc/src/channelClient.ts +275 -0
- package/server/vendor/zcode/packages/rpc/src/channelServer.ts +283 -0
- package/server/vendor/zcode/packages/rpc/src/channels.shared.ts +66 -0
- package/server/vendor/zcode/packages/rpc/src/channels.ts +4 -0
- package/server/vendor/zcode/packages/rpc/src/delayedChannel.ts +17 -0
- package/server/vendor/zcode/packages/rpc/src/foundation.ts +260 -0
- package/server/vendor/zcode/packages/rpc/src/protocol.ts +397 -0
- package/server/vendor/zcode/packages/rpc/src/proxy-channel.ts +213 -0
- package/server/vendor/zcode/packages/rpc/src/serialization.ts +291 -0
- package/server/vendor/zcode/packages/shared/src/account-provider-state.ts +13 -0
- package/server/vendor/zcode/packages/shared/src/background-bash-output.ts +24 -0
- package/server/vendor/zcode/packages/shared/src/background-task-controls.ts +404 -0
- package/server/vendor/zcode/packages/shared/src/bash-output-display.ts +11 -0
- package/server/vendor/zcode/packages/shared/src/bots.ts +558 -0
- package/server/vendor/zcode/packages/shared/src/browser-use/backend.ts +80 -0
- package/server/vendor/zcode/packages/shared/src/browser-use/command-metadata.ts +170 -0
- package/server/vendor/zcode/packages/shared/src/browser-use/commands.ts +588 -0
- package/server/vendor/zcode/packages/shared/src/browser-use/result.ts +130 -0
- package/server/vendor/zcode/packages/shared/src/browser-use/snapshot.ts +77 -0
- package/server/vendor/zcode/packages/shared/src/command-types.ts +96 -0
- package/server/vendor/zcode/packages/shared/src/config-schema.ts +8 -0
- package/server/vendor/zcode/packages/shared/src/cuaAccessibilitySettings.ts +41 -0
- package/server/vendor/zcode/packages/shared/src/database-startup.ts +178 -0
- package/server/vendor/zcode/packages/shared/src/env.ts +63 -0
- package/server/vendor/zcode/packages/shared/src/execution-output-preview.ts +14 -0
- package/server/vendor/zcode/packages/shared/src/localTtft.ts +192 -0
- package/server/vendor/zcode/packages/shared/src/model-config.ts +123 -0
- package/server/vendor/zcode/packages/shared/src/model-execution.ts +23 -0
- package/server/vendor/zcode/packages/shared/src/model-provider-family.ts +171 -0
- package/server/vendor/zcode/packages/shared/src/model-provider-types.ts +81 -0
- package/server/vendor/zcode/packages/shared/src/model-selection.ts +60 -0
- package/server/vendor/zcode/packages/shared/src/oauth.ts +203 -0
- package/server/vendor/zcode/packages/shared/src/official-mcp-auth.ts +272 -0
- package/server/vendor/zcode/packages/shared/src/official-mcp-tool-error.ts +68 -0
- package/server/vendor/zcode/packages/shared/src/process-diagnostic.ts +42 -0
- package/server/vendor/zcode/packages/shared/src/protocol.ts +369 -0
- package/server/vendor/zcode/packages/shared/src/provider-family-connection-selection.ts +32 -0
- package/server/vendor/zcode/packages/shared/src/remoteAssetInstallMode.ts +11 -0
- package/server/vendor/zcode/packages/shared/src/remoteResourcePackages.ts +91 -0
- package/server/vendor/zcode/packages/shared/src/runtimeEnv.ts +315 -0
- package/server/vendor/zcode/packages/shared/src/settings-source.ts +10 -0
- package/server/vendor/zcode/packages/shared/src/usage-quota.ts +74 -0
- package/server/vendor/zcode/packages/shared/src/usage-stats.ts +462 -0
- package/server/vendor/zcode/packages/shared/src/validationAppSettings.ts +562 -0
- package/server/vendor/zcode/packages/shared/src/workspacePurpose.ts +2 -0
- package/server/vendor/zcode/packages/shared/src/wslUserValidation.ts +33 -0
- package/server/vendor/zcode/packages/shared/src/zcode-agent-policy.ts +25 -0
- package/server/vendor/zcode/packages/shared/src/zcode-media-policy.ts +10 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol/index.ts +3720 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-legacy-types.ts +529 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/apply.ts +218 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/attachment-ref.ts +14 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/command.ts +482 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/core.ts +100 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/create-workflow-display.ts +156 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/cuaPermission.ts +41 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/delta.ts +147 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/input-intent.ts +69 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/rows.ts +432 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/session-config.ts +43 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/sessions-index-workflow-activity.ts +195 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/sessions-index.ts +85 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/shared-context-import.ts +38 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/shared-context-ref.ts +10 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/snapshot.ts +509 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/submission.ts +5 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/toolDisplay.ts +264 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/transport.ts +1152 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-assembler.ts +574 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-binary.ts +65 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-codec.ts +240 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-fault.ts +39 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire.ts +159 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-artifacts.ts +291 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-observation-display.ts +281 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-row-meta.ts +163 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-run-settings-command.ts +62 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-runs-delta.ts +517 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-runs.ts +512 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workspace-config.ts +81 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workspace-hook-review.ts +210 -0
- package/server/vendor/zcode/packages/shared/src/zcode-task-mode-schema.ts +6 -0
- package/server/vendor/zcode/packages/shared/src/zcode-task-types-core.ts +1187 -0
- package/server/vendor/zcode/packages/shared/src/zcodeEndpoint.ts +296 -0
- package/server/vendor/zcode/provenance.json +405 -0
- package/shared/account.ts +201 -0
- package/shared/diagnostics.ts +52 -0
- package/shared/runtime-setup.ts +73 -0
- package/vendor/acp-registry/LICENSE +176 -0
- package/vendor/paseo/LICENSE +211 -0
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ProviderPermissionAction,
|
|
3
|
+
ProviderPermissionRequest,
|
|
4
|
+
ProviderPermissionResponse,
|
|
5
|
+
ProviderTimelineItem,
|
|
6
|
+
ProviderToolCallDetail,
|
|
7
|
+
ProviderUsage,
|
|
8
|
+
} from "@getpaseo/plugin/server/provider";
|
|
9
|
+
import type {
|
|
10
|
+
ConversationRow,
|
|
11
|
+
HookInvocationRow,
|
|
12
|
+
TimelineMarkerPayload,
|
|
13
|
+
} from "./vendor/zcode/packages/shared/src/zcode-protocol-v4/rows.js";
|
|
14
|
+
import type {
|
|
15
|
+
ConversationSnapshot,
|
|
16
|
+
PendingInteraction,
|
|
17
|
+
} from "./vendor/zcode/packages/shared/src/zcode-protocol-v4/snapshot.js";
|
|
18
|
+
import { AdapterError } from "./errors.js";
|
|
19
|
+
import { jsonValue, record, planMarkdown } from "./mapping.js";
|
|
20
|
+
|
|
21
|
+
export function rowTimeline(
|
|
22
|
+
row: ConversationRow,
|
|
23
|
+
clientMessageId?: string,
|
|
24
|
+
): ProviderTimelineItem | undefined {
|
|
25
|
+
const id = `zcode:row:${row.rowId}`;
|
|
26
|
+
switch (row.kind) {
|
|
27
|
+
case "turnHeader":
|
|
28
|
+
return;
|
|
29
|
+
case "userInput":
|
|
30
|
+
return row.origin === "realUser"
|
|
31
|
+
? {
|
|
32
|
+
id,
|
|
33
|
+
type: "user_message",
|
|
34
|
+
text: [
|
|
35
|
+
row.text,
|
|
36
|
+
...(row.attachments ?? []).map(
|
|
37
|
+
(a) =>
|
|
38
|
+
`[Attachment: ${a.fileName} (${a.mime}, ${a.bytes} bytes)]`,
|
|
39
|
+
),
|
|
40
|
+
]
|
|
41
|
+
.filter(Boolean)
|
|
42
|
+
.join("\n\n"),
|
|
43
|
+
messageId: row.sourceCommandId ?? row.entityId,
|
|
44
|
+
...(clientMessageId ? { clientMessageId } : {}),
|
|
45
|
+
}
|
|
46
|
+
: { id, type: "notification", level: "info", message: row.text };
|
|
47
|
+
case "assistantText":
|
|
48
|
+
return {
|
|
49
|
+
id,
|
|
50
|
+
type: "assistant_message",
|
|
51
|
+
text: row.text,
|
|
52
|
+
messageId: row.assistantResponseId ?? row.entityId,
|
|
53
|
+
};
|
|
54
|
+
case "reasoning":
|
|
55
|
+
return { id, type: "reasoning", text: row.text };
|
|
56
|
+
case "toolCall": {
|
|
57
|
+
const input = record(row.input);
|
|
58
|
+
const truncated =
|
|
59
|
+
!!row.output?.truncated ||
|
|
60
|
+
(row.output?.display?.kind === "bash_output" &&
|
|
61
|
+
row.output.display.truncated);
|
|
62
|
+
const text =
|
|
63
|
+
(row.output?.text ?? row.error?.message ?? "") +
|
|
64
|
+
(truncated
|
|
65
|
+
? "\n[ZCode truncated this output; the full result has not been loaded.]"
|
|
66
|
+
: "");
|
|
67
|
+
let detail: ProviderToolCallDetail;
|
|
68
|
+
if (row.toolName === "Bash" && typeof input.command === "string")
|
|
69
|
+
detail = { type: "shell", command: input.command, output: text };
|
|
70
|
+
else if (row.toolName === "Read" && typeof input.file_path === "string")
|
|
71
|
+
detail = { type: "read", filePath: input.file_path, content: text };
|
|
72
|
+
else if (row.toolName === "Write" && typeof input.file_path === "string")
|
|
73
|
+
detail = {
|
|
74
|
+
type: "write",
|
|
75
|
+
filePath: input.file_path,
|
|
76
|
+
...(typeof input.content === "string"
|
|
77
|
+
? { content: input.content }
|
|
78
|
+
: {}),
|
|
79
|
+
};
|
|
80
|
+
else if (row.toolName === "Edit" && typeof input.file_path === "string")
|
|
81
|
+
detail = {
|
|
82
|
+
type: "edit",
|
|
83
|
+
filePath: input.file_path,
|
|
84
|
+
...(typeof input.old_string === "string"
|
|
85
|
+
? { oldString: input.old_string }
|
|
86
|
+
: {}),
|
|
87
|
+
...(typeof input.new_string === "string"
|
|
88
|
+
? { newString: input.new_string }
|
|
89
|
+
: {}),
|
|
90
|
+
};
|
|
91
|
+
else
|
|
92
|
+
detail = {
|
|
93
|
+
type: "unknown",
|
|
94
|
+
input: jsonValue(row.input ?? row.inputText),
|
|
95
|
+
output: jsonValue({
|
|
96
|
+
text,
|
|
97
|
+
...(row.output?.display ? { display: row.output.display } : {}),
|
|
98
|
+
truncated,
|
|
99
|
+
}),
|
|
100
|
+
};
|
|
101
|
+
const base = {
|
|
102
|
+
id,
|
|
103
|
+
type: "tool_call" as const,
|
|
104
|
+
callId: row.toolCallId,
|
|
105
|
+
name: row.toolName,
|
|
106
|
+
detail,
|
|
107
|
+
metadata: {
|
|
108
|
+
truncated,
|
|
109
|
+
...(row.backgrounded ? { backgrounded: true } : {}),
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
return row.status === "error"
|
|
113
|
+
? { ...base, status: "failed", error: jsonValue(row.error ?? text) }
|
|
114
|
+
: {
|
|
115
|
+
...base,
|
|
116
|
+
status:
|
|
117
|
+
row.status === "success"
|
|
118
|
+
? "completed"
|
|
119
|
+
: row.status === "cancelled"
|
|
120
|
+
? "canceled"
|
|
121
|
+
: "running",
|
|
122
|
+
error: null,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
case "subagent": {
|
|
126
|
+
const base = {
|
|
127
|
+
id,
|
|
128
|
+
type: "tool_call" as const,
|
|
129
|
+
callId: row.entityId ?? `subagent:${row.rowId}`,
|
|
130
|
+
name: row.subagentType,
|
|
131
|
+
detail: {
|
|
132
|
+
type: "sub_agent" as const,
|
|
133
|
+
subAgentType: row.subagentType,
|
|
134
|
+
log: row.summaryText,
|
|
135
|
+
},
|
|
136
|
+
metadata: {
|
|
137
|
+
backgrounded: row.backgrounded === true,
|
|
138
|
+
...(row.childSessionId
|
|
139
|
+
? { zcodeChildSessionId: row.childSessionId }
|
|
140
|
+
: {}),
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
return row.status === "failed"
|
|
144
|
+
? { ...base, status: "failed", error: row.summaryText }
|
|
145
|
+
: {
|
|
146
|
+
...base,
|
|
147
|
+
status:
|
|
148
|
+
row.status === "success"
|
|
149
|
+
? "completed"
|
|
150
|
+
: row.status === "cancelled"
|
|
151
|
+
? "canceled"
|
|
152
|
+
: "running",
|
|
153
|
+
error: null,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
case "artifact":
|
|
157
|
+
return {
|
|
158
|
+
id,
|
|
159
|
+
type: "notification",
|
|
160
|
+
level: "info",
|
|
161
|
+
message: `${row.displayName} (${row.artifactType}, ${row.sizeBytes} bytes)`,
|
|
162
|
+
};
|
|
163
|
+
case "hookInvocation":
|
|
164
|
+
return hookTimeline(id, row);
|
|
165
|
+
case "timelineMarker":
|
|
166
|
+
// Paseo appends every notification it receives, so a changing row is
|
|
167
|
+
// reported once, in its final state.
|
|
168
|
+
if (row.marker.type === "compact" && row.marker.status === "running")
|
|
169
|
+
return;
|
|
170
|
+
return {
|
|
171
|
+
id,
|
|
172
|
+
type: "notification",
|
|
173
|
+
level: "info",
|
|
174
|
+
message: markerText(row.marker),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Like ZCode Desktop, which keeps hooks out of the conversation and lists
|
|
179
|
+
// them on request, successful hooks are not shown. Paseo appends every
|
|
180
|
+
// notification it receives, so an invocation is reported once, after it ends,
|
|
181
|
+
// and only when a hook that ran did not succeed.
|
|
182
|
+
function hookTimeline(
|
|
183
|
+
id: string,
|
|
184
|
+
row: HookInvocationRow,
|
|
185
|
+
): ProviderTimelineItem | undefined {
|
|
186
|
+
if (
|
|
187
|
+
row.state === "running" ||
|
|
188
|
+
row.executions.some((h) => h.state === "running")
|
|
189
|
+
)
|
|
190
|
+
return;
|
|
191
|
+
const problems = row.executions.flatMap((hook) => {
|
|
192
|
+
if (!hook.didExecute) return [];
|
|
193
|
+
const outcome =
|
|
194
|
+
hook.outcome && hook.outcome !== "success"
|
|
195
|
+
? hook.outcome
|
|
196
|
+
: hook.state === "failed"
|
|
197
|
+
? "failed"
|
|
198
|
+
: undefined;
|
|
199
|
+
return outcome ? [{ hook, outcome }] : [];
|
|
200
|
+
});
|
|
201
|
+
if (problems.length === 0) return;
|
|
202
|
+
const outcomes = new Set(problems.map((p) => p.outcome));
|
|
203
|
+
return {
|
|
204
|
+
id,
|
|
205
|
+
type: "notification",
|
|
206
|
+
level: outcomes.has("failed")
|
|
207
|
+
? "error"
|
|
208
|
+
: outcomes.has("blocked") || outcomes.has("timed_out")
|
|
209
|
+
? "warning"
|
|
210
|
+
: "info",
|
|
211
|
+
message: `${row.hookEventName} hook ${problems
|
|
212
|
+
.map(
|
|
213
|
+
({ hook, outcome }) =>
|
|
214
|
+
`${outcome.replace("_", " ")}: ${hook.displayName}${hook.blockReason ? ` (${hook.blockReason})` : ""}`,
|
|
215
|
+
)
|
|
216
|
+
.join("; ")}`,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export function usage(state: ConversationSnapshot): ProviderUsage {
|
|
221
|
+
return {
|
|
222
|
+
inputTokens: state.usage.cumulative.inputTokens,
|
|
223
|
+
cachedInputTokens: state.usage.cumulative.cacheReadTokens,
|
|
224
|
+
outputTokens: state.usage.cumulative.outputTokens,
|
|
225
|
+
...(state.usage.contextWindow
|
|
226
|
+
? {
|
|
227
|
+
contextWindowUsedTokens: state.usage.contextWindow.usedTokens,
|
|
228
|
+
contextWindowMaxTokens: state.usage.contextWindow.maxTokens,
|
|
229
|
+
}
|
|
230
|
+
: {}),
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
export interface PresentedInteraction {
|
|
234
|
+
request: ProviderPermissionRequest;
|
|
235
|
+
answer(response: ProviderPermissionResponse): Record<string, unknown>;
|
|
236
|
+
}
|
|
237
|
+
export function presentInteraction(
|
|
238
|
+
interaction: PendingInteraction,
|
|
239
|
+
): PresentedInteraction | undefined {
|
|
240
|
+
const p = interaction.payload,
|
|
241
|
+
id = interaction.interactionId;
|
|
242
|
+
if (p.kind === "workspaceHookReview") return;
|
|
243
|
+
if (p.kind === "permission") {
|
|
244
|
+
const options = p.options.filter((o) => o.optionId !== "fullAccess");
|
|
245
|
+
const actions: ProviderPermissionAction[] = options.map((o) => {
|
|
246
|
+
const behavior =
|
|
247
|
+
o.response?.decision ??
|
|
248
|
+
(o.kind === "deny"
|
|
249
|
+
? "deny"
|
|
250
|
+
: o.kind === "allowOnce" || o.kind === "allowAlways"
|
|
251
|
+
? "allow"
|
|
252
|
+
: undefined);
|
|
253
|
+
if (behavior !== "allow" && behavior !== "deny")
|
|
254
|
+
throw new AdapterError(
|
|
255
|
+
"INTERACTION_UNSUPPORTED",
|
|
256
|
+
"ZCode permission option cannot be represented",
|
|
257
|
+
);
|
|
258
|
+
return {
|
|
259
|
+
id: o.optionId,
|
|
260
|
+
label: o.label,
|
|
261
|
+
behavior,
|
|
262
|
+
variant: behavior === "allow" ? "primary" : "danger",
|
|
263
|
+
};
|
|
264
|
+
});
|
|
265
|
+
if (!actions.some((a) => a.behavior === "deny"))
|
|
266
|
+
throw new AdapterError(
|
|
267
|
+
"NATIVE_PROTOCOL_ERROR",
|
|
268
|
+
"ZCode permission has no deny option",
|
|
269
|
+
);
|
|
270
|
+
const plan = p.toolName === "ExitPlanMode";
|
|
271
|
+
const markdown = plan ? planMarkdown(p.detail) : undefined;
|
|
272
|
+
return {
|
|
273
|
+
request: {
|
|
274
|
+
id,
|
|
275
|
+
name: plan ? "ZCodePlanApproval" : p.toolName,
|
|
276
|
+
kind: plan ? "plan" : "tool",
|
|
277
|
+
title: plan ? "Plan" : p.toolName,
|
|
278
|
+
description: p.summary,
|
|
279
|
+
actions,
|
|
280
|
+
...(markdown
|
|
281
|
+
? {
|
|
282
|
+
input: { plan: markdown },
|
|
283
|
+
metadata: { planText: markdown, source: "zcode_plan_approval" },
|
|
284
|
+
}
|
|
285
|
+
: {
|
|
286
|
+
detail: {
|
|
287
|
+
type: "unknown",
|
|
288
|
+
input: jsonValue(p.detail ?? null),
|
|
289
|
+
output: null,
|
|
290
|
+
},
|
|
291
|
+
}),
|
|
292
|
+
},
|
|
293
|
+
answer(response) {
|
|
294
|
+
const action = actions.find((a) => a.id === response.selectedActionId);
|
|
295
|
+
if (!action || action.behavior !== response.behavior)
|
|
296
|
+
throw new AdapterError(
|
|
297
|
+
"INVALID_CONFIGURATION",
|
|
298
|
+
"Permission response does not match an offered action",
|
|
299
|
+
);
|
|
300
|
+
return { optionId: action.id };
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
if (p.sensitive)
|
|
305
|
+
throw new AdapterError(
|
|
306
|
+
"INTERACTION_UNSUPPORTED",
|
|
307
|
+
"Sensitive ZCode input must be completed in the official CLI",
|
|
308
|
+
);
|
|
309
|
+
const questions = p.questions;
|
|
310
|
+
if (!questions?.length)
|
|
311
|
+
throw new AdapterError(
|
|
312
|
+
"INTERACTION_UNSUPPORTED",
|
|
313
|
+
"ZCode question has no representable fields",
|
|
314
|
+
);
|
|
315
|
+
const headers = new Set<string>();
|
|
316
|
+
const prompts = new Set<string>();
|
|
317
|
+
for (const q of questions) {
|
|
318
|
+
if (
|
|
319
|
+
headers.has(q.header) ||
|
|
320
|
+
prompts.has(q.question) ||
|
|
321
|
+
new Set(q.options.map((o) => o.label)).size !== q.options.length ||
|
|
322
|
+
new Set(q.options.map((o) => o.value)).size !== q.options.length ||
|
|
323
|
+
q.options.some((o) => q.multiSelect && o.label.includes(", "))
|
|
324
|
+
)
|
|
325
|
+
throw new AdapterError(
|
|
326
|
+
"INTERACTION_UNSUPPORTED",
|
|
327
|
+
"ZCode question has ambiguous labels",
|
|
328
|
+
);
|
|
329
|
+
headers.add(q.header);
|
|
330
|
+
prompts.add(q.question);
|
|
331
|
+
}
|
|
332
|
+
const plan = record(p.schema).interaction === "plan_approval";
|
|
333
|
+
const answerContent = (answers: Record<string, unknown>) => {
|
|
334
|
+
const content: Record<string, unknown> = {},
|
|
335
|
+
nativeAnswers: Record<string, string[]> = {};
|
|
336
|
+
questions.forEach((q, i) => {
|
|
337
|
+
const value = answers[q.header];
|
|
338
|
+
if (typeof value !== "string")
|
|
339
|
+
throw new AdapterError(
|
|
340
|
+
"INVALID_CONFIGURATION",
|
|
341
|
+
"A ZCode question answer is missing",
|
|
342
|
+
);
|
|
343
|
+
const labels =
|
|
344
|
+
value === "" ? [] : q.multiSelect ? value.split(", ") : [value];
|
|
345
|
+
if (new Set(labels).size !== labels.length)
|
|
346
|
+
throw new AdapterError(
|
|
347
|
+
"INVALID_CONFIGURATION",
|
|
348
|
+
"Duplicate question answer",
|
|
349
|
+
);
|
|
350
|
+
const values = labels.map((label) => {
|
|
351
|
+
const option = q.options.find((o) => o.label === label);
|
|
352
|
+
if (option) return option.value;
|
|
353
|
+
if (p.freeText) return label;
|
|
354
|
+
throw new AdapterError(
|
|
355
|
+
"INVALID_CONFIGURATION",
|
|
356
|
+
"Unknown question option",
|
|
357
|
+
);
|
|
358
|
+
});
|
|
359
|
+
nativeAnswers[q.question] = values;
|
|
360
|
+
content[`answer_${i}`] = q.multiSelect ? values : (values[0] ?? "");
|
|
361
|
+
if (i === 0) content.answer = content[`answer_${i}`];
|
|
362
|
+
});
|
|
363
|
+
return { ...content, answers: nativeAnswers };
|
|
364
|
+
};
|
|
365
|
+
if (plan) {
|
|
366
|
+
if (questions.length !== 1 || questions[0]!.multiSelect)
|
|
367
|
+
throw new AdapterError(
|
|
368
|
+
"INTERACTION_UNSUPPORTED",
|
|
369
|
+
"Unsupported ZCode Plan approval fields",
|
|
370
|
+
);
|
|
371
|
+
const question = questions[0]!,
|
|
372
|
+
markdown = planMarkdown(p.input);
|
|
373
|
+
const actions: ProviderPermissionAction[] = [
|
|
374
|
+
...question.options.map((o) => ({
|
|
375
|
+
id: o.value,
|
|
376
|
+
label: o.label,
|
|
377
|
+
behavior: "allow" as const,
|
|
378
|
+
variant: "primary" as const,
|
|
379
|
+
intent: "implement" as const,
|
|
380
|
+
})),
|
|
381
|
+
{
|
|
382
|
+
id: `dismiss:${id}`,
|
|
383
|
+
label: "Dismiss",
|
|
384
|
+
behavior: "deny",
|
|
385
|
+
intent: "dismiss",
|
|
386
|
+
variant: "danger",
|
|
387
|
+
},
|
|
388
|
+
];
|
|
389
|
+
return {
|
|
390
|
+
request: {
|
|
391
|
+
id,
|
|
392
|
+
name: "ZCodePlanApproval",
|
|
393
|
+
kind: "plan",
|
|
394
|
+
title: "Plan",
|
|
395
|
+
description: p.prompt,
|
|
396
|
+
input: { plan: markdown },
|
|
397
|
+
metadata: { planText: markdown, source: "zcode_plan_approval" },
|
|
398
|
+
actions,
|
|
399
|
+
},
|
|
400
|
+
answer(response) {
|
|
401
|
+
const action = actions.find((a) => a.id === response.selectedActionId);
|
|
402
|
+
if (!action || action.behavior !== response.behavior)
|
|
403
|
+
throw new AdapterError(
|
|
404
|
+
"INVALID_CONFIGURATION",
|
|
405
|
+
"Plan response does not match an offered action",
|
|
406
|
+
);
|
|
407
|
+
if (action.behavior === "deny") return { action: "decline" };
|
|
408
|
+
return {
|
|
409
|
+
action: "accept",
|
|
410
|
+
content: {
|
|
411
|
+
answer_0: action.id,
|
|
412
|
+
answer: action.id,
|
|
413
|
+
answers: { [question.question]: [action.id] },
|
|
414
|
+
},
|
|
415
|
+
};
|
|
416
|
+
},
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
return {
|
|
420
|
+
request: {
|
|
421
|
+
id,
|
|
422
|
+
name: "ZCodeQuestion",
|
|
423
|
+
kind: "question",
|
|
424
|
+
title: p.prompt,
|
|
425
|
+
input: {
|
|
426
|
+
questions: questions.map((q) => ({
|
|
427
|
+
question: q.question,
|
|
428
|
+
header: q.header,
|
|
429
|
+
options: q.options.map((o) => ({
|
|
430
|
+
label: o.label,
|
|
431
|
+
...(o.description ? { description: o.description } : {}),
|
|
432
|
+
})),
|
|
433
|
+
multiSelect: q.multiSelect === true,
|
|
434
|
+
allowOther: p.freeText,
|
|
435
|
+
allowEmpty: true,
|
|
436
|
+
dismissLabel: "Dismiss",
|
|
437
|
+
})),
|
|
438
|
+
},
|
|
439
|
+
},
|
|
440
|
+
answer(response) {
|
|
441
|
+
return response.behavior === "deny"
|
|
442
|
+
? { action: response.interrupt ? "cancel" : "decline" }
|
|
443
|
+
: {
|
|
444
|
+
action: "accept",
|
|
445
|
+
content: answerContent(record(response.updatedInput?.answers)),
|
|
446
|
+
};
|
|
447
|
+
},
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
function markerText(marker: TimelineMarkerPayload): string {
|
|
452
|
+
switch (marker.type) {
|
|
453
|
+
case "compact":
|
|
454
|
+
return `Context compaction: ${marker.status}`;
|
|
455
|
+
case "modelChange":
|
|
456
|
+
return `Model: ${marker.toModel} (${marker.toThought})`;
|
|
457
|
+
case "forkNotice":
|
|
458
|
+
return "Conversation continued from a parent conversation.";
|
|
459
|
+
case "forkCreated":
|
|
460
|
+
return "ZCode created a child conversation.";
|
|
461
|
+
case "goalSet":
|
|
462
|
+
return `Goal: ${marker.objective}`;
|
|
463
|
+
case "goalVerify":
|
|
464
|
+
return `Goal verification: ${marker.outcome}${marker.detail ? ` — ${marker.detail}` : ""}`;
|
|
465
|
+
case "retryNotice":
|
|
466
|
+
return `ZCode is retrying the model request (attempt ${marker.attempt}).`;
|
|
467
|
+
case "checkpointRestored":
|
|
468
|
+
return "ZCode restored a file checkpoint.";
|
|
469
|
+
}
|
|
470
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ProviderStatus,
|
|
3
|
+
ProviderStatusRequest,
|
|
4
|
+
} from "@getpaseo/plugin/server/provider";
|
|
5
|
+
import {
|
|
6
|
+
assertRuntimeSupported,
|
|
7
|
+
discoverRuntime,
|
|
8
|
+
} from "./discovery/discover.js";
|
|
9
|
+
import { AdapterError } from "./errors.js";
|
|
10
|
+
import { logger } from "./logger.js";
|
|
11
|
+
|
|
12
|
+
export interface RuntimeStatusOptions {
|
|
13
|
+
readonly environment?: NodeJS.ProcessEnv;
|
|
14
|
+
readonly discover?: typeof discoverRuntime;
|
|
15
|
+
/** How long a result is reused. Paseo asks on every catalog load and agent start. */
|
|
16
|
+
readonly ttlMs?: number;
|
|
17
|
+
readonly now?: () => number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Same shape as Paseo's built-in provider diagnostics; the daemon appends the
|
|
21
|
+
// model count and snapshot status as further indented lines.
|
|
22
|
+
const format = (entries: readonly [string, string][]) =>
|
|
23
|
+
["ZCode", ...entries.map(([label, value]) => ` ${label}: ${value}`)].join(
|
|
24
|
+
"\n",
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
async function check(
|
|
28
|
+
environment: NodeJS.ProcessEnv,
|
|
29
|
+
discover: typeof discoverRuntime,
|
|
30
|
+
): Promise<ProviderStatus> {
|
|
31
|
+
try {
|
|
32
|
+
const runtime = await discover({ environment });
|
|
33
|
+
assertRuntimeSupported(runtime);
|
|
34
|
+
const { appVersion, cliVersion, nodeVersion, platform } = runtime.identity;
|
|
35
|
+
return {
|
|
36
|
+
available: true,
|
|
37
|
+
diagnostic: format([
|
|
38
|
+
[
|
|
39
|
+
"Runtime",
|
|
40
|
+
`${runtime.source === "managed" ? "managed" : "PASEO_ZCODE_RUNTIME"}, Server ${appVersion}, Agent ${cliVersion}`,
|
|
41
|
+
],
|
|
42
|
+
["Node.js", nodeVersion],
|
|
43
|
+
["Platform", platform],
|
|
44
|
+
]),
|
|
45
|
+
};
|
|
46
|
+
} catch (error) {
|
|
47
|
+
// Discovery errors carry fixed messages; anything else stays in the log.
|
|
48
|
+
if (!(error instanceof AdapterError))
|
|
49
|
+
logger.error("zcode.provider.status.failed", error);
|
|
50
|
+
return {
|
|
51
|
+
available: false,
|
|
52
|
+
diagnostic: format([
|
|
53
|
+
[
|
|
54
|
+
"Error",
|
|
55
|
+
error instanceof AdapterError
|
|
56
|
+
? error.message
|
|
57
|
+
: "ZCode runtime could not be inspected",
|
|
58
|
+
],
|
|
59
|
+
]),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Availability for Paseo's provider snapshot and diagnostics (Paseo 0.11+;
|
|
66
|
+
* older daemons ignore it). It inspects the runtime without starting a Server,
|
|
67
|
+
* so sign-in problems still surface when a session opens.
|
|
68
|
+
*/
|
|
69
|
+
export function createRuntimeStatus(options: RuntimeStatusOptions = {}) {
|
|
70
|
+
const environment = options.environment ?? process.env;
|
|
71
|
+
const discover = options.discover ?? discoverRuntime;
|
|
72
|
+
const ttlMs = options.ttlMs ?? 30_000;
|
|
73
|
+
const now = options.now ?? Date.now;
|
|
74
|
+
let cached: { at: number; result: Promise<ProviderStatus> } | undefined;
|
|
75
|
+
return (_request?: ProviderStatusRequest): Promise<ProviderStatus> => {
|
|
76
|
+
if (cached && now() - cached.at < ttlMs) return cached.result;
|
|
77
|
+
const entry = { at: now(), result: check(environment, discover) };
|
|
78
|
+
cached = entry;
|
|
79
|
+
return entry.result;
|
|
80
|
+
};
|
|
81
|
+
}
|