@get-bb/plugin-sdk 0.4.16 → 0.4.18
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/bundled-types/bb-plugin-sdk-internal-host-policy.d.ts +4 -3
- package/bundled-types/bb-plugin-sdk-provider-bridge-acp.d.ts +17 -0
- package/bundled-types/bb-plugin-sdk.d.ts +15 -6
- package/dist/internal/host-policy.js +13 -1
- package/dist/provider-bridge-acp.js +338 -47
- package/dist/provider-bridge-testing.js +1 -1
- package/dist/provider-bridge.js +1 -1
- package/dist/testing/index.js +14 -6
- package/package.json +1 -1
|
@@ -9,8 +9,8 @@ import { z } from 'zod';
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Core `bb` CLI top-level command names (plus commander's built-in help).
|
|
12
|
-
*
|
|
13
|
-
* against the real Commander program by
|
|
12
|
+
* Core commands win these names; plugin scaffolding rejects them. Maintained
|
|
13
|
+
* by hand and checked against the real Commander program by
|
|
14
14
|
* apps/cli/src/__tests__/plugin-cli-proxy.test.ts.
|
|
15
15
|
*
|
|
16
16
|
* "automation" and "connect" are intentionally absent: builtin plugins own
|
|
@@ -583,6 +583,7 @@ interface PluginAiServiceDeclaration {
|
|
|
583
583
|
readonly kinds: readonly PluginAiServiceKind[];
|
|
584
584
|
}
|
|
585
585
|
|
|
586
|
+
declare function pluginCliCollisionWarning(pluginId: string, commandName: string): string | null;
|
|
586
587
|
/**
|
|
587
588
|
* Built-in dynamic tool names plugins may not shadow. Maintained by hand —
|
|
588
589
|
* kept in sync with the built-in tools in
|
|
@@ -789,5 +790,5 @@ declare function agentToolIconRefusalMessage(toolName: string, problem: string):
|
|
|
789
790
|
*/
|
|
790
791
|
declare function providerWithoutBridgeMessage(providerId: string): string;
|
|
791
792
|
|
|
792
|
-
export { AGENT_TOOL_NAME_PATTERN, BACKGROUND_NAME_PATTERN, CLI_COMMAND_NAME_PATTERN, KV_VALUE_MAX_BYTES, MENTION_PROVIDER_ID_PATTERN, PLUGIN_AGENT_DYNAMIC_INSTRUCTIONS_MAX_CHARS, PLUGIN_AGENT_SELECTION_MAX_IDS, PLUGIN_AGENT_STATIC_INSTRUCTIONS_MAX_CHARS, PLUGIN_AGENT_STATUS_LABEL_MAX_CHARS, PLUGIN_AGENT_TOOL_PARAMETERS_MAX_BYTES, PLUGIN_HTTP_METHODS, PLUGIN_MENTION_TRIGGER_VALUES, PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES, PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES, PLUGIN_PROVIDER_DISPLAY_NAME_MAX_CHARS, PLUGIN_PROVIDER_PERMISSION_MODE_VALUES, PLUGIN_PROVIDER_REASONING_LEVEL_VALUES, PROVIDER_ID_PATTERN, RESERVED_AGENT_TOOL_NAMES, RESERVED_BB_CLI_COMMANDS, RPC_METHOD_PATTERN, SERVER_DIRECT_AI_SERVICE_IDS, SETTING_KEY_PATTERN, adoptHttpRouteResponse, agentToolIconRefusalMessage, aiServiceAlreadyRegisteredMessage, assertAiServiceRegistrable, assertNoRecursiveJsonSchemaReferences, deriveValidatedProviderOptions, enforcePluginCliOutputLimit, isPluginMentionTrigger, isStandardSchema, isZodSchemaLike, normalizeMentionProviderTriggers, parsePluginAgentToolPresentation, providerAlreadyRegisteredMessage, providerIconRefusalMessage, providerWithoutBridgeMessage, readRpcMethodContract, registerSettingDescriptors, rejectStaleAgentToolFields, summarizeParseIssues, undeclaredIconProblem, validatePluginAiServiceDeclaration, validatePluginProviderDeclaration, validateSettingsUpdate };
|
|
793
|
+
export { AGENT_TOOL_NAME_PATTERN, BACKGROUND_NAME_PATTERN, CLI_COMMAND_NAME_PATTERN, KV_VALUE_MAX_BYTES, MENTION_PROVIDER_ID_PATTERN, PLUGIN_AGENT_DYNAMIC_INSTRUCTIONS_MAX_CHARS, PLUGIN_AGENT_SELECTION_MAX_IDS, PLUGIN_AGENT_STATIC_INSTRUCTIONS_MAX_CHARS, PLUGIN_AGENT_STATUS_LABEL_MAX_CHARS, PLUGIN_AGENT_TOOL_PARAMETERS_MAX_BYTES, PLUGIN_HTTP_METHODS, PLUGIN_MENTION_TRIGGER_VALUES, PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES, PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES, PLUGIN_PROVIDER_DISPLAY_NAME_MAX_CHARS, PLUGIN_PROVIDER_PERMISSION_MODE_VALUES, PLUGIN_PROVIDER_REASONING_LEVEL_VALUES, PROVIDER_ID_PATTERN, RESERVED_AGENT_TOOL_NAMES, RESERVED_BB_CLI_COMMANDS, RPC_METHOD_PATTERN, SERVER_DIRECT_AI_SERVICE_IDS, SETTING_KEY_PATTERN, adoptHttpRouteResponse, agentToolIconRefusalMessage, aiServiceAlreadyRegisteredMessage, assertAiServiceRegistrable, assertNoRecursiveJsonSchemaReferences, deriveValidatedProviderOptions, enforcePluginCliOutputLimit, isPluginMentionTrigger, isStandardSchema, isZodSchemaLike, normalizeMentionProviderTriggers, parsePluginAgentToolPresentation, pluginCliCollisionWarning, providerAlreadyRegisteredMessage, providerIconRefusalMessage, providerWithoutBridgeMessage, readRpcMethodContract, registerSettingDescriptors, rejectStaleAgentToolFields, summarizeParseIssues, undeclaredIconProblem, validatePluginAiServiceDeclaration, validatePluginProviderDeclaration, validateSettingsUpdate };
|
|
793
794
|
export type { AiServiceHostBinding, NormalizedPluginProviderDeclaration };
|
|
@@ -467,6 +467,12 @@ interface AcpClassifiedToolCall {
|
|
|
467
467
|
item: DeltaItemShape;
|
|
468
468
|
presentation: DeltaPresentation;
|
|
469
469
|
}
|
|
470
|
+
interface AcpCommandResult {
|
|
471
|
+
/** The process exit code the agent reported; absent when it reported none. */
|
|
472
|
+
exitCode?: number;
|
|
473
|
+
/** The command's output text; absent when the agent reported none. */
|
|
474
|
+
output?: string;
|
|
475
|
+
}
|
|
470
476
|
|
|
471
477
|
/**
|
|
472
478
|
* Per-agent dialects: the vendor side channels of an ACP agent.
|
|
@@ -525,6 +531,17 @@ interface AcpDialect {
|
|
|
525
531
|
* the shared classifier in charge — which is the normal answer.
|
|
526
532
|
*/
|
|
527
533
|
classifyToolCall?(event: AcpToolCallUpdateEvent): AcpClassifiedToolCall | undefined;
|
|
534
|
+
/**
|
|
535
|
+
* A command result carried in the agent's non-standard rawOutput shape.
|
|
536
|
+
* Returning `undefined` leaves the shared ACP result parser in charge.
|
|
537
|
+
*/
|
|
538
|
+
commandResult?(event: AcpToolCallUpdateEvent): AcpCommandResult | undefined;
|
|
539
|
+
/**
|
|
540
|
+
* A command event with the agent's non-standard result fields normalized
|
|
541
|
+
* into the shared ACP result shapes. The hook runs only after the call has
|
|
542
|
+
* classified as a command; existing shared result fields must win.
|
|
543
|
+
*/
|
|
544
|
+
normalizeCommandEvent?(event: AcpToolCallUpdateEvent): AcpToolCallUpdateEvent;
|
|
528
545
|
/**
|
|
529
546
|
* A vendor JSON-RPC request the agent sends to the client. A dialect that
|
|
530
547
|
* answers one returns the JSON-RPC result to reply with (`{}` is a valid
|
|
@@ -7865,6 +7865,7 @@ declare const pluginCatalogSearchResultSchema: z$1.ZodObject<{
|
|
|
7865
7865
|
iconUrl: z$1.ZodNullable<z$1.ZodString>;
|
|
7866
7866
|
incompatibleReason: z$1.ZodNullable<z$1.ZodString>;
|
|
7867
7867
|
installed: z$1.ZodBoolean;
|
|
7868
|
+
installs: z$1.ZodDefault<z$1.ZodNullable<z$1.ZodNumber>>;
|
|
7868
7869
|
marketplace: z$1.ZodString;
|
|
7869
7870
|
marketplaceDisplayName: z$1.ZodString;
|
|
7870
7871
|
official: z$1.ZodBoolean;
|
|
@@ -10233,6 +10234,15 @@ declare const sendMessageRequestSchema: z$1.ZodObject<{
|
|
|
10233
10234
|
}>>;
|
|
10234
10235
|
}, z$1.core.$strip>;
|
|
10235
10236
|
type SendMessageRequest = z$1.infer<typeof sendMessageRequestSchema>;
|
|
10237
|
+
declare const sendMessageResponseSchema: z$1.ZodObject<{
|
|
10238
|
+
delivery: z$1.ZodEnum<{
|
|
10239
|
+
deferred: "deferred";
|
|
10240
|
+
queued: "queued";
|
|
10241
|
+
sent: "sent";
|
|
10242
|
+
}>;
|
|
10243
|
+
ok: z$1.ZodLiteral<true>;
|
|
10244
|
+
}, z$1.core.$strip>;
|
|
10245
|
+
type SendMessageResponse = z$1.infer<typeof sendMessageResponseSchema>;
|
|
10236
10246
|
declare const editMessageRequestSchema: z$1.ZodObject<{
|
|
10237
10247
|
executionInputSources: z$1.ZodOptional<z$1.ZodObject<{
|
|
10238
10248
|
model: z$1.ZodOptional<z$1.ZodEnum<{
|
|
@@ -15194,9 +15204,7 @@ type ThreadPaneActionResult = ThreadPaneActionResponse;
|
|
|
15194
15204
|
type ThreadDeleteResult = {
|
|
15195
15205
|
ok: true;
|
|
15196
15206
|
};
|
|
15197
|
-
type ThreadSendResult =
|
|
15198
|
-
ok: true;
|
|
15199
|
-
};
|
|
15207
|
+
type ThreadSendResult = SendMessageResponse;
|
|
15200
15208
|
type ThreadEditMessageResult = EditMessageResponse;
|
|
15201
15209
|
type ThreadStopResult = {
|
|
15202
15210
|
ok: true;
|
|
@@ -15851,8 +15859,9 @@ interface PluginCliExecutionResult {
|
|
|
15851
15859
|
error?: PluginCliOutputLimitError;
|
|
15852
15860
|
}
|
|
15853
15861
|
interface PluginCliRegistration {
|
|
15854
|
-
/**
|
|
15855
|
-
*
|
|
15862
|
+
/** Preferred top-level command name (`bb <name> …`): lowercase [a-z0-9-]+.
|
|
15863
|
+
* A core collision logs an activation warning and remains available through
|
|
15864
|
+
* `bb plugin run <plugin-id>`. */
|
|
15856
15865
|
name: string;
|
|
15857
15866
|
summary: string;
|
|
15858
15867
|
/** Subcommand metadata rendered in help and the plugin-commands skill
|
|
@@ -15864,7 +15873,7 @@ interface PluginCli {
|
|
|
15864
15873
|
/**
|
|
15865
15874
|
* Register this plugin's `bb` subcommand. One registration per factory
|
|
15866
15875
|
* execution; a repeated call is rejected. Core bb commands always win
|
|
15867
|
-
* name collisions;
|
|
15876
|
+
* name collisions; the plugin is warned and remains explicitly callable by id.
|
|
15868
15877
|
*/
|
|
15869
15878
|
register(registration: PluginCliRegistration): void;
|
|
15870
15879
|
}
|
|
@@ -24,16 +24,23 @@ function parseNamespacedGlyph(glyph) {
|
|
|
24
24
|
// ../domain/src/plugin-cli.ts
|
|
25
25
|
var RESERVED_BB_CLI_COMMANDS = [
|
|
26
26
|
"environment",
|
|
27
|
+
"file",
|
|
27
28
|
"guide",
|
|
28
29
|
"help",
|
|
30
|
+
"machine",
|
|
29
31
|
"manager",
|
|
32
|
+
"marketplace",
|
|
30
33
|
"plugin",
|
|
31
34
|
"project",
|
|
32
35
|
"provider",
|
|
36
|
+
"settings",
|
|
33
37
|
"skill",
|
|
34
38
|
"status",
|
|
39
|
+
"terminal",
|
|
35
40
|
"theme",
|
|
36
|
-
"thread"
|
|
41
|
+
"thread",
|
|
42
|
+
"updates",
|
|
43
|
+
"voice"
|
|
37
44
|
];
|
|
38
45
|
|
|
39
46
|
// ../domain/src/provider-fork.ts
|
|
@@ -252,6 +259,10 @@ var providerNativeRootSetSchema = z2.object({
|
|
|
252
259
|
var PLUGIN_CLI_OUTPUT_MAX_BYTES = 1024 * 1024;
|
|
253
260
|
|
|
254
261
|
// src/internal/host-policy.ts
|
|
262
|
+
function pluginCliCollisionWarning(pluginId, commandName) {
|
|
263
|
+
if (!RESERVED_BB_CLI_COMMANDS.includes(commandName)) return null;
|
|
264
|
+
return `CLI command "${commandName}" collides with core command "bb ${commandName}"; core keeps the short form. Use "bb plugin run ${pluginId}" to invoke this plugin.`;
|
|
265
|
+
}
|
|
255
266
|
var RESERVED_AGENT_TOOL_NAMES = [
|
|
256
267
|
"update_environment_directory"
|
|
257
268
|
];
|
|
@@ -1646,6 +1657,7 @@ export {
|
|
|
1646
1657
|
isZodSchemaLike,
|
|
1647
1658
|
normalizeMentionProviderTriggers,
|
|
1648
1659
|
parsePluginAgentToolPresentation,
|
|
1660
|
+
pluginCliCollisionWarning,
|
|
1649
1661
|
providerAlreadyRegisteredMessage,
|
|
1650
1662
|
providerIconRefusalMessage,
|
|
1651
1663
|
providerWithoutBridgeMessage,
|
|
@@ -3116,7 +3116,7 @@ var deltaItemShapeSchema = z24.discriminatedUnion("type", [
|
|
|
3116
3116
|
}),
|
|
3117
3117
|
z24.object({
|
|
3118
3118
|
type: z24.literal("fileChange"),
|
|
3119
|
-
/** Empty
|
|
3119
|
+
/** Empty while a path is not yet known, including bare close fallbacks. */
|
|
3120
3120
|
changes: z24.array(deltaFileChangeSchema)
|
|
3121
3121
|
}),
|
|
3122
3122
|
/**
|
|
@@ -5235,13 +5235,126 @@ var CURSOR_ACP_DIALECT = {
|
|
|
5235
5235
|
handleClientRequest: cursorHandleClientRequest,
|
|
5236
5236
|
maintenance: CURSOR_ACP_MAINTENANCE
|
|
5237
5237
|
};
|
|
5238
|
+
var ompBashRawInputSchema = z35.object({
|
|
5239
|
+
command: z35.string(),
|
|
5240
|
+
async: z35.boolean().optional()
|
|
5241
|
+
}).passthrough();
|
|
5242
|
+
var ompBashRawOutputSchema = z35.object({
|
|
5243
|
+
content: z35.array(
|
|
5244
|
+
z35.object({
|
|
5245
|
+
type: z35.literal("text"),
|
|
5246
|
+
text: z35.string()
|
|
5247
|
+
}).passthrough()
|
|
5248
|
+
),
|
|
5249
|
+
details: z35.object({
|
|
5250
|
+
exitCode: z35.number().int().optional(),
|
|
5251
|
+
wallTimeMs: z35.number().nonnegative().optional(),
|
|
5252
|
+
timedOut: z35.boolean().optional(),
|
|
5253
|
+
signal: z35.unknown().optional(),
|
|
5254
|
+
async: z35.unknown().optional()
|
|
5255
|
+
}).passthrough(),
|
|
5256
|
+
// If an OMP version emits generic ACP result fields, the shared parser
|
|
5257
|
+
// owns those exit/output/timeout/signal semantics.
|
|
5258
|
+
exitCode: z35.number().int().nullable().optional(),
|
|
5259
|
+
exit_code: z35.number().int().nullable().optional(),
|
|
5260
|
+
stdout: z35.string().optional(),
|
|
5261
|
+
stderr: z35.string().optional(),
|
|
5262
|
+
output_for_prompt: z35.string().optional(),
|
|
5263
|
+
signal: z35.string().nullable().optional(),
|
|
5264
|
+
timed_out: z35.boolean().optional()
|
|
5265
|
+
}).passthrough();
|
|
5266
|
+
function stripOmpTrailingNotice(text, notice) {
|
|
5267
|
+
const suffix = `
|
|
5268
|
+
|
|
5269
|
+
${notice}`;
|
|
5270
|
+
return text.endsWith(suffix) ? text.slice(0, -suffix.length) : text;
|
|
5271
|
+
}
|
|
5272
|
+
function ompCommandResult(event) {
|
|
5273
|
+
if (event.kind !== "execute") {
|
|
5274
|
+
return void 0;
|
|
5275
|
+
}
|
|
5276
|
+
const parsedInput = ompBashRawInputSchema.safeParse(event.rawInput);
|
|
5277
|
+
const parsedOutput = ompBashRawOutputSchema.safeParse(event.rawOutput);
|
|
5278
|
+
if (!parsedInput.success || parsedInput.data.command.trim().length === 0 || !parsedOutput.success) {
|
|
5279
|
+
return void 0;
|
|
5280
|
+
}
|
|
5281
|
+
const rawOutput = parsedOutput.data;
|
|
5282
|
+
const details = rawOutput.details;
|
|
5283
|
+
const hasGenericCommandResult = rawOutput.exitCode !== void 0 || rawOutput.exit_code !== void 0 || rawOutput.stdout !== void 0 || rawOutput.stderr !== void 0 || rawOutput.output_for_prompt !== void 0 || rawOutput.signal !== void 0 && rawOutput.signal !== null || rawOutput.timed_out === true;
|
|
5284
|
+
if (parsedInput.data.async === true || details.async !== void 0 || hasGenericCommandResult) {
|
|
5285
|
+
return void 0;
|
|
5286
|
+
}
|
|
5287
|
+
if (details.exitCode === void 0 && details.wallTimeMs === void 0) {
|
|
5288
|
+
return void 0;
|
|
5289
|
+
}
|
|
5290
|
+
let output = rawOutput.content.map((block) => block.text).join("\n");
|
|
5291
|
+
if (details.exitCode !== void 0) {
|
|
5292
|
+
output = stripOmpTrailingNotice(
|
|
5293
|
+
output,
|
|
5294
|
+
`Command exited with code ${String(details.exitCode)}`
|
|
5295
|
+
);
|
|
5296
|
+
}
|
|
5297
|
+
if (details.wallTimeMs !== void 0) {
|
|
5298
|
+
output = stripOmpTrailingNotice(
|
|
5299
|
+
output,
|
|
5300
|
+
`Wall time: ${(details.wallTimeMs / 1e3).toFixed(2)} seconds`
|
|
5301
|
+
);
|
|
5302
|
+
}
|
|
5303
|
+
const isCompletedForegroundBash = event.status === "completed" && details.timedOut !== true && (details.signal === void 0 || details.signal === null);
|
|
5304
|
+
const exitCode = details.exitCode ?? (isCompletedForegroundBash ? 0 : void 0);
|
|
5305
|
+
return {
|
|
5306
|
+
...exitCode === void 0 ? {} : { exitCode },
|
|
5307
|
+
...output.length === 0 ? {} : { output }
|
|
5308
|
+
};
|
|
5309
|
+
}
|
|
5310
|
+
var OMP_ACP_DIALECT = {
|
|
5311
|
+
id: "omp",
|
|
5312
|
+
commandResult: ompCommandResult
|
|
5313
|
+
};
|
|
5314
|
+
var openCodeCommandRawOutputSchema = z35.object({
|
|
5315
|
+
output: z35.unknown().optional(),
|
|
5316
|
+
metadata: z35.object({
|
|
5317
|
+
exit: z35.number().int().nullable().optional(),
|
|
5318
|
+
output: z35.string().optional()
|
|
5319
|
+
}).passthrough().optional()
|
|
5320
|
+
}).passthrough();
|
|
5321
|
+
function normalizeOpenCodeCommandEvent(event) {
|
|
5322
|
+
const parsed = openCodeCommandRawOutputSchema.safeParse(event.rawOutput);
|
|
5323
|
+
if (!parsed.success) {
|
|
5324
|
+
return event;
|
|
5325
|
+
}
|
|
5326
|
+
const rawOutput = parsed.data;
|
|
5327
|
+
const output = typeof rawOutput.output === "string" ? rawOutput.output : rawOutput.metadata?.output;
|
|
5328
|
+
const hasSharedOutput = rawOutput["stdout"] !== void 0 || rawOutput["stderr"] !== void 0 || rawOutput["output_for_prompt"] !== void 0;
|
|
5329
|
+
const hasSharedExitCode = rawOutput["exitCode"] !== void 0 || rawOutput["exit_code"] !== void 0;
|
|
5330
|
+
const exitCode = rawOutput.metadata?.exit ?? void 0;
|
|
5331
|
+
if ((output === void 0 || hasSharedOutput) && (exitCode === void 0 || hasSharedExitCode)) {
|
|
5332
|
+
return event;
|
|
5333
|
+
}
|
|
5334
|
+
return {
|
|
5335
|
+
...event,
|
|
5336
|
+
rawOutput: {
|
|
5337
|
+
...rawOutput,
|
|
5338
|
+
...output === void 0 || hasSharedOutput ? {} : { stdout: output },
|
|
5339
|
+
...exitCode === void 0 || hasSharedExitCode ? {} : { exitCode }
|
|
5340
|
+
}
|
|
5341
|
+
};
|
|
5342
|
+
}
|
|
5343
|
+
var OPENCODE_ACP_DIALECT = {
|
|
5344
|
+
id: "opencode",
|
|
5345
|
+
normalizeCommandEvent: normalizeOpenCodeCommandEvent
|
|
5346
|
+
};
|
|
5238
5347
|
var DIALECTS_BY_ID = /* @__PURE__ */ new Map([
|
|
5239
5348
|
[CURSOR_ACP_DIALECT.id, CURSOR_ACP_DIALECT],
|
|
5240
|
-
[GROK_ACP_DIALECT.id, GROK_ACP_DIALECT]
|
|
5349
|
+
[GROK_ACP_DIALECT.id, GROK_ACP_DIALECT],
|
|
5350
|
+
[OMP_ACP_DIALECT.id, OMP_ACP_DIALECT],
|
|
5351
|
+
[OPENCODE_ACP_DIALECT.id, OPENCODE_ACP_DIALECT]
|
|
5241
5352
|
]);
|
|
5242
5353
|
var DIALECT_IDS_BY_COMMAND = {
|
|
5243
5354
|
"cursor-agent": CURSOR_ACP_DIALECT.id,
|
|
5244
|
-
grok: GROK_ACP_DIALECT.id
|
|
5355
|
+
grok: GROK_ACP_DIALECT.id,
|
|
5356
|
+
omp: OMP_ACP_DIALECT.id,
|
|
5357
|
+
opencode: OPENCODE_ACP_DIALECT.id
|
|
5245
5358
|
};
|
|
5246
5359
|
function resolveAcpDialect(launch) {
|
|
5247
5360
|
if (launch.dialectId !== void 0) {
|
|
@@ -5317,9 +5430,6 @@ function classifyAcpToolCall(event, options) {
|
|
|
5317
5430
|
}
|
|
5318
5431
|
}
|
|
5319
5432
|
const paths = extractAcpToolCallPaths(event, options);
|
|
5320
|
-
if (paths.length === 0) {
|
|
5321
|
-
return { kind: "generic" };
|
|
5322
|
-
}
|
|
5323
5433
|
const hasDiff = (event.content ?? []).some((entry) => entry.type === "diff");
|
|
5324
5434
|
if (hasDiff || event.kind === "edit") {
|
|
5325
5435
|
return { kind: "file_change", changeKind: "update", paths };
|
|
@@ -5553,7 +5663,10 @@ function urlFromTitle(title) {
|
|
|
5553
5663
|
function looksLikePath(token) {
|
|
5554
5664
|
return token.startsWith("/") || token.startsWith("~") || token.startsWith(".");
|
|
5555
5665
|
}
|
|
5556
|
-
function fileChangeVerb(changes) {
|
|
5666
|
+
function fileChangeVerb(changes, fallback) {
|
|
5667
|
+
if (changes.length === 0) {
|
|
5668
|
+
return fallback;
|
|
5669
|
+
}
|
|
5557
5670
|
if (changes.every((change) => change.kind === "add")) {
|
|
5558
5671
|
return "add";
|
|
5559
5672
|
}
|
|
@@ -5582,11 +5695,11 @@ function buildAcpFileChanges(event, operation, options) {
|
|
|
5582
5695
|
const [path5] = operation.paths;
|
|
5583
5696
|
return path5 === void 0 ? [] : [{ path: path5, kind: operation.changeKind }];
|
|
5584
5697
|
}
|
|
5585
|
-
function fileChangeItem(changes) {
|
|
5698
|
+
function fileChangeItem(changes, fallbackVerb) {
|
|
5586
5699
|
return {
|
|
5587
5700
|
item: { type: "fileChange", changes },
|
|
5588
5701
|
presentation: fileChangePresentation({
|
|
5589
|
-
verb: fileChangeVerb(changes),
|
|
5702
|
+
verb: fileChangeVerb(changes, fallbackVerb),
|
|
5590
5703
|
paths: changes.map((change) => change.path)
|
|
5591
5704
|
})
|
|
5592
5705
|
};
|
|
@@ -5697,9 +5810,7 @@ function classifyAcpToolCall2(event, injected, options) {
|
|
|
5697
5810
|
}
|
|
5698
5811
|
if (operation.kind === "file_change") {
|
|
5699
5812
|
const changes = buildAcpFileChanges(event, operation, options);
|
|
5700
|
-
|
|
5701
|
-
return fileChangeItem(changes);
|
|
5702
|
-
}
|
|
5813
|
+
return fileChangeItem(changes, operation.changeKind);
|
|
5703
5814
|
}
|
|
5704
5815
|
const title = toOptionalString(event.title);
|
|
5705
5816
|
switch (event.kind) {
|
|
@@ -5920,6 +6031,73 @@ function createAcpDeltaTranslator(options = {}) {
|
|
|
5920
6031
|
}
|
|
5921
6032
|
return classifyAcpToolCall2(event, injected, pathOptions);
|
|
5922
6033
|
}
|
|
6034
|
+
function withClientFileWrites(event, writes) {
|
|
6035
|
+
if (writes.length === 0) {
|
|
6036
|
+
return event;
|
|
6037
|
+
}
|
|
6038
|
+
const paths = new Set(
|
|
6039
|
+
writes.map((write) => resolveAcpToolCallPath(write.path, pathOptions))
|
|
6040
|
+
);
|
|
6041
|
+
return {
|
|
6042
|
+
...event,
|
|
6043
|
+
content: [
|
|
6044
|
+
...(event.content ?? []).filter(
|
|
6045
|
+
(entry) => entry.type !== "diff" || !paths.has(resolveAcpToolCallPath(entry.path, pathOptions))
|
|
6046
|
+
),
|
|
6047
|
+
...writes
|
|
6048
|
+
]
|
|
6049
|
+
};
|
|
6050
|
+
}
|
|
6051
|
+
function mergeFsWriteIntoOpenToolCall(context, write) {
|
|
6052
|
+
const writePath = resolveAcpToolCallPath(write.path, pathOptions);
|
|
6053
|
+
const fileChangeCalls = threadCallEntries(context).flatMap(
|
|
6054
|
+
([key, open]) => {
|
|
6055
|
+
if (open.openedType !== "fileChange") {
|
|
6056
|
+
return [];
|
|
6057
|
+
}
|
|
6058
|
+
const classified = classifyCall(context, open.event);
|
|
6059
|
+
return classified.item.type === "fileChange" ? [
|
|
6060
|
+
{
|
|
6061
|
+
key,
|
|
6062
|
+
open,
|
|
6063
|
+
paths: classified.item.changes.map((change) => change.path)
|
|
6064
|
+
}
|
|
6065
|
+
] : [];
|
|
6066
|
+
}
|
|
6067
|
+
);
|
|
6068
|
+
const exactMatches = fileChangeCalls.filter(
|
|
6069
|
+
({ paths }) => paths.includes(writePath)
|
|
6070
|
+
);
|
|
6071
|
+
const pathPendingMatches = fileChangeCalls.filter(
|
|
6072
|
+
({ paths }) => paths.length === 0
|
|
6073
|
+
);
|
|
6074
|
+
const matching = exactMatches.length === 1 ? exactMatches[0] : exactMatches.length === 0 && pathPendingMatches.length === 1 ? pathPendingMatches[0] : void 0;
|
|
6075
|
+
if (matching === void 0) {
|
|
6076
|
+
return false;
|
|
6077
|
+
}
|
|
6078
|
+
const previous = matching.open.clientFileWrites?.find(
|
|
6079
|
+
(entry) => resolveAcpToolCallPath(entry.path, pathOptions) === writePath
|
|
6080
|
+
);
|
|
6081
|
+
const oldText = previous === void 0 ? write.oldText : previous.oldText;
|
|
6082
|
+
const diff = {
|
|
6083
|
+
type: "diff",
|
|
6084
|
+
path: write.path,
|
|
6085
|
+
...oldText === void 0 ? {} : { oldText },
|
|
6086
|
+
newText: write.content
|
|
6087
|
+
};
|
|
6088
|
+
const clientFileWrites = [
|
|
6089
|
+
...(matching.open.clientFileWrites ?? []).filter(
|
|
6090
|
+
(entry) => resolveAcpToolCallPath(entry.path, pathOptions) !== writePath
|
|
6091
|
+
),
|
|
6092
|
+
diff
|
|
6093
|
+
];
|
|
6094
|
+
mergedToolCalls.set(matching.key, {
|
|
6095
|
+
...matching.open,
|
|
6096
|
+
clientFileWrites,
|
|
6097
|
+
event: withClientFileWrites(matching.open.event, clientFileWrites)
|
|
6098
|
+
});
|
|
6099
|
+
return true;
|
|
6100
|
+
}
|
|
5923
6101
|
function toRawEvent(rawEvent) {
|
|
5924
6102
|
const parsed = providerRawEventSchema.safeParse(rawEvent);
|
|
5925
6103
|
if (parsed.success) {
|
|
@@ -6036,7 +6214,8 @@ function createAcpDeltaTranslator(options = {}) {
|
|
|
6036
6214
|
};
|
|
6037
6215
|
}
|
|
6038
6216
|
function commandCloseFields(event, status) {
|
|
6039
|
-
const
|
|
6217
|
+
const normalizedEvent = dialect.normalizeCommandEvent?.(event) ?? event;
|
|
6218
|
+
const result = dialect.commandResult?.(normalizedEvent) ?? extractAcpCommandResult(normalizedEvent);
|
|
6040
6219
|
const exitCode = result.exitCode ?? (status === "failed" ? 1 : void 0);
|
|
6041
6220
|
return {
|
|
6042
6221
|
...result.output === void 0 ? {} : { aggregatedOutput: result.output, resultText: result.output },
|
|
@@ -6155,7 +6334,10 @@ function createAcpDeltaTranslator(options = {}) {
|
|
|
6155
6334
|
const event = withDialectIdentity(parsed.data);
|
|
6156
6335
|
const key = callKey(context, event.toolCallId);
|
|
6157
6336
|
const open = mergedToolCalls.get(key);
|
|
6158
|
-
const merged =
|
|
6337
|
+
const merged = withClientFileWrites(
|
|
6338
|
+
mergeAcpToolCallEvents(open?.event, event),
|
|
6339
|
+
open?.clientFileWrites ?? []
|
|
6340
|
+
);
|
|
6159
6341
|
if (isTerminalAcpStatus(merged.status)) {
|
|
6160
6342
|
mergedToolCalls.delete(key);
|
|
6161
6343
|
return [
|
|
@@ -6174,10 +6356,12 @@ function createAcpDeltaTranslator(options = {}) {
|
|
|
6174
6356
|
event: merged,
|
|
6175
6357
|
openedType: open?.openedType ?? mergedType,
|
|
6176
6358
|
...open?.permissionTitle === void 0 ? {} : { permissionTitle: open.permissionTitle },
|
|
6177
|
-
...open?.delegation === void 0 ? {} : { delegation: open.delegation }
|
|
6359
|
+
...open?.delegation === void 0 ? {} : { delegation: open.delegation },
|
|
6360
|
+
...open?.clientFileWrites === void 0 ? {} : { clientFileWrites: open.clientFileWrites }
|
|
6178
6361
|
});
|
|
6179
6362
|
if (event.status === "in_progress" && mergedType === "command" && open?.openedType === "command") {
|
|
6180
|
-
const
|
|
6363
|
+
const normalizedEvent = dialect.normalizeCommandEvent?.(event) ?? event;
|
|
6364
|
+
const streamed = extractAcpStreamedCommandOutput(normalizedEvent);
|
|
6181
6365
|
return streamed === void 0 ? suppressedUnhandled(rawEvent) : [
|
|
6182
6366
|
{
|
|
6183
6367
|
kind: "command.outputSnapshot",
|
|
@@ -6354,6 +6538,9 @@ function createAcpDeltaTranslator(options = {}) {
|
|
|
6354
6538
|
if (!params.success) {
|
|
6355
6539
|
return [];
|
|
6356
6540
|
}
|
|
6541
|
+
if (mergeFsWriteIntoOpenToolCall(context, params.data)) {
|
|
6542
|
+
return [];
|
|
6543
|
+
}
|
|
6357
6544
|
const rawEvent = {
|
|
6358
6545
|
jsonrpc: "2.0",
|
|
6359
6546
|
method: ACP_FS_WRITE_METHOD,
|
|
@@ -6676,31 +6863,44 @@ function buildAcpModelDiscoveryAgentCommand(launchSpec) {
|
|
|
6676
6863
|
...launchEnvVars(launchSpec)
|
|
6677
6864
|
};
|
|
6678
6865
|
}
|
|
6679
|
-
function buildAcpModelListParams(launchSpec) {
|
|
6866
|
+
function buildAcpModelListParams(launchSpec, options) {
|
|
6867
|
+
const primaryModels = [
|
|
6868
|
+
...options.primaryModels ?? launchSpec?.modelCli?.primaryModels ?? []
|
|
6869
|
+
];
|
|
6870
|
+
const reasoningProbePriorityModelIds = [
|
|
6871
|
+
...options.reasoningProbePriorityModelIds
|
|
6872
|
+
];
|
|
6680
6873
|
if (launchSpec === null) {
|
|
6681
|
-
return {
|
|
6874
|
+
return {
|
|
6875
|
+
primaryModels,
|
|
6876
|
+
reasoningProbePriorityModelIds,
|
|
6877
|
+
parameterizedModelPicker: options.parameterizedModelPicker
|
|
6878
|
+
};
|
|
6682
6879
|
}
|
|
6683
6880
|
const listCommand = buildAcpModelListCommand(launchSpec);
|
|
6684
6881
|
const agent = buildAcpModelDiscoveryAgentCommand(launchSpec);
|
|
6685
6882
|
return {
|
|
6686
6883
|
...listCommand !== void 0 ? { listCommand } : {},
|
|
6687
6884
|
...agent !== void 0 ? { agent } : {},
|
|
6688
|
-
primaryModels
|
|
6885
|
+
primaryModels,
|
|
6886
|
+
reasoningProbePriorityModelIds,
|
|
6887
|
+
parameterizedModelPicker: options.parameterizedModelPicker,
|
|
6689
6888
|
...launchSpec.reasoningCli !== void 0 ? { reasoningCli: launchSpec.reasoningCli } : {},
|
|
6690
6889
|
...launchSpec.nativeReasoning !== void 0 ? { nativeReasoning: launchSpec.nativeReasoning } : {}
|
|
6691
6890
|
};
|
|
6692
6891
|
}
|
|
6693
|
-
function buildAcpModelSelectionParam(launchSpec, options) {
|
|
6892
|
+
function buildAcpModelSelectionParam(launchSpec, options, parameterizedModelPicker) {
|
|
6694
6893
|
const model = options.model;
|
|
6695
6894
|
const listCommand = buildAcpModelListCommand(launchSpec);
|
|
6696
6895
|
if (!model || model === ACP_DEFAULT_MODEL_ID) {
|
|
6697
6896
|
return {};
|
|
6698
6897
|
}
|
|
6699
|
-
if (!listCommand || !launchSpec.modelCli?.selectFlag) {
|
|
6898
|
+
if (parameterizedModelPicker || !listCommand || !launchSpec.modelCli?.selectFlag) {
|
|
6700
6899
|
return {
|
|
6701
6900
|
modelSelection: {
|
|
6702
6901
|
modelId: model,
|
|
6703
|
-
...options.reasoningLevel !== void 0 ? { reasoningLevel: options.reasoningLevel } : {}
|
|
6902
|
+
...options.reasoningLevel !== void 0 ? { reasoningLevel: options.reasoningLevel } : {},
|
|
6903
|
+
...parameterizedModelPicker && options.serviceTier !== void 0 ? { serviceTier: options.serviceTier } : {}
|
|
6704
6904
|
}
|
|
6705
6905
|
};
|
|
6706
6906
|
}
|
|
@@ -6710,7 +6910,7 @@ function buildAcpModelSelectionParam(launchSpec, options) {
|
|
|
6710
6910
|
selectFlag: launchSpec.modelCli.selectFlag,
|
|
6711
6911
|
model,
|
|
6712
6912
|
...options.reasoningLevel !== void 0 ? { reasoningLevel: options.reasoningLevel } : {},
|
|
6713
|
-
// Only "fast" changes resolution; "default" is the
|
|
6913
|
+
// Only "fast" changes launch resolution; "default" is the normal id.
|
|
6714
6914
|
...options.serviceTier === "fast" ? { serviceTier: options.serviceTier } : {}
|
|
6715
6915
|
}
|
|
6716
6916
|
};
|
|
@@ -6736,7 +6936,12 @@ function buildAcpSessionParams(args) {
|
|
|
6736
6936
|
args: [...launchSpec.args]
|
|
6737
6937
|
},
|
|
6738
6938
|
...args.dialectId === void 0 ? {} : { dialectId: args.dialectId },
|
|
6739
|
-
...buildAcpModelSelectionParam(
|
|
6939
|
+
...buildAcpModelSelectionParam(
|
|
6940
|
+
launchSpec,
|
|
6941
|
+
options,
|
|
6942
|
+
args.parameterizedModelPicker
|
|
6943
|
+
),
|
|
6944
|
+
parameterizedModelPicker: args.parameterizedModelPicker,
|
|
6740
6945
|
...launchSpec.reasoningCli !== void 0 ? { reasoningCli: launchSpec.reasoningCli } : {},
|
|
6741
6946
|
...launchSpec.nativeReasoning !== void 0 ? { nativeReasoning: launchSpec.nativeReasoning } : {},
|
|
6742
6947
|
...launchSpec.permissionCli !== void 0 ? { permissionCli: launchSpec.permissionCli } : {},
|
|
@@ -8128,6 +8333,13 @@ async function authenticateAcpAgent(args) {
|
|
|
8128
8333
|
);
|
|
8129
8334
|
}
|
|
8130
8335
|
}
|
|
8336
|
+
function acpClientCapabilities(parameterizedModelPicker, fsAccess = false) {
|
|
8337
|
+
return {
|
|
8338
|
+
fs: { readTextFile: fsAccess, writeTextFile: fsAccess },
|
|
8339
|
+
terminal: false,
|
|
8340
|
+
...parameterizedModelPicker === true ? { _meta: { parameterizedModelPicker: true } } : {}
|
|
8341
|
+
};
|
|
8342
|
+
}
|
|
8131
8343
|
async function loadAgentModelCatalog(listCommand) {
|
|
8132
8344
|
const stdout = await new Promise((resolveExec, rejectExec) => {
|
|
8133
8345
|
execFile4(
|
|
@@ -8177,8 +8389,12 @@ async function loadAgentModelCatalog(listCommand) {
|
|
|
8177
8389
|
cachedModelCatalog = { key, catalog };
|
|
8178
8390
|
return catalog;
|
|
8179
8391
|
}
|
|
8180
|
-
async function loadSessionDiscoveredModels(agent) {
|
|
8181
|
-
const key = JSON.stringify(
|
|
8392
|
+
async function loadSessionDiscoveredModels(agent, reasoningProbePriorityModelIds, parameterizedModelPicker) {
|
|
8393
|
+
const key = JSON.stringify({
|
|
8394
|
+
agent,
|
|
8395
|
+
reasoningProbePriorityModelIds,
|
|
8396
|
+
parameterizedModelPicker
|
|
8397
|
+
});
|
|
8182
8398
|
if (cachedSessionDiscoveredModels?.key === key && Date.now() - cachedSessionDiscoveredModels.fetchedAt < SESSION_MODEL_DISCOVERY_TTL_MS) {
|
|
8183
8399
|
return cachedSessionDiscoveredModels.models;
|
|
8184
8400
|
}
|
|
@@ -8219,10 +8435,7 @@ async function loadSessionDiscoveredModels(agent) {
|
|
|
8219
8435
|
params: {
|
|
8220
8436
|
protocolVersion: ACP_PROTOCOL_VERSION,
|
|
8221
8437
|
clientInfo: { name: "bb", version: "1.0.0" },
|
|
8222
|
-
clientCapabilities:
|
|
8223
|
-
fs: { readTextFile: false, writeTextFile: false },
|
|
8224
|
-
terminal: false
|
|
8225
|
-
}
|
|
8438
|
+
clientCapabilities: acpClientCapabilities(parameterizedModelPicker)
|
|
8226
8439
|
},
|
|
8227
8440
|
resultSchema: acpInitializeResultSchema
|
|
8228
8441
|
});
|
|
@@ -8260,7 +8473,8 @@ async function loadSessionDiscoveredModels(agent) {
|
|
|
8260
8473
|
const reasoningByModel = await discoverAcpNativeReasoningByModel({
|
|
8261
8474
|
connection,
|
|
8262
8475
|
sessionId: newSession.sessionId,
|
|
8263
|
-
modelOption
|
|
8476
|
+
modelOption,
|
|
8477
|
+
reasoningProbePriorityModelIds
|
|
8264
8478
|
});
|
|
8265
8479
|
const models = reasoningByModel === null ? configOptionModels : buildModelCatalogFromConfigOptions(modelOption, reasoningByModel);
|
|
8266
8480
|
cachedSessionDiscoveredModels = {
|
|
@@ -8288,6 +8502,23 @@ async function discoverAcpNativeReasoningByModel(args) {
|
|
|
8288
8502
|
return null;
|
|
8289
8503
|
}
|
|
8290
8504
|
const modelOption = args.modelOption;
|
|
8505
|
+
const modelByValue = new Map(
|
|
8506
|
+
modelOptions.map((model) => [model.value, model])
|
|
8507
|
+
);
|
|
8508
|
+
const modelsToProbe = [];
|
|
8509
|
+
const addedModels = /* @__PURE__ */ new Set();
|
|
8510
|
+
for (const value of args.reasoningProbePriorityModelIds) {
|
|
8511
|
+
const model = modelByValue.get(value);
|
|
8512
|
+
if (model && !addedModels.has(model.value)) {
|
|
8513
|
+
modelsToProbe.push(model);
|
|
8514
|
+
addedModels.add(model.value);
|
|
8515
|
+
}
|
|
8516
|
+
}
|
|
8517
|
+
for (const model of modelOptions) {
|
|
8518
|
+
if (!addedModels.has(model.value)) {
|
|
8519
|
+
modelsToProbe.push(model);
|
|
8520
|
+
}
|
|
8521
|
+
}
|
|
8291
8522
|
const supportByModel = /* @__PURE__ */ new Map();
|
|
8292
8523
|
let timeout;
|
|
8293
8524
|
const timeoutReached = new Promise((resolve4) => {
|
|
@@ -8299,7 +8530,7 @@ async function discoverAcpNativeReasoningByModel(args) {
|
|
|
8299
8530
|
try {
|
|
8300
8531
|
return await Promise.race([
|
|
8301
8532
|
(async () => {
|
|
8302
|
-
for (const model of
|
|
8533
|
+
for (const model of modelsToProbe) {
|
|
8303
8534
|
const configState = await args.connection.request({
|
|
8304
8535
|
method: "session/set_config_option",
|
|
8305
8536
|
params: {
|
|
@@ -8459,6 +8690,12 @@ async function selectAcpNativeModel(args) {
|
|
|
8459
8690
|
modelSelection: selection,
|
|
8460
8691
|
nativeReasoning: args.nativeReasoning
|
|
8461
8692
|
});
|
|
8693
|
+
await selectAcpNativeServiceTier({
|
|
8694
|
+
connection: args.connection,
|
|
8695
|
+
sessionId: args.sessionId,
|
|
8696
|
+
configOptions,
|
|
8697
|
+
modelSelection: selection
|
|
8698
|
+
});
|
|
8462
8699
|
}
|
|
8463
8700
|
async function selectAcpNativeReasoning(args) {
|
|
8464
8701
|
const reasoningLevel = args.modelSelection.reasoningLevel;
|
|
@@ -8489,6 +8726,28 @@ async function selectAcpNativeReasoning(args) {
|
|
|
8489
8726
|
} catch {
|
|
8490
8727
|
}
|
|
8491
8728
|
}
|
|
8729
|
+
async function selectAcpNativeServiceTier(args) {
|
|
8730
|
+
const serviceTier = args.modelSelection.serviceTier;
|
|
8731
|
+
if (serviceTier === void 0) {
|
|
8732
|
+
return;
|
|
8733
|
+
}
|
|
8734
|
+
const fastOption = (args.configOptions ?? []).find(
|
|
8735
|
+
(option) => option.id === "fast" && option.type === "select"
|
|
8736
|
+
);
|
|
8737
|
+
const value = serviceTier === "fast" ? "true" : "false";
|
|
8738
|
+
if (!fastOption?.options?.some((option) => option.value === value)) {
|
|
8739
|
+
return;
|
|
8740
|
+
}
|
|
8741
|
+
await args.connection.request({
|
|
8742
|
+
method: "session/set_config_option",
|
|
8743
|
+
params: {
|
|
8744
|
+
sessionId: args.sessionId,
|
|
8745
|
+
configId: fastOption.id,
|
|
8746
|
+
value
|
|
8747
|
+
},
|
|
8748
|
+
resultSchema: acpConfigStateResultSchema
|
|
8749
|
+
});
|
|
8750
|
+
}
|
|
8492
8751
|
function buildPromptContentBlocks(session, input) {
|
|
8493
8752
|
const blocks = [];
|
|
8494
8753
|
const instructions = session.pendingInstructions;
|
|
@@ -8854,10 +9113,10 @@ async function startAgentSession(request) {
|
|
|
8854
9113
|
params: {
|
|
8855
9114
|
protocolVersion: ACP_PROTOCOL_VERSION,
|
|
8856
9115
|
clientInfo: { name: "bb", version: "1.0.0" },
|
|
8857
|
-
clientCapabilities:
|
|
8858
|
-
|
|
8859
|
-
|
|
8860
|
-
|
|
9116
|
+
clientCapabilities: acpClientCapabilities(
|
|
9117
|
+
params.parameterizedModelPicker,
|
|
9118
|
+
true
|
|
9119
|
+
)
|
|
8861
9120
|
},
|
|
8862
9121
|
resultSchema: acpInitializeResultSchema
|
|
8863
9122
|
});
|
|
@@ -9327,15 +9586,22 @@ async function handleModelList(id, params) {
|
|
|
9327
9586
|
);
|
|
9328
9587
|
return;
|
|
9329
9588
|
}
|
|
9330
|
-
const sessionDiscoveredModels = params.listCommand === void 0 && params.agent ? await loadSessionDiscoveredModels(
|
|
9589
|
+
const sessionDiscoveredModels = params.listCommand === void 0 && params.agent ? await loadSessionDiscoveredModels(
|
|
9590
|
+
params.agent,
|
|
9591
|
+
params.reasoningProbePriorityModelIds,
|
|
9592
|
+
params.parameterizedModelPicker
|
|
9593
|
+
) : null;
|
|
9331
9594
|
if (sessionDiscoveredModels) {
|
|
9332
|
-
sendResult(
|
|
9333
|
-
|
|
9334
|
-
|
|
9335
|
-
|
|
9336
|
-
|
|
9337
|
-
|
|
9338
|
-
|
|
9595
|
+
sendResult(
|
|
9596
|
+
id,
|
|
9597
|
+
splitPrimaryModels(
|
|
9598
|
+
applyConfiguredReasoningToModels(sessionDiscoveredModels, {
|
|
9599
|
+
reasoningCli: params.reasoningCli,
|
|
9600
|
+
nativeReasoning: params.nativeReasoning
|
|
9601
|
+
}),
|
|
9602
|
+
params.primaryModels
|
|
9603
|
+
)
|
|
9604
|
+
);
|
|
9339
9605
|
return;
|
|
9340
9606
|
}
|
|
9341
9607
|
sendResult(id, {
|
|
@@ -9367,8 +9633,24 @@ var acpProviderOptionsSchema = z39.object({
|
|
|
9367
9633
|
* the provider, so a third-party registration of a known agent gets the
|
|
9368
9634
|
* same reporting fidelity a first-party one does.
|
|
9369
9635
|
*/
|
|
9370
|
-
acpDialect: z39.string().min(1).optional()
|
|
9636
|
+
acpDialect: z39.string().min(1).optional(),
|
|
9637
|
+
/** Enables an agent's separate model configuration options. */
|
|
9638
|
+
parameterizedModelPicker: z39.boolean().optional(),
|
|
9639
|
+
/** Bare model ids shown before the collapsed "More models" pool. */
|
|
9640
|
+
primaryModels: z39.array(z39.string().min(1)).optional(),
|
|
9641
|
+
/** Model ids to probe first during bounded native discovery. */
|
|
9642
|
+
reasoningProbePriorityModelIds: z39.array(z39.string().min(1)).optional()
|
|
9371
9643
|
}).passthrough();
|
|
9644
|
+
function decodeAcpModelPickerOptions(providerOptions) {
|
|
9645
|
+
const parsed = acpProviderOptionsSchema.parse(providerOptions ?? {});
|
|
9646
|
+
return {
|
|
9647
|
+
parameterizedModelPicker: parsed.parameterizedModelPicker === true,
|
|
9648
|
+
...parsed.primaryModels === void 0 ? {} : { primaryModels: [...parsed.primaryModels] },
|
|
9649
|
+
reasoningProbePriorityModelIds: [
|
|
9650
|
+
...parsed.reasoningProbePriorityModelIds ?? []
|
|
9651
|
+
]
|
|
9652
|
+
};
|
|
9653
|
+
}
|
|
9372
9654
|
function decodeAdditionalWorkspaceWriteRoots(providerOptions) {
|
|
9373
9655
|
return acpProviderOptionsSchema.parse(providerOptions ?? {}).additionalWorkspaceWriteRoots ?? [];
|
|
9374
9656
|
}
|
|
@@ -9410,14 +9692,19 @@ async function handleRequest2(request) {
|
|
|
9410
9692
|
};
|
|
9411
9693
|
sendResult(request.id, result);
|
|
9412
9694
|
return;
|
|
9413
|
-
case "model/list":
|
|
9695
|
+
case "model/list": {
|
|
9696
|
+
const modelPicker = decodeAcpModelPickerOptions(
|
|
9697
|
+
request.params.providerOptions
|
|
9698
|
+
);
|
|
9414
9699
|
await handleModelList(
|
|
9415
9700
|
request.id,
|
|
9416
9701
|
buildAcpModelListParams(
|
|
9417
|
-
decodeLaunchSpec(request.params.providerOptions)
|
|
9702
|
+
decodeLaunchSpec(request.params.providerOptions),
|
|
9703
|
+
modelPicker
|
|
9418
9704
|
)
|
|
9419
9705
|
);
|
|
9420
9706
|
return;
|
|
9707
|
+
}
|
|
9421
9708
|
case "provider/health": {
|
|
9422
9709
|
const launchSpec = decodeLaunchSpec(request.params.providerOptions);
|
|
9423
9710
|
sendResult(
|
|
@@ -9496,6 +9783,9 @@ async function handleRequest2(request) {
|
|
|
9496
9783
|
);
|
|
9497
9784
|
return;
|
|
9498
9785
|
}
|
|
9786
|
+
const modelPicker = decodeAcpModelPickerOptions(
|
|
9787
|
+
params.options.providerOptions
|
|
9788
|
+
);
|
|
9499
9789
|
const sessionParams = buildAcpSessionParams({
|
|
9500
9790
|
additionalWorkspaceWriteRoots: decodeAdditionalWorkspaceWriteRoots(
|
|
9501
9791
|
params.options.providerOptions
|
|
@@ -9507,6 +9797,7 @@ async function handleRequest2(request) {
|
|
|
9507
9797
|
...params.options,
|
|
9508
9798
|
skillRoots: configuredSkillRoots ?? void 0
|
|
9509
9799
|
},
|
|
9800
|
+
parameterizedModelPicker: modelPicker.parameterizedModelPicker,
|
|
9510
9801
|
launchSpec,
|
|
9511
9802
|
providerLabel: launchSpec.displayName,
|
|
9512
9803
|
threadId: params.threadId
|
|
@@ -2246,7 +2246,7 @@ var deltaItemShapeSchema = z14.discriminatedUnion("type", [
|
|
|
2246
2246
|
}),
|
|
2247
2247
|
z14.object({
|
|
2248
2248
|
type: z14.literal("fileChange"),
|
|
2249
|
-
/** Empty
|
|
2249
|
+
/** Empty while a path is not yet known, including bare close fallbacks. */
|
|
2250
2250
|
changes: z14.array(deltaFileChangeSchema)
|
|
2251
2251
|
}),
|
|
2252
2252
|
/**
|
package/dist/provider-bridge.js
CHANGED
|
@@ -4693,7 +4693,7 @@ var deltaItemShapeSchema = z30.discriminatedUnion("type", [
|
|
|
4693
4693
|
}),
|
|
4694
4694
|
z30.object({
|
|
4695
4695
|
type: z30.literal("fileChange"),
|
|
4696
|
-
/** Empty
|
|
4696
|
+
/** Empty while a path is not yet known, including bare close fallbacks. */
|
|
4697
4697
|
changes: z30.array(deltaFileChangeSchema)
|
|
4698
4698
|
}),
|
|
4699
4699
|
/**
|
package/dist/testing/index.js
CHANGED
|
@@ -37,16 +37,23 @@ function parseNamespacedGlyph(glyph) {
|
|
|
37
37
|
// ../domain/src/plugin-cli.ts
|
|
38
38
|
var RESERVED_BB_CLI_COMMANDS = [
|
|
39
39
|
"environment",
|
|
40
|
+
"file",
|
|
40
41
|
"guide",
|
|
41
42
|
"help",
|
|
43
|
+
"machine",
|
|
42
44
|
"manager",
|
|
45
|
+
"marketplace",
|
|
43
46
|
"plugin",
|
|
44
47
|
"project",
|
|
45
48
|
"provider",
|
|
49
|
+
"settings",
|
|
46
50
|
"skill",
|
|
47
51
|
"status",
|
|
52
|
+
"terminal",
|
|
48
53
|
"theme",
|
|
49
|
-
"thread"
|
|
54
|
+
"thread",
|
|
55
|
+
"updates",
|
|
56
|
+
"voice"
|
|
50
57
|
];
|
|
51
58
|
|
|
52
59
|
// ../domain/src/provider-fork.ts
|
|
@@ -265,6 +272,10 @@ var providerNativeRootSetSchema = z2.object({
|
|
|
265
272
|
var PLUGIN_CLI_OUTPUT_MAX_BYTES = 1024 * 1024;
|
|
266
273
|
|
|
267
274
|
// src/internal/host-policy.ts
|
|
275
|
+
function pluginCliCollisionWarning(pluginId, commandName) {
|
|
276
|
+
if (!RESERVED_BB_CLI_COMMANDS.includes(commandName)) return null;
|
|
277
|
+
return `CLI command "${commandName}" collides with core command "bb ${commandName}"; core keeps the short form. Use "bb plugin run ${pluginId}" to invoke this plugin.`;
|
|
278
|
+
}
|
|
268
279
|
var RESERVED_AGENT_TOOL_NAMES = [
|
|
269
280
|
"update_environment_directory"
|
|
270
281
|
];
|
|
@@ -2265,11 +2276,6 @@ function createFakePluginHostInternal(options, sharedState) {
|
|
|
2265
2276
|
`invalid cli command name ${JSON.stringify(name)} \u2014 use lowercase letters, digits, and "-"`
|
|
2266
2277
|
);
|
|
2267
2278
|
}
|
|
2268
|
-
if (RESERVED_BB_CLI_COMMANDS.includes(name)) {
|
|
2269
|
-
throw new Error(
|
|
2270
|
-
`cli command name "${name}" is reserved by the bb CLI \u2014 pick another name`
|
|
2271
|
-
);
|
|
2272
|
-
}
|
|
2273
2279
|
if (typeof registration.summary !== "string" || registration.summary.trim().length === 0) {
|
|
2274
2280
|
throw new Error(`cli command "${name}" must provide a summary`);
|
|
2275
2281
|
}
|
|
@@ -2300,6 +2306,8 @@ function createFakePluginHostInternal(options, sharedState) {
|
|
|
2300
2306
|
commands: validatedCommands,
|
|
2301
2307
|
run: registration.run.bind(registration)
|
|
2302
2308
|
};
|
|
2309
|
+
const warning = pluginCliCollisionWarning(pluginId, name);
|
|
2310
|
+
if (warning) emitLog("warn", warning);
|
|
2303
2311
|
}
|
|
2304
2312
|
};
|
|
2305
2313
|
const agentTools = [];
|