@getpaseo/server 0.1.97 → 0.1.99

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.
Files changed (101) hide show
  1. package/dist/server/server/agent/agent-manager.d.ts +11 -3
  2. package/dist/server/server/agent/agent-manager.js +96 -24
  3. package/dist/server/server/agent/agent-prompt.d.ts +1 -1
  4. package/dist/server/server/agent/agent-prompt.js +3 -10
  5. package/dist/server/server/agent/agent-sdk-types.d.ts +20 -9
  6. package/dist/server/server/agent/create-agent/create.d.ts +2 -0
  7. package/dist/server/server/agent/create-agent/create.js +8 -7
  8. package/dist/server/server/agent/lifecycle-command.d.ts +15 -1
  9. package/dist/server/server/agent/lifecycle-command.js +9 -2
  10. package/dist/server/server/agent/mcp-server.js +254 -115
  11. package/dist/server/server/agent/provider-notices.d.ts +3 -0
  12. package/dist/server/server/agent/provider-notices.js +5 -0
  13. package/dist/server/server/agent/provider-registry.d.ts +8 -3
  14. package/dist/server/server/agent/provider-registry.js +58 -25
  15. package/dist/server/server/agent/provider-snapshot-manager.d.ts +3 -0
  16. package/dist/server/server/agent/provider-snapshot-manager.js +37 -16
  17. package/dist/server/server/agent/providers/acp-agent.d.ts +5 -3
  18. package/dist/server/server/agent/providers/acp-agent.js +32 -19
  19. package/dist/server/server/agent/providers/claude/agent.d.ts +2 -2
  20. package/dist/server/server/agent/providers/claude/agent.js +261 -167
  21. package/dist/server/server/agent/providers/claude/models.js +7 -3
  22. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +6 -4
  23. package/dist/server/server/agent/providers/codex-app-server-agent.js +48 -25
  24. package/dist/server/server/agent/providers/copilot-acp-agent.js +4 -31
  25. package/dist/server/server/agent/providers/diagnostic-utils.d.ts +9 -0
  26. package/dist/server/server/agent/providers/diagnostic-utils.js +188 -0
  27. package/dist/server/server/agent/providers/generic-acp-agent.d.ts +0 -1
  28. package/dist/server/server/agent/providers/generic-acp-agent.js +2 -108
  29. package/dist/server/server/agent/providers/mock-load-test-agent.d.ts +2 -3
  30. package/dist/server/server/agent/providers/mock-load-test-agent.js +5 -5
  31. package/dist/server/server/agent/providers/mock-slow-provider.d.ts +2 -3
  32. package/dist/server/server/agent/providers/mock-slow-provider.js +3 -6
  33. package/dist/server/server/agent/providers/opencode/server-manager.d.ts +29 -2
  34. package/dist/server/server/agent/providers/opencode/server-manager.js +83 -17
  35. package/dist/server/server/agent/providers/opencode-agent.d.ts +6 -3
  36. package/dist/server/server/agent/providers/opencode-agent.js +61 -107
  37. package/dist/server/server/agent/providers/pi/agent.d.ts +2 -3
  38. package/dist/server/server/agent/providers/pi/agent.js +11 -63
  39. package/dist/server/server/agent/providers/pi/cli-runtime.js +2 -2
  40. package/dist/server/server/agent/providers/pi/runtime.d.ts +1 -1
  41. package/dist/server/server/agent/providers/pi/test-utils/fake-pi.d.ts +1 -1
  42. package/dist/server/server/agent/providers/pi/test-utils/fake-pi.js +1 -1
  43. package/dist/server/server/bootstrap.d.ts +2 -0
  44. package/dist/server/server/bootstrap.js +32 -2
  45. package/dist/server/server/managed-processes/managed-processes.d.ts +76 -0
  46. package/dist/server/server/managed-processes/managed-processes.js +326 -0
  47. package/dist/server/server/resolve-worktree-creation-intent.d.ts +3 -0
  48. package/dist/server/server/resolve-worktree-creation-intent.js +3 -3
  49. package/dist/server/server/session/agent-config/agent-config-session.d.ts +50 -0
  50. package/dist/server/server/session/agent-config/agent-config-session.js +98 -0
  51. package/dist/server/server/session/chat/chat-schedule-loop-session.d.ts +120 -0
  52. package/dist/server/server/session/chat/chat-schedule-loop-session.js +489 -0
  53. package/dist/server/server/session/checkout/checkout-session.d.ts +142 -0
  54. package/dist/server/server/session/checkout/checkout-session.js +925 -0
  55. package/dist/server/server/session/daemon/daemon-session.d.ts +50 -0
  56. package/dist/server/server/session/daemon/daemon-session.js +98 -0
  57. package/dist/server/server/session/files/workspace-files-session.d.ts +43 -0
  58. package/dist/server/server/session/files/workspace-files-session.js +218 -0
  59. package/dist/server/server/session/project-config/project-config-session.d.ts +34 -0
  60. package/dist/server/server/session/project-config/project-config-session.js +125 -0
  61. package/dist/server/server/session/provider/provider-catalog-session.d.ts +74 -0
  62. package/dist/server/server/session/provider/provider-catalog-session.js +339 -0
  63. package/dist/server/server/session/voice/voice-session.d.ts +166 -0
  64. package/dist/server/server/session/voice/voice-session.js +893 -0
  65. package/dist/server/server/{voice → session/voice}/voice-turn-controller.d.ts +2 -2
  66. package/dist/server/server/{voice → session/voice}/voice-turn-controller.js +2 -2
  67. package/dist/server/server/session.d.ts +23 -207
  68. package/dist/server/server/session.js +2319 -5102
  69. package/dist/server/server/speech/providers/openai/runtime.js +3 -4
  70. package/dist/server/server/websocket-server.d.ts +1 -0
  71. package/dist/server/server/websocket-server.js +11 -0
  72. package/dist/server/server/workspace-archive-service.js +2 -3
  73. package/dist/server/server/workspace-directory.js +5 -5
  74. package/dist/server/server/workspace-reconciliation-service.js +2 -2
  75. package/dist/server/server/worktree-core.d.ts +1 -0
  76. package/dist/server/server/worktree-core.js +5 -1
  77. package/dist/server/services/quota-fetcher/manifest.d.ts +4 -0
  78. package/dist/server/services/quota-fetcher/manifest.js +47 -0
  79. package/dist/server/services/quota-fetcher/provider.d.ts +17 -0
  80. package/dist/server/services/quota-fetcher/provider.js +2 -0
  81. package/dist/server/services/quota-fetcher/providers/claude.d.ts +26 -0
  82. package/dist/server/services/quota-fetcher/providers/claude.js +217 -0
  83. package/dist/server/services/quota-fetcher/providers/codex.d.ts +23 -0
  84. package/dist/server/services/quota-fetcher/providers/codex.js +211 -0
  85. package/dist/server/services/quota-fetcher/providers/copilot.d.ts +17 -0
  86. package/dist/server/services/quota-fetcher/providers/copilot.js +75 -0
  87. package/dist/server/services/quota-fetcher/providers/cursor.d.ts +17 -0
  88. package/dist/server/services/quota-fetcher/providers/cursor.js +123 -0
  89. package/dist/server/services/quota-fetcher/providers/grok.d.ts +18 -0
  90. package/dist/server/services/quota-fetcher/providers/grok.js +89 -0
  91. package/dist/server/services/quota-fetcher/providers/kimi.d.ts +20 -0
  92. package/dist/server/services/quota-fetcher/providers/kimi.js +89 -0
  93. package/dist/server/services/quota-fetcher/providers/zai.d.ts +17 -0
  94. package/dist/server/services/quota-fetcher/providers/zai.js +58 -0
  95. package/dist/server/services/quota-fetcher/service.d.ts +28 -0
  96. package/dist/server/services/quota-fetcher/service.js +58 -0
  97. package/dist/server/services/quota-fetcher/usage.d.ts +22 -0
  98. package/dist/server/services/quota-fetcher/usage.js +49 -0
  99. package/dist/server/utils/checkout-git.d.ts +6 -0
  100. package/dist/server/utils/directory-suggestions.js +98 -2
  101. package/package.json +5 -5
