@otto-code/client 0.7.4 → 0.7.5

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.
@@ -4,7 +4,7 @@ import { AgentRefreshedStatusPayloadSchema, CheckoutRenameBranchResponseSchema,
4
4
  import type { AgentStreamEventPayload, AgentSnapshotPayload, ProjectPlacementPayload, AgentPermissionResolvedMessage, CreateAgentRequestMessage, CreateOttoWorktreeRequest, CodeListFilesResponse, CodeSymbolLocation, CodeDefinitionLocation, CodeDefinitionStatus, CodeRenameApplyStatus, CodeRenameFileOutcome, CodeRenameUndoFile, CodeRenameUndoStatus, CodeHoverRange, CodeRenameEdit, CodeRenameFilePlan, LspLanguageState, LspRunningServer, CodeSolutionGetTreeResponse, CodeSolutionLoadProjectResponse, SolutionFormat, SolutionRef, SolutionTreeFolder, SolutionTreeProject, SolutionProjectNode, SolutionProjectStatus, SolutionPackageReference, FileCreateResult, FileDeleteResult, FileDownloadTokenResponse, FileEntryKind, FileEol, FileRenameResult, FileReplaceFileResult, FileReplaceRequest, FileReplaceResponse, FileSearchResultPayload, FileSearchSummary, FileUploadResponse, FileExplorerResponse, FileWatchEventPayload, FileWriteResult, FileRefineResult, FileRefineDocument, FileRefineReference, FetchAgentTimelineResponseMessage, AgentForkContextResponseMessage, GitSetupOptions, CheckoutStatusResponse, CheckoutCommitResponse, CheckoutGitCommitResponse, CheckoutGitCommitAgentResponse, CheckoutGitRollbackResponse, CheckoutGitFileHistoryResponse, CheckoutGitFileCommitDiffResponse, CheckoutGitFileBlameResponse, CheckoutGitFileOriginResponse, CheckoutGitGetOperationLogResponse, CheckoutMergeResponse, CheckoutMergeFromBaseResponse, CheckoutPullResponse, CheckoutPushResponse, CheckoutRefreshResponse, CheckoutPrCreateResponse, CheckoutPrMergeResponse, CheckoutPrMergeMethod, CheckoutGithubSetAutoMergeResponse, CheckoutGithubGetCheckDetailsResponse, PreviewListConfigResponse, PreviewStartResponse, PreviewBindTabResponse, PreviewStopResponse, CheckoutPrStatusResponse, PullRequestTimelineResponse, CheckoutSwitchBranchResponse, StashSaveResponse, StashPopResponse, StashListResponse, ValidateBranchResponse, BranchSuggestionsResponse, GitHubSearchResponse, GitHubSearchRequest, GitHostingProviderId, HostingSearchRequest, HostingSearchResponse, HostingAuthStatusResponse, DirectorySuggestionsResponse, OttoWorktreeListResponse, OttoWorktreeArchiveResponse, ProjectIconResponse, ContextCategory, ContextPromptPreviewGetResponseMessage, ContextReportGetResponseMessage, ContextEdgeConvertResponseMessage, ContextFindingsFixResponseMessage, PersonalityMemoryListResponseMessage, PersonalityMemoryUpdateResponseMessage, PersonalityMemoryTransferResponseMessage, PersonalityMemoryStatsResponseMessage, ProjectAddResponse, ProjectScaffoldGit, ProjectScaffoldProgress, ProjectScaffoldResponse, HostingListRepositoriesResponse, HostingListOwnersResponse, OpenProjectResponseMessage, ArchiveWorkspaceResponseMessage, WorkspaceArchivePreflightResponse, WorktreeBaseRefSetResponse, WorktreeReattachListResponse, WorktreeReattachResponse, WorktreeReattachTarget, WorkspaceSetupStatusResponseMessage, ListCommandsResponse, ListProviderFeaturesResponseMessage, ListProviderModelsResponseMessage, ListProviderModesResponseMessage, ListAvailableProvidersResponse, GetProvidersSnapshotResponseMessage, RefreshProvidersSnapshotResponseMessage, ProviderDiagnosticResponseMessage, ProviderUsageListResponseMessage, StatsActivityGetResponseMessage, StatsActivityResetResponseMessage, UsageLogGetResponseMessage, AgentContextGetUsageResponseMessage, DaemonGetStatusResponse, DaemonGetPairingOfferResponse, DiagnosticsResponse, AgentRewindResponseMessage, ListTerminalsResponse, CreateTerminalResponse, SubscribeTerminalResponse, SubscribeTerminalRequest, CloseItemsResponse, AttachmentsImagesClearResponse, AttachmentsImagesStatsResponse, HistoryAgentsClearArchivedResponse, KillTerminalResponse, CaptureTerminalResponse, TerminalInput, SessionInboundMessage, SessionOutboundMessage, SendAgentMessageRequest, AgentPromptDelivery, TasksSuggestedStartMode, OttoConfigRaw, OttoConfigRevision, WorkspaceCreateRequest } from "@otto-code/protocol/messages";
5
5
  import type { AgentPermissionRequest, AgentPermissionResponse, AgentPersistenceHandle, AgentProviderNotice, AgentProvider, AgentSessionConfig } from "@otto-code/protocol/agent-types";
6
6
  import type { OrchestrationGraph, PromptTemplate, Run } from "@otto-code/protocol/orchestration";
7
- import type { CueMoment, MutableDaemonConfig, MutableDaemonConfigPatch, ProjectLink, SpeechSettingsOptions, SpeechTtsPreviewResult, SpeechTtsSpeakResult, SpeechTtsSpeakCancelResult, VisualizerVoiceCuesResult } from "@otto-code/protocol/messages";
7
+ import type { BrainCatalogModel, BrainEvals, BrainHfSearchResult, BrainHostStatus, BrainInstalledModel, BrainJob, BrainNetworkInfo, BrainRemoteConfig, BrainRepoQuant, BrainRuntime, ConnectorsListToolsResponse, CueMoment, MutableDaemonConfig, MutableDaemonConfigPatch, ProjectLink, SpeechSettingsOptions, SpeechTtsPreviewResult, SpeechTtsSpeakResult, SpeechTtsSpeakCancelResult, VisualizerVoiceCuesResult, AgentPersonalitiesGenerateProfileResult } from "@otto-code/protocol/messages";
8
8
  import { type DaemonTransportFactory, type WebSocketFactory } from "./daemon-client-transport.js";
9
9
  import { type DaemonClientTrafficHotspot, type DaemonClientTrafficTotals } from "./daemon-client-runtime-metrics.js";
10
10
  import { type TerminalStreamEvent } from "./terminal-stream-router.js";
@@ -1537,6 +1537,29 @@ export declare class DaemonClient {
1537
1537
  requestId: string;
1538
1538
  config: MutableDaemonConfig;
1539
1539
  }>;
1540
+ connectorsListTools(connectorId: string, requestId?: string): Promise<ConnectorsListToolsResponse["payload"]>;
1541
+ brainHostStatus(requestId?: string): Promise<BrainHostStatus>;
1542
+ brainHostStart(model?: string | null, requestId?: string): Promise<BrainHostStatus>;
1543
+ brainHostStop(requestId?: string): Promise<BrainHostStatus>;
1544
+ brainHostRestart(model?: string | null, requestId?: string): Promise<BrainHostStatus>;
1545
+ brainEvalsGet(requestId?: string): Promise<BrainEvals | null>;
1546
+ brainRemoteConfigGet(requestId?: string): Promise<BrainRemoteConfig | null>;
1547
+ brainRemoteConfigPatch(patch: BrainRemoteConfig, requestId?: string): Promise<BrainRemoteConfig | null>;
1548
+ brainModelsList(requestId?: string): Promise<string[]>;
1549
+ brainNetworkDiscover(requestId?: string): Promise<BrainNetworkInfo | null>;
1550
+ brainModelsScan(requestId?: string): Promise<BrainInstalledModel[]>;
1551
+ brainCatalogList(requestId?: string): Promise<BrainCatalogModel[]>;
1552
+ brainRuntimeList(requestId?: string): Promise<BrainRuntime[]>;
1553
+ brainModelsPull(model: string, requestId?: string): Promise<BrainJob>;
1554
+ brainHfSearch(query: string, limit?: number | null, requestId?: string): Promise<BrainHfSearchResult[]>;
1555
+ brainHfQuants(repo: string, requestId?: string): Promise<BrainRepoQuant[]>;
1556
+ brainModelsAdd(repo: string, quant: string, requestId?: string): Promise<BrainJob>;
1557
+ brainRuntimeInstall(build?: string | null, requestId?: string): Promise<BrainJob>;
1558
+ brainCalibrate(model: string, requestId?: string): Promise<BrainJob>;
1559
+ brainSweep(model: string, requestId?: string): Promise<BrainJob>;
1560
+ brainBench(model?: string | null, requestId?: string): Promise<BrainJob>;
1561
+ brainJobsList(requestId?: string): Promise<BrainJob[]>;
1562
+ brainJobsCancel(jobId: string, requestId?: string): Promise<BrainJob[]>;
1540
1563
  getSpeechSettingsOptions(requestId?: string): Promise<{
1541
1564
  requestId: string;
1542
1565
  options: SpeechSettingsOptions;
@@ -1569,6 +1592,13 @@ export declare class DaemonClient {
1569
1592
  requestId: string;
1570
1593
  stats: Record<string, number>;
1571
1594
  }>;
1595
+ generatePersonalityProfile(params: {
1596
+ name: string;
1597
+ roles?: string[];
1598
+ glowA?: string;
1599
+ glowB?: string;
1600
+ cwd?: string;
1601
+ }, requestId?: string): Promise<AgentPersonalitiesGenerateProfileResult>;
1572
1602
  sendBrowserAutomationExecuteResponse(response: BrowserAutomationExecuteResponse): void;
1573
1603
  readProjectConfig(repoRoot: string, requestId?: string): Promise<ReadProjectConfigPayload>;
1574
1604
  writeProjectConfig(input: WriteProjectConfigInput): Promise<WriteProjectConfigPayload>;
@@ -169,6 +169,17 @@ function toReasonCode(reason) {
169
169
  }
170
170
  return "unknown";
171
171
  }
172
+ // A job-starting brain RPC returns { job, error }; surface the error as a throw
173
+ // so callers get a plain Promise<BrainJob>.
174
+ function unwrapBrainJob(payload) {
175
+ if (payload.error) {
176
+ throw new Error(payload.error);
177
+ }
178
+ if (!payload.job) {
179
+ throw new Error("The brain did not start the operation.");
180
+ }
181
+ return payload.job;
182
+ }
172
183
  export class DaemonClient {
173
184
  constructor(config) {
174
185
  this.config = config;
@@ -3937,6 +3948,249 @@ export class DaemonClient {
3937
3948
  responseType: "set_daemon_config_response",
3938
3949
  });
3939
3950
  }
3951
+ // Enumerate a connector's tools live (connect + listTools), each flagged with
3952
+ // its configured disabled state. Registry edits (add/enable/disable a
3953
+ // connector or a tool) go through patchDaemonConfig's `connectors` instead.
3954
+ async connectorsListTools(connectorId, requestId) {
3955
+ return this.sendCorrelatedSessionRequest({
3956
+ requestId,
3957
+ message: {
3958
+ type: "connectors.list_tools.request",
3959
+ connectorId,
3960
+ },
3961
+ responseType: "connectors.list_tools.response",
3962
+ });
3963
+ }
3964
+ async brainHostStatus(requestId) {
3965
+ const payload = await this.sendCorrelatedSessionRequest({
3966
+ requestId,
3967
+ message: {
3968
+ type: "brain.host.status.request",
3969
+ },
3970
+ responseType: "brain.host.status.response",
3971
+ });
3972
+ return payload.status;
3973
+ }
3974
+ async brainHostStart(model, requestId) {
3975
+ const payload = await this.sendCorrelatedSessionRequest({
3976
+ requestId,
3977
+ message: {
3978
+ type: "brain.host.start.request",
3979
+ model: model ?? null,
3980
+ },
3981
+ responseType: "brain.host.start.response",
3982
+ });
3983
+ return payload.status;
3984
+ }
3985
+ async brainHostStop(requestId) {
3986
+ const payload = await this.sendCorrelatedSessionRequest({
3987
+ requestId,
3988
+ message: {
3989
+ type: "brain.host.stop.request",
3990
+ },
3991
+ responseType: "brain.host.stop.response",
3992
+ });
3993
+ return payload.status;
3994
+ }
3995
+ async brainHostRestart(model, requestId) {
3996
+ const payload = await this.sendCorrelatedSessionRequest({
3997
+ requestId,
3998
+ message: {
3999
+ type: "brain.host.restart.request",
4000
+ model: model ?? null,
4001
+ },
4002
+ responseType: "brain.host.restart.response",
4003
+ });
4004
+ return payload.status;
4005
+ }
4006
+ async brainEvalsGet(requestId) {
4007
+ const payload = await this.sendCorrelatedSessionRequest({
4008
+ requestId,
4009
+ message: {
4010
+ type: "brain.evals.get.request",
4011
+ },
4012
+ responseType: "brain.evals.get.response",
4013
+ });
4014
+ return payload.evals;
4015
+ }
4016
+ async brainRemoteConfigGet(requestId) {
4017
+ const payload = await this.sendCorrelatedSessionRequest({
4018
+ requestId,
4019
+ message: {
4020
+ type: "brain.remote.config.get.request",
4021
+ },
4022
+ responseType: "brain.remote.config.get.response",
4023
+ });
4024
+ if (payload.error) {
4025
+ throw new Error(payload.error);
4026
+ }
4027
+ return payload.config;
4028
+ }
4029
+ async brainRemoteConfigPatch(patch, requestId) {
4030
+ const payload = await this.sendCorrelatedSessionRequest({
4031
+ requestId,
4032
+ message: {
4033
+ type: "brain.remote.config.patch.request",
4034
+ patch,
4035
+ },
4036
+ responseType: "brain.remote.config.patch.response",
4037
+ });
4038
+ if (payload.error) {
4039
+ throw new Error(payload.error);
4040
+ }
4041
+ return payload.config;
4042
+ }
4043
+ async brainModelsList(requestId) {
4044
+ const payload = await this.sendCorrelatedSessionRequest({
4045
+ requestId,
4046
+ message: {
4047
+ type: "brain.models.list.request",
4048
+ },
4049
+ responseType: "brain.models.list.response",
4050
+ });
4051
+ if (payload.error) {
4052
+ throw new Error(payload.error);
4053
+ }
4054
+ return payload.models;
4055
+ }
4056
+ async brainNetworkDiscover(requestId) {
4057
+ const payload = await this.sendCorrelatedSessionRequest({
4058
+ requestId,
4059
+ message: {
4060
+ type: "brain.network.discover.request",
4061
+ },
4062
+ responseType: "brain.network.discover.response",
4063
+ });
4064
+ if (payload.error) {
4065
+ throw new Error(payload.error);
4066
+ }
4067
+ return payload.info;
4068
+ }
4069
+ async brainModelsScan(requestId) {
4070
+ const payload = await this.sendCorrelatedSessionRequest({
4071
+ requestId,
4072
+ message: { type: "brain.models.scan.request" },
4073
+ responseType: "brain.models.scan.response",
4074
+ });
4075
+ if (payload.error) {
4076
+ throw new Error(payload.error);
4077
+ }
4078
+ return payload.models;
4079
+ }
4080
+ async brainCatalogList(requestId) {
4081
+ const payload = await this.sendCorrelatedSessionRequest({
4082
+ requestId,
4083
+ message: { type: "brain.catalog.list.request" },
4084
+ responseType: "brain.catalog.list.response",
4085
+ });
4086
+ if (payload.error) {
4087
+ throw new Error(payload.error);
4088
+ }
4089
+ return payload.models;
4090
+ }
4091
+ async brainRuntimeList(requestId) {
4092
+ const payload = await this.sendCorrelatedSessionRequest({
4093
+ requestId,
4094
+ message: { type: "brain.runtime.list.request" },
4095
+ responseType: "brain.runtime.list.response",
4096
+ });
4097
+ if (payload.error) {
4098
+ throw new Error(payload.error);
4099
+ }
4100
+ return payload.runtimes;
4101
+ }
4102
+ async brainModelsPull(model, requestId) {
4103
+ const payload = await this.sendCorrelatedSessionRequest({
4104
+ requestId,
4105
+ message: { type: "brain.models.pull.request", model },
4106
+ responseType: "brain.models.pull.response",
4107
+ });
4108
+ return unwrapBrainJob(payload);
4109
+ }
4110
+ async brainHfSearch(query, limit, requestId) {
4111
+ const payload = await this.sendCorrelatedSessionRequest({
4112
+ requestId,
4113
+ message: { type: "brain.hf.search.request", query, limit: limit ?? null },
4114
+ responseType: "brain.hf.search.response",
4115
+ });
4116
+ if (payload.error) {
4117
+ throw new Error(payload.error);
4118
+ }
4119
+ return payload.results;
4120
+ }
4121
+ async brainHfQuants(repo, requestId) {
4122
+ const payload = await this.sendCorrelatedSessionRequest({
4123
+ requestId,
4124
+ message: { type: "brain.hf.quants.request", repo },
4125
+ responseType: "brain.hf.quants.response",
4126
+ });
4127
+ if (payload.error) {
4128
+ throw new Error(payload.error);
4129
+ }
4130
+ return payload.quants;
4131
+ }
4132
+ async brainModelsAdd(repo, quant, requestId) {
4133
+ const payload = await this.sendCorrelatedSessionRequest({
4134
+ requestId,
4135
+ message: { type: "brain.models.add.request", repo, quant },
4136
+ responseType: "brain.models.add.response",
4137
+ });
4138
+ return unwrapBrainJob(payload);
4139
+ }
4140
+ async brainRuntimeInstall(build, requestId) {
4141
+ const payload = await this.sendCorrelatedSessionRequest({
4142
+ requestId,
4143
+ message: { type: "brain.runtime.install.request", build: build ?? null },
4144
+ responseType: "brain.runtime.install.response",
4145
+ });
4146
+ return unwrapBrainJob(payload);
4147
+ }
4148
+ async brainCalibrate(model, requestId) {
4149
+ const payload = await this.sendCorrelatedSessionRequest({
4150
+ requestId,
4151
+ message: { type: "brain.calibrate.request", model },
4152
+ responseType: "brain.calibrate.response",
4153
+ });
4154
+ return unwrapBrainJob(payload);
4155
+ }
4156
+ async brainSweep(model, requestId) {
4157
+ const payload = await this.sendCorrelatedSessionRequest({
4158
+ requestId,
4159
+ message: { type: "brain.sweep.request", model },
4160
+ responseType: "brain.sweep.response",
4161
+ });
4162
+ return unwrapBrainJob(payload);
4163
+ }
4164
+ async brainBench(model, requestId) {
4165
+ const payload = await this.sendCorrelatedSessionRequest({
4166
+ requestId,
4167
+ message: { type: "brain.bench.request", model: model ?? null },
4168
+ responseType: "brain.bench.response",
4169
+ });
4170
+ return unwrapBrainJob(payload);
4171
+ }
4172
+ async brainJobsList(requestId) {
4173
+ const payload = await this.sendCorrelatedSessionRequest({
4174
+ requestId,
4175
+ message: { type: "brain.jobs.list.request" },
4176
+ responseType: "brain.jobs.list.response",
4177
+ });
4178
+ if (payload.error) {
4179
+ throw new Error(payload.error);
4180
+ }
4181
+ return payload.jobs;
4182
+ }
4183
+ async brainJobsCancel(jobId, requestId) {
4184
+ const payload = await this.sendCorrelatedSessionRequest({
4185
+ requestId,
4186
+ message: { type: "brain.jobs.cancel.request", jobId },
4187
+ responseType: "brain.jobs.cancel.response",
4188
+ });
4189
+ if (payload.error) {
4190
+ throw new Error(payload.error);
4191
+ }
4192
+ return payload.jobs;
4193
+ }
3940
4194
  async getSpeechSettingsOptions(requestId) {
3941
4195
  return this.sendNamespacedCorrelatedSessionRequest({
3942
4196
  requestId,
@@ -4007,6 +4261,25 @@ export class DaemonClient {
4007
4261
  },
4008
4262
  });
4009
4263
  }
4264
+ // Author a personality profile (the prose personality prompt) from a draft's
4265
+ // name, roles, and spinner colors. Routed through the Writer chain; the caller
4266
+ // drops the result into the editor's prompt field.
4267
+ async generatePersonalityProfile(params, requestId) {
4268
+ return this.sendNamespacedCorrelatedSessionRequest({
4269
+ requestId,
4270
+ message: {
4271
+ type: "agentPersonalities.generate_profile.request",
4272
+ name: params.name,
4273
+ ...(params.roles && params.roles.length > 0 ? { roles: params.roles } : {}),
4274
+ ...(params.glowA ? { glowA: params.glowA } : {}),
4275
+ ...(params.glowB ? { glowB: params.glowB } : {}),
4276
+ ...(params.cwd ? { cwd: params.cwd } : {}),
4277
+ },
4278
+ // Same reason as the voice cues: the daemon spawns a structured-generation
4279
+ // agent, and provider SDK cold starts blow past the 60s default.
4280
+ timeout: 180000,
4281
+ });
4282
+ }
4010
4283
  sendBrowserAutomationExecuteResponse(response) {
4011
4284
  this.sendSessionMessageStrict(response);
4012
4285
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@otto-code/client",
3
- "version": "0.7.4",
3
+ "version": "0.7.5",
4
4
  "description": "Otto client SDK package",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "files": [
@@ -36,8 +36,8 @@
36
36
  "test": "vitest run"
37
37
  },
38
38
  "dependencies": {
39
- "@otto-code/protocol": "0.7.4",
40
- "@otto-code/relay": "0.7.4",
39
+ "@otto-code/protocol": "0.7.5",
40
+ "@otto-code/relay": "0.7.5",
41
41
  "zod": "^4.4.3"
42
42
  },
43
43
  "devDependencies": {