remote-codex 0.1.9 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/apps/supervisor-api/dist/index.js +11942 -6101
  2. package/apps/supervisor-web/dist/assets/{highlighted-body-OFNGDK62-BFD4Ytvg.js → highlighted-body-OFNGDK62-ChrwAL9u.js} +1 -1
  3. package/apps/supervisor-web/dist/assets/index-DHf2HOXx.js +381 -0
  4. package/apps/supervisor-web/dist/assets/index-DpWxXCgt.css +32 -0
  5. package/apps/supervisor-web/dist/assets/{xterm-CukFWbxr.js → xterm-D4sevve4.js} +1 -1
  6. package/apps/supervisor-web/dist/index.html +2 -2
  7. package/config/codex-model-pricing.json +63 -0
  8. package/package.json +5 -2
  9. package/packages/agent-runtime/src/index.ts +4 -0
  10. package/packages/agent-runtime/src/management-errors.ts +11 -0
  11. package/packages/agent-runtime/src/model-pricing.ts +312 -0
  12. package/packages/agent-runtime/src/registry.ts +19 -4
  13. package/packages/agent-runtime/src/runtime-errors.ts +97 -0
  14. package/packages/agent-runtime/src/types.ts +50 -4
  15. package/packages/agent-runtime/src/unavailable-runtime.ts +169 -0
  16. package/packages/claude/src/historyItems.ts +693 -0
  17. package/packages/claude/src/index.ts +2 -0
  18. package/packages/claude/src/runtimeAdapter.test.ts +2138 -0
  19. package/packages/claude/src/runtimeAdapter.ts +2145 -0
  20. package/packages/codex/src/appServerManager.ts +12 -3
  21. package/packages/codex/src/historyItems.test.ts +110 -0
  22. package/packages/codex/src/historyItems.ts +97 -16
  23. package/packages/codex/src/hookHistory.test.ts +59 -0
  24. package/packages/codex/src/index.ts +7 -0
  25. package/packages/codex/src/local-session-store.ts +390 -0
  26. package/packages/codex/src/management/codex-management-service.ts +454 -0
  27. package/packages/codex/src/management/codexHostConfig.test.ts +88 -0
  28. package/packages/codex/src/management/codexHostConfig.ts +188 -0
  29. package/packages/codex/src/management/errors.ts +20 -0
  30. package/packages/codex/src/modelPricing.test.ts +184 -0
  31. package/packages/codex/src/modelPricing.ts +9 -0
  32. package/packages/codex/src/runtime-errors.test.ts +72 -0
  33. package/packages/codex/src/runtime-errors.ts +37 -0
  34. package/packages/codex/src/runtimeAdapter.ts +25 -2
  35. package/packages/codex/src/thread-title.ts +1 -0
  36. package/packages/db/src/repositories.ts +30 -0
  37. package/packages/opencode/src/historyItems.test.ts +504 -0
  38. package/packages/opencode/src/historyItems.ts +896 -0
  39. package/packages/opencode/src/index.ts +2 -0
  40. package/packages/opencode/src/runtimeAdapter.test.ts +1355 -0
  41. package/packages/opencode/src/runtimeAdapter.ts +1469 -0
  42. package/packages/shared/src/agent-providers.ts +56 -0
  43. package/packages/shared/src/index.ts +174 -35
  44. package/apps/supervisor-web/dist/assets/index-CbIt0KnL.css +0 -32
  45. package/apps/supervisor-web/dist/assets/index-Rd2EBQac.js +0 -377