@@ -32,7 +32,9 @@ const PROVIDER_CLIENT_FACTORIES = {
32
32
  command: getCursorACPCommand(runtimeSettings),
33
33
  env: runtimeSettings?.env,
34
34
  }),
35
- opencode: (logger, runtimeSettings) => new OpenCodeAgentClient(logger, runtimeSettings),
35
+ opencode: (logger, runtimeSettings, options) => new OpenCodeAgentClient(logger, runtimeSettings, {
36
+ managedProcesses: options?.managedProcesses,
37
+ }),
36
38
  pi: (logger, runtimeSettings, options) => new PiRpcAgentClient({
37
39
  logger,
38
40
  runtimeSettings,
@@ -230,10 +232,15 @@ function wrapClientProvider(provider, inner, profileModels, additionalModels, pr
230
232
  provider: inner.provider,
231
233
  }
232
234
  : undefined, launchContext)),
233
- listModels: async (options) => mergeModels(provider, profileModels, additionalModels, await inner.listModels(options), {
234
- profileModelsAreAdditive,
235
- }),
236
- listModes: inner.listModes?.bind(inner),
235
+ fetchCatalog: async (options) => {
236
+ const catalog = await inner.fetchCatalog(options);
237
+ return {
238
+ models: mergeModels(provider, profileModels, additionalModels, catalog.models, {
239
+ profileModelsAreAdditive,
240
+ }),
241
+ modes: catalog.modes,
242
+ };
243
+ },
237
244
  resolveCreateConfig: inner.resolveCreateConfig?.bind(inner),
238
245
  isCreateConfigUnattended: inner.isCreateConfigUnattended?.bind(inner),
239
246
  listImportableSessions: listImportableSessions
@@ -273,6 +280,22 @@ function wrapClientProvider(provider, inner, profileModels, additionalModels, pr
273
280
  }
274
281
  function createRegistryEntry(logger, provider, resolved) {
275
282
  const modelClient = resolved.createBaseClient(logger);
283
+ const hasReplacementModels = resolved.profileModels.length > 0 && !resolved.profileModelsAreAdditive;
284
+ const replacementModels = hasReplacementModels
285
+ ? resolved.profileModels.map((model) => mapModel(provider, model))
286
+ : [];
287
+ const decorateModes = (modes) => modes.map((mode) => {
288
+ if (mode.icon && mode.colorTier)
289
+ return mode;
290
+ const definitionMode = resolved.definition.modes.find((d) => d.id === mode.id);
291
+ if (!definitionMode)
292
+ return mode;
293
+ return Object.assign({}, mode, {
294
+ icon: mode.icon ?? definitionMode.icon,
295
+ colorTier: mode.colorTier ?? definitionMode.colorTier,
296
+ });
297
+ });
298
+ const hasStaticModes = resolved.definition.modes.length > 0;
276
299
  return {
277
300
  ...resolved.definition,
278
301
  enabled: resolved.enabled,
@@ -280,24 +303,29 @@ function createRegistryEntry(logger, provider, resolved) {
280
303
  createClient: (providerLogger) => createResolvedProviderClient(providerLogger, provider, resolved),
281
304
  resolveCreateConfig: modelClient.resolveCreateConfig ?? resolveDefaultAgentCreateConfig,
282
305
  isCreateConfigUnattended: modelClient.isCreateConfigUnattended ?? isDefaultAgentCreateConfigUnattended,
283
- fetchModels: async (options) => mergeModels(provider, resolved.profileModels, resolved.additionalModels, await modelClient.listModels(options), {
284
- profileModelsAreAdditive: resolved.profileModelsAreAdditive,
285
- }),
286
- fetchModes: async (options) => {
287
- const modes = modelClient.listModes
288
- ? await modelClient.listModes(options)
289
- : resolved.definition.modes;
290
- return modes.map((mode) => {
291
- if (mode.icon && mode.colorTier)
292
- return mode;
293
- const definitionMode = resolved.definition.modes.find((d) => d.id === mode.id);
294
- if (!definitionMode)
295
- return mode;
296
- return Object.assign({}, mode, {
297
- icon: mode.icon ?? definitionMode.icon,
298
- colorTier: mode.colorTier ?? definitionMode.colorTier,
299
- });
300
- });
306
+ fetchCatalog: async (options, client) => {
307
+ const catalogClient = client ?? modelClient;
308
+ if (hasReplacementModels) {
309
+ // Replacement models skip runtime model discovery, but additionalModels
310
+ // must still be merged on top. If modes are dynamic, probe for modes via
311
+ // the single catalog API; otherwise use static/empty modes with no runtime.
312
+ const models = mergeModelAdditions(provider, replacementModels, resolved.additionalModels);
313
+ if (hasStaticModes) {
314
+ return {
315
+ models,
316
+ modes: decorateModes(resolved.definition.modes),
317
+ };
318
+ }
319
+ const catalog = await catalogClient.fetchCatalog(options);
320
+ return { models, modes: decorateModes(catalog.modes) };
321
+ }
322
+ const catalog = await catalogClient.fetchCatalog(options);
323
+ return {
324
+ models: mergeModels(provider, resolved.profileModels, resolved.additionalModels, catalog.models, {
325
+ profileModelsAreAdditive: resolved.profileModelsAreAdditive,
326
+ }),
327
+ modes: decorateModes(catalog.modes),
328
+ };
301
329
  },
302
330
  };
303
331
  }
@@ -329,13 +357,14 @@ function buildResolvedBuiltinProviders(providerOverrides, runtimeSettings, optio
329
357
  providerParams: override?.params,
330
358
  createBaseClient: (logger) => factory(logger, mergedRuntimeSettings, {
331
359
  workspaceGitService: options.workspaceGitService,
360
+ managedProcesses: options.managedProcesses,
332
361
  providerParams: override?.params,
333
362
  }),
334
363
  });
335
364
  }