@@ -0,0 +1,312 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ import type {
5
+ ThreadTurnPriceEstimateDto,
6
+ ThreadTurnTokenUsageDto,
7
+ } from '../../shared/src/index';
8
+
9
+ export type PricingTierKey = 'standard' | 'fast';
10
+
11
+ interface ModelPricingEntry {
12
+ inputUsdPerMillion: number;
13
+ cachedInputUsdPerMillion: number;
14
+ outputUsdPerMillion: number;
15
+ supportsFastMode: boolean;
16
+ fastMultiplier?: number;
17
+ contextWindowTokens?: number;
18
+ }
19
+
20
+ interface PricingTierConfig {
21
+ multiplier: number;
22
+ }
23
+
24
+ interface TurnPricingSnapshot {
25
+ pricingModelKey: string;
26
+ pricingTierKey: PricingTierKey;
27
+ }
28
+
29
+ interface PricingConfig {
30
+ currency: 'USD';
31
+ tiers: Record<PricingTierKey, PricingTierConfig>;
32
+ models: Record<string, ModelPricingEntry>;
33
+ }
34
+
35
+ const TOKEN_PRICE_DENOMINATOR = 1_000_000;
36
+ let cachedPricingConfig: PricingConfig | null = null;
37
+
38
+ function resolvePackageRoot(start = process.cwd()) {
39
+ if (process.env.REMOTE_CODEX_PACKAGE_ROOT) {
40
+ return path.resolve(process.env.REMOTE_CODEX_PACKAGE_ROOT);
41
+ }
42
+
43
+ let current = path.resolve(start);
44
+
45
+ while (current !== path.dirname(current)) {
46
+ if (fs.existsSync(path.join(current, 'pnpm-workspace.yaml'))) {
47
+ return current;
48
+ }
49
+ current = path.dirname(current);
50
+ }
51
+
52
+ throw new Error('Unable to locate package root for model pricing config.');
53
+ }
54
+
55
+ function getPricingConfigPath() {
56
+ return path.join(resolvePackageRoot(), 'config', 'codex-model-pricing.json');
57
+ }
58
+
59
+ function isPositiveNumber(value: unknown) {
60
+ return typeof value === 'number' && Number.isFinite(value) && value >= 0;
61
+ }
62
+
63
+ function parsePricingConfig(raw: unknown): PricingConfig {
64
+ if (!raw || typeof raw !== 'object') {
65
+ throw new Error('Pricing config must be a JSON object.');
66
+ }
67
+
68
+ const config = raw as {
69
+ currency?: unknown;
70
+ tiers?: unknown;
71
+ models?: unknown;
72
+ };
73
+
74
+ if (config.currency !== 'USD') {
75
+ throw new Error('Pricing config currency must be "USD".');
76
+ }
77
+
78
+ if (!config.tiers || typeof config.tiers !== 'object') {
79
+ throw new Error('Pricing config must include a "tiers" object.');
80
+ }
81
+ if (!config.models || typeof config.models !== 'object') {
82
+ throw new Error('Pricing config must include a "models" object.');
83
+ }
84
+
85
+ const tiersSource = config.tiers as Record<string, unknown>;
86
+ const modelsSource = config.models as Record<string, unknown>;
87
+
88
+ const tiers: Record<PricingTierKey, PricingTierConfig> = {
89
+ standard: {
90
+ multiplier: 1,
91
+ },
92
+ fast: {
93
+ multiplier: 1,
94
+ },
95
+ };
96
+
97
+ for (const tierKey of ['standard', 'fast'] as const) {
98
+ const value = tiersSource[tierKey];
99
+ if (!value || typeof value !== 'object') {
100
+ throw new Error(`Pricing config tier "${tierKey}" is missing or invalid.`);
101
+ }
102
+
103
+ const multiplier = (value as { multiplier?: unknown }).multiplier;
104
+ if (!isPositiveNumber(multiplier)) {
105
+ throw new Error(`Pricing config tier "${tierKey}" multiplier must be a non-negative number.`);
106
+ }
107
+
108
+ tiers[tierKey] = {
109
+ multiplier: multiplier as number,
110
+ };
111
+ }
112
+
113
+ const models: Record<string, ModelPricingEntry> = {};
114
+ for (const [modelKey, value] of Object.entries(modelsSource)) {
115
+ if (!value || typeof value !== 'object') {
116
+ throw new Error(`Pricing config model "${modelKey}" is invalid.`);
117
+ }
118
+
119
+ const entry = value as {
120
+ inputUsdPerMillion?: unknown;
121
+ cachedInputUsdPerMillion?: unknown;
122
+ outputUsdPerMillion?: unknown;
123
+ supportsFastMode?: unknown;
124
+ fastMultiplier?: unknown;
125
+ contextWindowTokens?: unknown;
126
+ };
127
+
128
+ if (
129
+ !isPositiveNumber(entry.inputUsdPerMillion) ||
130
+ !isPositiveNumber(entry.cachedInputUsdPerMillion) ||
131
+ !isPositiveNumber(entry.outputUsdPerMillion) ||
132
+ typeof entry.supportsFastMode !== 'boolean'
133
+ ) {
134
+ throw new Error(`Pricing config model "${modelKey}" has invalid fields.`);
135
+ }
136
+ if (
137
+ entry.fastMultiplier !== undefined &&
138
+ !isPositiveNumber(entry.fastMultiplier)
139
+ ) {
140
+ throw new Error(`Pricing config model "${modelKey}" fastMultiplier must be a non-negative number.`);
141
+ }
142
+ if (
143
+ entry.contextWindowTokens !== undefined &&
144
+ !isPositiveNumber(entry.contextWindowTokens)
145
+ ) {
146
+ throw new Error(`Pricing config model "${modelKey}" contextWindowTokens must be a non-negative number.`);
147
+ }
148
+
149
+ models[modelKey] = {
150
+ inputUsdPerMillion: entry.inputUsdPerMillion as number,
151
+ cachedInputUsdPerMillion: entry.cachedInputUsdPerMillion as number,
152
+ outputUsdPerMillion: entry.outputUsdPerMillion as number,
153
+ supportsFastMode: entry.supportsFastMode,
154
+ ...(entry.fastMultiplier !== undefined
155
+ ? { fastMultiplier: entry.fastMultiplier as number }
156
+ : {}),
157
+ ...(entry.contextWindowTokens !== undefined
158
+ ? { contextWindowTokens: entry.contextWindowTokens as number }
159
+ : {}),
160
+ };
161
+ }
162
+
163
+ return {
164
+ currency: 'USD',
165
+ tiers,
166
+ models,
167
+ };
168
+ }
169
+
170
+ function getPricingConfig() {
171
+ if (cachedPricingConfig) {
172
+ return cachedPricingConfig;
173
+ }
174
+
175
+ const configPath = getPricingConfigPath();
176
+ const content = fs.readFileSync(configPath, 'utf8');
177
+ cachedPricingConfig = parsePricingConfig(JSON.parse(content) as unknown);
178
+ return cachedPricingConfig;
179
+ }
180
+
181
+ export function resetPricingConfigCacheForTest() {
182
+ cachedPricingConfig = null;
183
+ }
184
+
185
+ export function pricingTierForFastMode(fastMode: boolean): PricingTierKey {
186
+ return fastMode ? 'fast' : 'standard';
187
+ }
188
+
189
+ function pricingModelKeyForModel(model: string | null | undefined) {
190
+ const modelKey = model?.trim();
191
+ if (!modelKey) {
192
+ return null;
193
+ }
194
+
195
+ const models = getPricingConfig().models;
196
+ if (models[modelKey]) {
197
+ return modelKey;
198
+ }
199
+
200
+ const claudeDateSuffixMatch = modelKey.match(/^(claude-[a-z]+-\d+(?:-\d+)?)-20\d{6}$/);
201
+ if (claudeDateSuffixMatch?.[1] && models[claudeDateSuffixMatch[1]]) {
202
+ return claudeDateSuffixMatch[1];
203
+ }
204
+
205
+ return modelKey;
206
+ }
207
+
208
+ export function supportsFastMode(model: string | null | undefined) {
209
+ const pricingModelKey = pricingModelKeyForModel(model);
210
+ if (!pricingModelKey) {
211
+ return false;
212
+ }
213
+
214
+ return getPricingConfig().models[pricingModelKey]?.supportsFastMode === true;
215
+ }
216
+
217
+ export function contextWindowForModel(model: string | null | undefined) {
218
+ const pricingModelKey = pricingModelKeyForModel(model);
219
+ if (!pricingModelKey) {
220
+ return null;
221
+ }
222
+
223
+ const contextWindow = getPricingConfig().models[pricingModelKey]?.contextWindowTokens;
224
+ return typeof contextWindow === 'number' && contextWindow > 0
225
+ ? contextWindow
226
+ : null;
227
+ }
228
+
229
+ export function buildTurnPricingSnapshot(
230
+ model: string | null | undefined,
231
+ fastMode: boolean,
232
+ ): TurnPricingSnapshot | null {
233
+ const pricingModelKey = pricingModelKeyForModel(model);
234
+ if (!pricingModelKey) {
235
+ return null;
236
+ }
237
+
238
+ return {
239
+ pricingModelKey,
240
+ pricingTierKey: pricingTierForFastMode(fastMode),
241
+ };
242
+ }
243
+
244
+ export function estimateTurnPrice(
245
+ usage: ThreadTurnTokenUsageDto | null | undefined,
246
+ snapshot:
247
+ | {
248
+ pricingModelKey: string | null | undefined;
249
+ pricingTierKey: PricingTierKey | string | null | undefined;
250
+ }
251
+ | null
252
+ | undefined,
253
+ ): ThreadTurnPriceEstimateDto | null {
254
+ if (!usage?.total) {
255
+ return null;
256
+ }
257
+
258
+ const pricingModelKey = pricingModelKeyForModel(snapshot?.pricingModelKey);
259
+ if (!pricingModelKey) {
260
+ return null;
261
+ }
262
+
263
+ const pricingConfig = getPricingConfig();
264
+ const modelPricing = pricingConfig.models[pricingModelKey];
265
+ if (!modelPricing) {
266
+ return null;
267
+ }
268
+
269
+ const tierKey =
270
+ snapshot?.pricingTierKey === 'fast' ? 'fast' : snapshot?.pricingTierKey === 'standard'
271
+ ? 'standard'
272
+ : null;
273
+ if (!tierKey) {
274
+ return null;
275
+ }
276
+
277
+ const tier = pricingConfig.tiers[tierKey];
278
+ if (!tier) {
279
+ return null;
280
+ }
281
+
282
+ const nonCachedInputTokens = Math.max(
283
+ usage.total.inputTokens - usage.total.cachedInputTokens,
284
+ 0,
285
+ );
286
+ const cachedInputTokens = Math.max(usage.total.cachedInputTokens, 0);
287
+ const outputTokens = Math.max(usage.total.outputTokens, 0);
288
+ const multiplier =
289
+ tierKey === 'fast' && modelPricing.fastMultiplier !== undefined
290
+ ? modelPricing.fastMultiplier
291
+ : tier.multiplier;
292
+
293
+ const inputUsd =
294
+ (nonCachedInputTokens * modelPricing.inputUsdPerMillion * multiplier) /
295
+ TOKEN_PRICE_DENOMINATOR;
296
+ const cachedInputUsd =
297
+ (cachedInputTokens * modelPricing.cachedInputUsdPerMillion * multiplier) /
298
+ TOKEN_PRICE_DENOMINATOR;
299
+ const outputUsd =
300
+ (outputTokens * modelPricing.outputUsdPerMillion * multiplier) /
301
+ TOKEN_PRICE_DENOMINATOR;
302
+
303
+ return {
304
+ pricingModelKey,
305
+ pricingTierKey: tierKey,
306
+ currency: pricingConfig.currency,
307
+ inputUsd,
308
+ cachedInputUsd,
309
+ outputUsd,
310
+ totalUsd: inputUsd + cachedInputUsd + outputUsd,
311
+ };
312
+ }
@@ -1,3 +1,6 @@
1
+ import {
2
+ defaultAgentBackendId,
3
+ } from '../../shared/src/index';
1
4
  import {
2
5
  AgentProviderId,
3
6
  AgentRuntime,
@@ -7,7 +10,10 @@ import {
7
10
  export class AgentRuntimeRegistry {
8
11
  private readonly runtimes = new Map<AgentProviderId, AgentRuntime>();
9
12
 
10
- constructor(runtimes: AgentRuntime[]) {
13
+ constructor(
14
+ runtimes: AgentRuntime[],
15
+ private readonly defaultProvider: AgentProviderId = defaultAgentBackendId,
16
+ ) {
11
17
  for (const runtime of runtimes) {
12
18
  this.runtimes.set(runtime.provider, runtime);
13
19
  }
@@ -30,15 +36,24 @@ export class AgentRuntimeRegistry {
30
36
  }
31
37
 
32
38
  list(): AgentRuntimeDescriptor[] {
33
- return this.all().map((runtime, index) => ({
39
+ return this.all().map((runtime) => ({
34
40
  provider: runtime.provider,
35
41
  displayName: runtime.displayName,
36
42
  description: runtime.description,
37
- enabled: true,
38
- isDefault: index === 0,
43
+ enabled: isAgentRuntimeEnabled(runtime),
44
+ isDefault: runtime.provider === this.defaultProvider,
39
45
  status: runtime.getStatus(),
40
46
  capabilities: runtime.capabilities,
41
47
  managementSchema: runtime.managementSchema,
48
+ installation: runtime.installation,
42
49
  }));
43
50
  }
44
51
  }
52
+
53
+ export function isAgentRuntimeEnabled(runtime: Pick<AgentRuntime, 'capabilities' | 'installation'>) {
54
+ return (
55
+ runtime.installation.installed &&
56
+ runtime.capabilities.sessions.resume &&
57
+ runtime.capabilities.turns.start
58
+ );
59
+ }
@@ -0,0 +1,97 @@
1
+ import { AgentRuntimeError } from './types';
2
+
3
+ export type TurnSteerRace =
4
+ | { type: 'missing' }
5
+ | { type: 'turnIdMismatch'; actualTurnId: string };
6
+
7
+ function isRecord(value: unknown): value is Record<string, unknown> {
8
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
9
+ }
10
+
11
+ function stringField(value: unknown, key: string) {
12
+ return isRecord(value) && typeof value[key] === 'string' ? value[key] : null;
13
+ }
14
+
15
+ function remoteErrorMessage(error: unknown) {
16
+ if (error instanceof AgentRuntimeError) {
17
+ return error.message;
18
+ }
19
+ return error instanceof Error ? error.message : null;
20
+ }
21
+
22
+ export function parseTurnSteerRace(error: unknown): TurnSteerRace | null {
23
+ if (error instanceof AgentRuntimeError) {
24
+ const raceType = stringField(error.details, 'turnSteerRace');
25
+ if (raceType === 'missing') {
26
+ return { type: 'missing' };
27
+ }
28
+ if (raceType === 'turnIdMismatch') {
29
+ const actualTurnId = stringField(error.details, 'actualTurnId');
30
+ if (actualTurnId) {
31
+ return { type: 'turnIdMismatch', actualTurnId };
32
+ }
33
+ }
34
+ }
35
+
36
+ const message = remoteErrorMessage(error);
37
+ if (!message) {
38
+ return null;
39
+ }
40
+
41
+ if (message === 'no active turn to steer') {
42
+ return { type: 'missing' };
43
+ }
44
+
45
+ const mismatchPrefix = 'expected active turn id `';
46
+ const mismatchSeparator = '` but found `';
47
+ if (!message.startsWith(mismatchPrefix)) {
48
+ return null;
49
+ }
50
+
51
+ const actualTurnId = message
52
+ .slice(mismatchPrefix.length)
53
+ .split(mismatchSeparator)[1]
54
+ ?.replace(/`$/, '');
55
+
56
+ if (!actualTurnId) {
57
+ return null;
58
+ }
59
+
60
+ return {
61
+ type: 'turnIdMismatch',
62
+ actualTurnId,
63
+ };
64
+ }
65
+
66
+ export function isRuntimeRequestError(error: unknown) {
67
+ return error instanceof AgentRuntimeError;
68
+ }
69
+
70
+ export function isRemoteThreadBootstrapError(error: unknown) {
71
+ if (!(error instanceof AgentRuntimeError)) {
72
+ return false;
73
+ }
74
+
75
+ return (
76
+ error.message.includes('includeTurns is unavailable before first user message') ||
77
+ error.message.includes('is not materialized yet') ||
78
+ error.message.includes('no rollout found for thread id') ||
79
+ error.message.includes('failed to load rollout') ||
80
+ (error.message.includes('rollout at') && error.message.includes('is empty'))
81
+ );
82
+ }
83
+
84
+ export function isUnsupportedHooksListError(error: unknown) {
85
+ if (!(error instanceof AgentRuntimeError)) {
86
+ return false;
87
+ }
88
+
89
+ const remoteCode = isRecord(error.details) ? error.details.code : null;
90
+ const message = error.message.toLowerCase();
91
+ return (
92
+ remoteCode === -32601 ||
93
+ message.includes('endpoint not found') ||
94
+ message.includes('method not found') ||
95
+ (message.includes('hooks/list') && message.includes('not found'))
96
+ );
97
+ }
@@ -1,7 +1,15 @@
1
1
  import { EventEmitter } from 'node:events';
2
- import type { ThreadHistoryItemDto } from '../../shared/src/index';
2
+ import type {
3
+ AgentBackendIdDto,
4
+ AgentBackendInstallationDto,
5
+ ThreadHistoryItemDto,
6
+ } from '../../shared/src/index';
3
7
 
4
- export type AgentProviderId = 'codex' | 'claude';
8
+ export const transientAgentHistoryItemSymbol: unique symbol = Symbol(
9
+ 'remoteCodex.transientAgentHistoryItem',
10
+ );
11
+
12
+ export type AgentProviderId = AgentBackendIdDto;
5
13
 
6
14
  export type AgentRuntimeErrorCode =
7
15
  | 'provider_unavailable'
@@ -84,6 +92,7 @@ export interface AgentRuntimeDescriptor {
84
92
  status: AgentRuntimeStatus;
85
93
  capabilities: AgentProviderCapabilities;
86
94
  managementSchema: AgentRuntimeManagementSchema;
95
+ installation: AgentBackendInstallationDto;
87
96
  }
88
97
 
89
98
  export interface AgentRuntimeConfigFileSchema {
@@ -142,6 +151,7 @@ export interface AgentModel {
142
151
  description: string;
143
152
  isDefault: boolean;
144
153
  hidden: boolean;
154
+ supportsPerformanceMode?: boolean;
145
155
  supportedReasoningEfforts: Array<{
146
156
  reasoningEffort: string;
147
157
  description: string;
@@ -169,13 +179,33 @@ export interface AgentSessionSummary {
169
179
  rawSession?: unknown;
170
180
  }
171
181
 
172
- export type AgentHistoryItem = ThreadHistoryItemDto;
182
+ export type AgentHistoryItem = ThreadHistoryItemDto & {
183
+ [transientAgentHistoryItemSymbol]?: true;
184
+ };
185
+
186
+ export function markTransientAgentHistoryItem<T extends ThreadHistoryItemDto>(
187
+ item: T,
188
+ ): T & AgentHistoryItem {
189
+ Object.defineProperty(item, transientAgentHistoryItemSymbol, {
190
+ value: true,
191
+ enumerable: false,
192
+ configurable: true,
193
+ });
194
+ return item as T & AgentHistoryItem;
195
+ }
196
+
197
+ export function isTransientAgentHistoryItem(
198
+ item: ThreadHistoryItemDto,
199
+ ): item is AgentHistoryItem & { [transientAgentHistoryItemSymbol]: true } {
200
+ return Boolean((item as AgentHistoryItem)[transientAgentHistoryItemSymbol]);
201
+ }
173
202
 
174
203
  export type AgentTurnItem = AgentHistoryItem;
175
204
 
176
205
  export interface AgentTurn {
177
206
  providerTurnId: string;
178
207
  rawTurnId?: string;
208
+ startedAt?: string | null;
179
209
  status: 'completed' | 'interrupted' | 'failed' | 'inProgress';
180
210
  error: { message?: string } | null;
181
211
  items: AgentHistoryItem[];
@@ -184,6 +214,14 @@ export interface AgentTurn {
184
214
 
185
215
  export interface AgentSessionDetail extends AgentSessionSummary {
186
216
  turns: AgentTurn[];
217
+ totalTurnCount?: number | null;
218
+ }
219
+
220
+ export interface ReadAgentSessionOptions {
221
+ limit?: number;
222
+ beforeTurnId?: string | null;
223
+ localThreadId?: string;
224
+ workspacePath?: string;
187
225
  }
188
226
 
189
227
  export interface StartAgentSessionInput {
@@ -214,12 +252,15 @@ export interface ResumeAgentSessionInput {
214
252
  export interface StartAgentTurnInput {
215
253
  providerSessionId: string;
216
254
  prompt: string;
255
+ displayPrompt?: string | null;
217
256
  model?: string | null;
218
257
  reasoningEffort?: string | null;
219
258
  collaborationMode?: 'default' | 'plan' | null;
220
259
  sandboxMode?: 'read-only' | 'workspace-write' | 'danger-full-access' | null;
221
260
  workspacePath?: string | null;
222
261
  performanceMode?: 'standard' | 'fast' | null;
262
+ hidden?: boolean;
263
+ displayTurnId?: string | null;
223
264
  }
224
265
 
225
266
  export interface SendAgentInputInput {
@@ -455,6 +496,7 @@ export interface AgentActionQuestion {
455
496
  id: string;
456
497
  header: string;
457
498
  question: string;
499
+ multiSelect?: boolean;
458
500
  isOther: boolean;
459
501
  isSecret: boolean;
460
502
  options: AgentActionQuestionOption[] | null;
@@ -495,6 +537,7 @@ export interface AgentRuntime extends EventEmitter {
495
537
  readonly description: string;
496
538
  readonly capabilities: AgentProviderCapabilities;
497
539
  readonly managementSchema: AgentRuntimeManagementSchema;
540
+ readonly installation: AgentBackendInstallationDto;
498
541
 
499
542
  getStatus(): AgentRuntimeStatus;
500
543
  start(): Promise<void>;
@@ -503,7 +546,10 @@ export interface AgentRuntime extends EventEmitter {
503
546
  listModels(): Promise<AgentModel[]>;
504
547
  listSessions(): Promise<AgentSessionSummary[]>;
505
548
  listLoadedSessions(): Promise<string[]>;
506
- readSession(providerSessionId: string): Promise<AgentSessionDetail>;
549
+ readSession(
550
+ providerSessionId: string,
551
+ options?: ReadAgentSessionOptions,
552
+ ): Promise<AgentSessionDetail>;
507
553
  startSession(input: StartAgentSessionInput): Promise<StartAgentSessionResult>;
508
554
  resumeSession(input: ResumeAgentSessionInput): Promise<StartAgentSessionResult>;
509
555