336
365
  return resolvedProviders;
337
366
  }
338
- function addDerivedProviders(resolvedProviders, providerOverrides) {
367
+ function addDerivedProviders(resolvedProviders, providerOverrides, options) {
339
368
  for (const [providerId, override] of Object.entries(providerOverrides)) {
340
369
  if (resolvedProviders.has(providerId) || BUILTIN_PROVIDER_IDS.includes(providerId)) {
341
370
  continue;
@@ -403,6 +432,7 @@ function addDerivedProviders(resolvedProviders, providerOverrides) {
403
432
  derivedFromProviderId: baseProviderId,
404
433
  providerParams,
405
434
  createBaseClient: (logger) => baseFactory(logger, mergedRuntimeSettings, {
435
+ managedProcesses: options.managedProcesses,
406
436
  providerParams,
407
437
  customProvider: {
408
438
  id: providerId,
@@ -418,8 +448,11 @@ export function buildProviderRegistry(logger, options) {
418
448
  const providerOverrides = options?.providerOverrides ?? {};
419
449
  const resolvedProviders = buildResolvedBuiltinProviders(providerOverrides, runtimeSettings, {
420
450
  workspaceGitService: options?.workspaceGitService,
451
+ managedProcesses: options?.managedProcesses,
421
452
  }, options?.isDev === true);
422
- addDerivedProviders(resolvedProviders, providerOverrides);
453
+ addDerivedProviders(resolvedProviders, providerOverrides, {
454
+ managedProcesses: options?.managedProcesses,
455
+ });
423
456
  return Object.fromEntries([...resolvedProviders.entries()].map(([provider, resolved]) => [
424
457
  provider,
425
458
  createRegistryEntry(logger, provider, resolved),
@@ -2,6 +2,7 @@ import type { Logger } from "pino";
2
2
  import type { AgentClient, AgentMode, AgentModelDefinition, AgentProvider, ProviderSnapshotEntry } from "./agent-sdk-types.js";
3
3
  import type { ManagedAgent } from "./agent-manager.js";
4
4
  import type { WorkspaceGitService } from "../workspace-git-service.js";
5
+ import type { ManagedProcessRegistry } from "../managed-processes/managed-processes.js";
5
6
  import type { AgentProviderRuntimeSettingsMap, ProviderOverride } from "./provider-launch-config.js";
6
7
  import type { MutableDaemonConfig } from "../daemon-config-store.js";
7
8
  type ProviderSnapshotChangeListener = (entries: ProviderSnapshotEntry[], cwd: string) => void;
@@ -10,6 +11,7 @@ export interface ProviderSnapshotManagerOptions {
10
11
  runtimeSettings?: AgentProviderRuntimeSettingsMap;
11
12
  providerOverrides?: Record<string, ProviderOverride>;
12
13
  workspaceGitService?: Pick<WorkspaceGitService, "resolveRepoRoot">;
14
+ managedProcesses?: ManagedProcessRegistry;
13
15
  isDev?: boolean;
14
16
  extraClients?: Partial<Record<AgentProvider, AgentClient>>;
15
17
  refreshTimeoutMs?: number;
@@ -64,6 +66,7 @@ export declare class ProviderSnapshotManager {
64
66
  private readonly refreshTimeoutMs;
65
67
  private readonly logger;
66
68
  private readonly workspaceGitService?;
69
+ private readonly managedProcesses?;
67
70
  private readonly isDev;
68
71
  private readonly extraClients;
69
72
  private runtimeSettings;
@@ -5,6 +5,7 @@ import { expandTilde } from "../../utils/path.js";
5
5
  import { withTimeout } from "../../utils/promise-timeout.js";
6
6
  import { buildProviderRegistry, shutdownAgentClients, } from "./provider-registry.js";
7
7
  import { applyMutableProviderConfigToOverrides } from "../daemon-config-store.js";
8
+ import { formatProviderDiagnostic } from "./providers/diagnostic-utils.js";
8
9
  const DEFAULT_REFRESH_TIMEOUT_MS = 30000;
9
10
  const REFRESH_TIMEOUT_ENV_VAR = "PASEO_PROVIDER_REFRESH_TIMEOUT_MS";
10
11
  // Provider refresh probes can be slow on cold starts (e.g. Copilot's first
@@ -32,6 +33,7 @@ export class ProviderSnapshotManager {
32
33
  this.destroyed = false;
33
34
  this.logger = options.logger;
34
35
  this.workspaceGitService = options.workspaceGitService;
36
+ this.managedProcesses = options.managedProcesses;
35
37
  this.isDev = options.isDev === true;
36
38
  this.extraClients = options.extraClients ?? {};
37
39
  this.runtimeSettings = options.runtimeSettings;
@@ -178,13 +180,19 @@ export class ProviderSnapshotManager {
178
180
  });
179
181
  }
180
182
  async getProviderDiagnostic(provider) {
181
- const client = this.providerClients[provider];
182
- if (!client) {
183
- throw new Error(`Provider ${provider} is not configured`);
184
- }
185
- const diagnostic = client.getDiagnostic
183
+ const definition = this.requireProvider(provider);
184
+ const client = this.ensureClient(provider, definition);
185
+ // Force-refresh the snapshot so Models/Status come from the single catalog authority.
186
+ await this.refreshSnapshotForCwd({ cwd: homedir(), providers: [provider] });
187
+ const entry = await this.getProvider({ cwd: homedir(), provider, wait: true });
188
+ const modelCount = entry.status === "ready" ? String(entry.models?.length ?? 0) : "—";
189
+ const status = formatProviderStatus(entry);
190
+ const baseDiagnostic = client.getDiagnostic
186
191
  ? (await client.getDiagnostic()).diagnostic
187
- : "No diagnostic available for this provider.";
192
+ : formatProviderDiagnostic(definition.label ?? provider, [
193
+ { label: "Diagnostic", value: "No diagnostic available" },
194
+ ]);
195
+ const diagnostic = `${baseDiagnostic}\n Models: ${modelCount}\n Status: ${status}`;
188
196
  return { provider, diagnostic };
189
197
  }
190
198
  applyMutableProviderConfig(mutableProviders) {
@@ -225,6 +233,7 @@ export class ProviderSnapshotManager {
225
233
  runtimeSettings: this.runtimeSettings,
226
234
  providerOverrides: this.providerOverrides,
227
235
  workspaceGitService: this.workspaceGitService,
236
+ managedProcesses: this.managedProcesses,
228
237
  isDev: this.isDev,
229
238
  });
230
239
  for (const [provider, client] of Object.entries(this.extraClients)) {
@@ -236,8 +245,7 @@ export class ProviderSnapshotManager {
236
245
  createClient: () => client,
237
246
  resolveCreateConfig: client.resolveCreateConfig?.bind(client) ?? definition.resolveCreateConfig,
238
247
  isCreateConfigUnattended: client.isCreateConfigUnattended?.bind(client) ?? definition.isCreateConfigUnattended,
239
- fetchModels: client.listModels.bind(client),
240
- fetchModes: client.listModes?.bind(client) ?? definition.fetchModes,
248
+ fetchCatalog: client.fetchCatalog.bind(client),
241
249
  };
242
250
  }
243
251
  return registry;
@@ -446,16 +454,13 @@ export class ProviderSnapshotManager {
446
454
  setEntry({ ...base, status: "unavailable", enabled: true });
447
455
  return;
448
456
  }
449
- const [models, modes] = await withTimeout(Promise.all([
450
- definition.fetchModels({ cwd, force }),
451
- definition.fetchModes({ cwd, force }),
452
- ]), this.refreshTimeoutMs, `Timed out refreshing ${definition.label} after ${this.refreshTimeoutMs}ms`);
457
+ const catalog = await withTimeout(definition.fetchCatalog({ cwd, force }, client), this.refreshTimeoutMs, `Timed out refreshing ${definition.label} after ${this.refreshTimeoutMs}ms`);
453
458
  setEntry({
454
459
  ...base,
455
460
  status: "ready",
456
461
  enabled: true,
457
- models,
458
- modes,
462
+ models: catalog.models,
463
+ modes: catalog.modes,
459
464
  fetchedAt: new Date().toISOString(),
460
465
  });
461
466
  }
@@ -549,8 +554,15 @@ export function resolveSnapshotCwd(cwd) {
549
554
  if (!trimmed) {
550
555
  return homedir();
551
556
  }
552
- const expanded = trimmed === "~" || trimmed.startsWith("~/") ? `${homedir()}${trimmed.slice(1)}` : trimmed;
553
- return resolve(expanded);
557
+ let expanded = trimmed === "~" || trimmed.startsWith("~/") ? `${homedir()}${trimmed.slice(1)}` : trimmed;
558
+ if (process.platform === "win32" && /^[A-Za-z]:$/.test(expanded)) {
559
+ expanded = `${expanded}\\`;
560
+ }
561
+ let resolved = resolve(expanded);
562
+ if (process.platform === "win32" && /^[A-Za-z]:$/.test(resolved)) {
563
+ resolved = `${resolved}\\`;
564
+ }
565
+ return resolved;
554
566
  }
555
567
  function entriesToArray(entries) {
556
568
  return Array.from(entries.values(), cloneEntry);
@@ -571,4 +583,13 @@ function toErrorMessage(error) {
571
583
  }
572
584
  return "Unknown error";
573
585
  }
586
+ function formatProviderStatus(entry) {
587
+ if (entry.status === "ready")
588
+ return "Ready";
589
+ if (entry.status === "error")
590
+ return `Error: ${entry.error ?? "Unknown error"}`;
591
+ if (entry.status === "unavailable")
592
+ return "Unavailable";
593
+ return "Loading";
594
+ }
574
595
  //# sourceMappingURL=provider-snapshot-manager.js.map
@@ -3,7 +3,7 @@ import type { ProcessTerminator } from "../../../utils/tree-kill.js";
3
3
  import type { ReadableStream as NodeReadableStream, WritableStream as NodeWritableStream } from "node:stream/web";
4
4
  import { ClientSideConnection, type Client as ACPClient, type CreateTerminalRequest, type InitializeResponse, type KillTerminalRequest, type LoadSessionResponse, type NewSessionResponse, type ReadTextFileRequest, type RequestPermissionRequest, type RequestPermissionResponse, type ResumeSessionResponse, type SessionConfigOption, type SessionMode, type SessionModelState, type SessionNotification, type TerminalOutputRequest, type TerminalOutputResponse, type ToolCallContent, type ToolCallLocation, type ToolCallStatus, type ToolKind, type Usage, type WaitForTerminalExitRequest, type WriteTextFileRequest, type Stream as ACPStream } from "@agentclientprotocol/sdk";
5
5
  import type { Logger } from "pino";
6
- import { type AgentCapabilityFlags, type AgentClient, type AgentLaunchContext, type AgentMode, type AgentModelDefinition, type AgentPermissionRequest, type AgentPermissionResponse, type AgentPersistenceHandle, type AgentPromptInput, type AgentRunOptions, type AgentRunResult, type AgentRuntimeInfo, type AgentSession, type AgentSessionConfig, type AgentSlashCommand, type AgentStreamEvent, type AgentUsage, type ImportableProviderSession, type ImportProviderSessionContext, type ImportProviderSessionInput, type ListImportableSessionsOptions, type ListModesOptions, type ListModelsOptions } from "../agent-sdk-types.js";
6
+ import { type AgentCapabilityFlags, type AgentClient, type AgentLaunchContext, type AgentMode, type AgentModelDefinition, type AgentPermissionRequest, type AgentPermissionResponse, type AgentPersistenceHandle, type AgentPromptInput, type AgentRunOptions, type AgentRunResult, type AgentRuntimeInfo, type AgentSession, type AgentSessionConfig, type AgentSlashCommand, type AgentStreamEvent, type AgentUsage, type FetchCatalogOptions, type ImportableProviderSession, type ImportProviderSessionContext, type ImportProviderSessionInput, type ListImportableSessionsOptions, type ProviderCatalog } from "../agent-sdk-types.js";
7
7
  import { type ProviderRuntimeSettings } from "../provider-launch-config.js";
8
8
  export declare function summarizeACPRequestError(error: unknown): {
9
9
  message: string;
@@ -155,8 +155,7 @@ export declare class ACPAgentClient implements AgentClient {
155
155
  constructor(options: ACPAgentClientOptions);
156
156
  createSession(config: AgentSessionConfig, launchContext?: AgentLaunchContext): Promise<AgentSession>;
157
157
  resumeSession(handle: AgentPersistenceHandle, overrides?: Partial<AgentSessionConfig>, launchContext?: AgentLaunchContext): Promise<AgentSession>;
158
- listModels(options: ListModelsOptions): Promise<AgentModelDefinition[]>;
159
- listModes(options: ListModesOptions): Promise<AgentMode[]>;
158
+ fetchCatalog(options: FetchCatalogOptions): Promise<ProviderCatalog>;
160
159
  listImportableSessions(options?: ListImportableSessionsOptions): Promise<ImportableProviderSession[]>;
161
160
  importSession(input: ImportProviderSessionInput, context: ImportProviderSessionContext): Promise<import("../agent-sdk-types.js").ImportedProviderSession>;
162
161
  isAvailable(): Promise<boolean>;
@@ -194,6 +193,7 @@ export declare class ACPAgentSession implements AgentSession, ACPClient {
194
193
  private readonly pendingPermissions;
195
194
  private readonly messageAssemblies;
196
195
  private readonly submittedUserMessageIds;
196
+ private activeSubmittedUserMessage;
197
197
  private readonly toolCalls;
198
198
  private readonly terminalEntries;
199
199
  private readonly persistedHistory;
@@ -282,6 +282,7 @@ export declare class ACPAgentSession implements AgentSession, ACPClient {
282
282
  private translateSessionUpdate;
283
283
  private handleToolCallUpdate;
284
284
  private createMessageTimelineItem;
285
+ private messageAssemblyKey;
285
286
  private handleCurrentModeUpdate;
286
287
  private handleConfigOptionUpdate;
287
288
  private handleSessionInfoUpdate;
@@ -292,6 +293,7 @@ export declare class ACPAgentSession implements AgentSession, ACPClient {
292
293
  private emitSubmittedUserMessage;
293
294
  private runtimeInfo;
294
295
  private finishTurn;
296
+ private isSubmittedUserMessageEcho;
295
297
  private emitBootstrapThreadEvent;
296
298
  private synthesizeCanceledToolCalls;
297
299
  private collectDiagnostic;
@@ -344,7 +344,7 @@ export class ACPAgentClient {
344
344
  await session.initializeResumedSession();
345
345
  return session;
346
346
  }
347
- async listModels(options) {
347
+ async fetchCatalog(options) {
348
348
  const { cwd } = options;
349
349
  const probe = await this.spawnProcess(PROBE_ENV);
350
350
  try {
@@ -354,23 +354,11 @@ export class ACPAgentClient {
354
354
  }));
355
355
  const transformed = this.transformSessionResponse(response);
356
356
  const models = deriveModelDefinitionsFromACP(this.provider, transformed.models, transformed.configOptions);
357
- return this.modelTransformer ? this.modelTransformer(models) : models;
358
- }
359
- finally {
360
- await this.closeProbe(probe);
361
- }
362
- }
363
- async listModes(options) {
364
- const { cwd } = options;
365
- const probe = await this.spawnProcess(PROBE_ENV);
366
- try {
367
- const response = await this.runACPRequest(() => probe.connection.newSession({
368
- cwd,
369
- mcpServers: [],
370
- }));
371
- const transformed = this.transformSessionResponse(response);
372
357
  const modeInfo = deriveModesFromACP(this.defaultModes, transformed.modes, transformed.configOptions);
373
- return modeInfo.modes;
358
+ return {
359
+ models: this.modelTransformer ? this.modelTransformer(models) : models,
360
+ modes: modeInfo.modes,
361
+ };
374
362
  }
375
363
  finally {
376
364
  await this.closeProbe(probe);
@@ -561,6 +549,7 @@ export class ACPAgentSession {
561
549
  this.pendingPermissions = new Map();
562
550
  this.messageAssemblies = new Map();
563
551
  this.submittedUserMessageIds = new Set();
552
+ this.activeSubmittedUserMessage = null;
564
553
  this.toolCalls = new Map();
565
554
  this.terminalEntries = new Map();
566
555
  this.persistedHistory = [];
@@ -690,6 +679,7 @@ export class ACPAgentSession {
690
679
  const turnId = randomUUID();
691
680
  const messageId = options?.messageId ?? randomUUID();
692
681
  this.activeForegroundTurnId = turnId;
682
+ this.activeSubmittedUserMessage = null;
693
683
  this.emitBootstrapThreadEvent();
694
684
  this.pushEvent({ type: "turn_started", provider: this.provider, turnId });
695
685
  this.emitSubmittedUserMessage(prompt, messageId, turnId);
@@ -1413,7 +1403,10 @@ export class ACPAgentSession {
1413
1403
  if (!item) {
1414
1404
  return [];
1415
1405
  }
1416
- if (update.messageId && this.submittedUserMessageIds.has(update.messageId)) {
1406
+ if (item.type !== "user_message") {
1407
+ return [this.wrapTimeline(item)];
1408
+ }
1409
+ if (this.isSubmittedUserMessageEcho(item)) {
1417
1410
  return [];
1418
1411
  }
1419
1412
  return [this.wrapTimeline(item)];
@@ -1476,7 +1469,7 @@ export class ACPAgentSession {
1476
1469
  if (!chunkText) {
1477
1470
  return null;
1478
1471
  }
1479
- const key = `${type}:${update.messageId ?? "default"}`;
1472
+ const key = this.messageAssemblyKey(type, update.messageId);
1480
1473
  const state = this.messageAssemblies.get(key) ?? { text: "" };
1481
1474
  state.text += chunkText;
1482
1475
  this.messageAssemblies.set(key, state);
@@ -1488,6 +1481,10 @@ export class ACPAgentSession {
1488
1481
  }
1489
1482
  return { type: "reasoning", text: chunkText };
1490
1483
  }
1484
+ messageAssemblyKey(type, messageId) {
1485
+ const fallbackId = type === "user_message" ? (this.activeForegroundTurnId ?? "default") : "default";
1486
+ return `${type}:${messageId ?? fallbackId}`;
1487
+ }
1491
1488
  handleCurrentModeUpdate(update) {
1492
1489
  this.currentMode = this.transformModeId(update.currentModeId);
1493
1490
  }
@@ -1589,6 +1586,7 @@ export class ACPAgentSession {
1589
1586
  return;
1590
1587
  }
1591
1588
  this.submittedUserMessageIds.add(messageId);
1589
+ this.activeSubmittedUserMessage = { messageId, text, turnId };
1592
1590
  this.pushEvent({
1593
1591
  type: "timeline",
1594
1592
  provider: this.provider,
@@ -1611,8 +1609,23 @@ export class ACPAgentSession {
1611
1609
  }
1612
1610
  finishTurn(event) {
1613
1611
  this.activeForegroundTurnId = null;
1612
+ if (this.activeSubmittedUserMessage?.turnId === event.turnId) {
1613
+ this.activeSubmittedUserMessage = null;
1614
+ }
1614
1615
  this.pushEvent(event);
1615
1616
  }
1617
+ isSubmittedUserMessageEcho(item) {
1618
+ const active = this.activeSubmittedUserMessage;
1619
+ if (!active || active.turnId !== this.activeForegroundTurnId) {
1620
+ return false;
1621
+ }
1622
+ if (item.messageId) {
1623
+ if (this.submittedUserMessageIds.has(item.messageId)) {
1624
+ return true;
1625
+ }
1626
+ }
1627
+ return active.text.startsWith(item.text);
1628
+ }
1616
1629
  emitBootstrapThreadEvent() {
1617
1630
  if (!this.bootstrapThreadEventPending || !this.sessionId) {
1618
1631
  return;
@@ -1,7 +1,7 @@
1
1
  import { type AgentDefinition, type McpServerConfig as ClaudeSdkMcpServerConfig, type SDKMessage } from "@anthropic-ai/claude-agent-sdk";
2
2
  import type { Logger } from "pino";
3
3
  import { type ClaudeQueryFactory } from "./query.js";
4
- import { type AgentCapabilityFlags, type AgentClient, type AgentCreateSessionOptions, type AgentFeature, type AgentLaunchContext, type AgentMetadata, type AgentModelDefinition, type AgentPersistenceHandle, type AgentSession, type AgentSessionConfig, type AgentTimelineItem, type ImportableProviderSession, type ImportProviderSessionContext, type ImportProviderSessionInput, type ListImportableSessionsOptions, type ListModelsOptions, type McpServerConfig } from "../../agent-sdk-types.js";
4
+ import { type AgentCapabilityFlags, type AgentClient, type AgentCreateSessionOptions, type AgentFeature, type AgentLaunchContext, type AgentMetadata, type AgentPersistenceHandle, type AgentSession, type AgentSessionConfig, type AgentTimelineItem, type FetchCatalogOptions, type ImportableProviderSession, type ImportProviderSessionContext, type ImportProviderSessionInput, type ListImportableSessionsOptions, type McpServerConfig, type ProviderCatalog } from "../../agent-sdk-types.js";
5
5
  import { type ProviderRuntimeSettings } from "../../provider-launch-config.js";
6
6
  export declare function normalizeClaudeAskUserQuestionRequestInput(toolName: string, input: AgentMetadata): AgentMetadata;
7
7
  export declare function normalizeClaudeAskUserQuestionUpdatedInput(updatedInput: AgentMetadata | undefined, fallbackInput: AgentMetadata | undefined): AgentMetadata;
@@ -39,7 +39,7 @@ export declare class ClaudeAgentClient implements AgentClient {
39
39
  constructor(options: ClaudeAgentClientOptions);
40
40
  createSession(config: AgentSessionConfig, launchContext?: AgentLaunchContext, options?: AgentCreateSessionOptions): Promise<AgentSession>;
41
41
  resumeSession(handle: AgentPersistenceHandle, overrides?: Partial<AgentSessionConfig>, launchContext?: AgentLaunchContext): Promise<AgentSession>;
42
- listModels(_options: ListModelsOptions): Promise<AgentModelDefinition[]>;
42
+ fetchCatalog(_options: FetchCatalogOptions): Promise<ProviderCatalog>;
43
43
  listFeatures(config: AgentSessionConfig): Promise<AgentFeature[]>;
44
44
  listImportableSessions(options?: ListImportableSessionsOptions): Promise<ImportableProviderSession[]>;
45
45
  importSession(input: ImportProviderSessionInput, context: ImportProviderSessionContext): Promise<import("../../agent-sdk-types.js").ImportedProviderSession>;