@pellux/goodvibes-agent 1.1.3 → 1.1.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.
- package/CHANGELOG.md +13 -0
- package/dist/package/main.js +1780 -939
- package/package.json +1 -1
- package/src/input/agent-workspace-activation.ts +21 -1
- package/src/input/agent-workspace-basic-command-editors.ts +8 -9
- package/src/input/agent-workspace-categories.ts +263 -115
- package/src/input/agent-workspace-category-actions.ts +25 -0
- package/src/input/agent-workspace-host-category.ts +57 -0
- package/src/input/agent-workspace-local-editor-submission.ts +193 -0
- package/src/input/agent-workspace-search.ts +6 -0
- package/src/input/agent-workspace-settings.ts +314 -0
- package/src/input/agent-workspace-setup.ts +20 -0
- package/src/input/agent-workspace-snapshot.ts +89 -0
- package/src/input/agent-workspace-subscription-editor.ts +214 -0
- package/src/input/agent-workspace-types.ts +56 -1
- package/src/input/agent-workspace.ts +139 -164
- package/src/input/handler-modal-token-routes.ts +12 -12
- package/src/input/handler.ts +2 -1
- package/src/main.ts +11 -7
- package/src/renderer/agent-workspace.ts +80 -14
- package/src/shell/agent-workspace-fullscreen.ts +11 -3
- package/src/tools/agent-harness-ui-surface-metadata.ts +1 -1
- package/src/tools/agent-harness-workspace-actions.ts +2 -2
- package/src/version.ts +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { basename, sep } from 'node:path';
|
|
2
|
+
import { listAvailableSubscriptionProviders } from '@pellux/goodvibes-sdk/platform/config';
|
|
2
3
|
import type { MemoryRecord } from '@pellux/goodvibes-sdk/platform/state';
|
|
3
4
|
import type { CommandContext } from './command-registry.ts';
|
|
4
5
|
import { AgentNoteRegistry, type AgentNoteRecord } from '../agent/note-registry.ts';
|
|
@@ -398,6 +399,41 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
398
399
|
const ttsVoice = readConfigString(context, 'tts.voice', '(voice default)');
|
|
399
400
|
const ttsLlmProvider = readConfigString(context, 'tts.llmProvider', '');
|
|
400
401
|
const ttsLlmModel = readConfigString(context, 'tts.llmModel', '');
|
|
402
|
+
const embeddingProvider = readConfigString(context, 'provider.embeddingProvider', '(provider default)');
|
|
403
|
+
const reasoningEffort = readConfigString(context, 'provider.reasoningEffort', '(default)');
|
|
404
|
+
const helperEnabled = readConfigBoolean(context, 'helper.enabled', false);
|
|
405
|
+
const toolLlmEnabled = readConfigBoolean(context, 'tools.llmEnabled', false);
|
|
406
|
+
const providerFailureHints = readConfigBoolean(context, 'behavior.suggestAlternativeOnProviderFail', false);
|
|
407
|
+
const cacheEnabled = readConfigBoolean(context, 'cache.enabled', true);
|
|
408
|
+
const cacheStableTtl = readConfigString(context, 'cache.stableTtl', '(default)');
|
|
409
|
+
const cacheMonitorHitRate = readConfigBoolean(context, 'cache.monitorHitRate', true);
|
|
410
|
+
const cacheHitRateWarningThreshold = readConfigNumber(context, 'cache.hitRateWarningThreshold', 0.3);
|
|
411
|
+
const hitlMode = readConfigString(context, 'behavior.hitlMode', '(default)');
|
|
412
|
+
const guidanceMode = readConfigString(context, 'behavior.guidanceMode', '(default)');
|
|
413
|
+
const saveHistory = readConfigBoolean(context, 'behavior.saveHistory', true);
|
|
414
|
+
const autoApprove = readConfigBoolean(context, 'behavior.autoApprove', false);
|
|
415
|
+
const autoCompactThreshold = readConfigNumber(context, 'behavior.autoCompactThreshold', 0);
|
|
416
|
+
const staleContextWarnings = readConfigBoolean(context, 'behavior.staleContextWarnings', false);
|
|
417
|
+
const showThinking = readConfigBoolean(context, 'display.showThinking', false);
|
|
418
|
+
const showReasoningSummary = readConfigBoolean(context, 'display.showReasoningSummary', false);
|
|
419
|
+
const theme = readConfigString(context, 'display.theme', '(default)');
|
|
420
|
+
const stream = readConfigBoolean(context, 'display.stream', true);
|
|
421
|
+
const lineNumbers = readConfigString(context, 'display.lineNumbers', '(default)');
|
|
422
|
+
const operationalMessages = readConfigString(context, 'ui.operationalMessages', '(default)');
|
|
423
|
+
const systemMessages = readConfigString(context, 'ui.systemMessages', '(default)');
|
|
424
|
+
const releaseChannel = readConfigString(context, 'release.channel', '(default)');
|
|
425
|
+
const permissionMode = readConfigString(context, 'permissions.mode', '(default)');
|
|
426
|
+
const toolAutoHeal = readConfigBoolean(context, 'tools.autoHeal', false);
|
|
427
|
+
const toolsDefaultTokenBudget = readConfigNumber(context, 'tools.defaultTokenBudget', 5000);
|
|
428
|
+
const artifactMaxBytes = readConfigNumber(context, 'storage.artifacts.maxBytes', 512 * 1024 * 1024);
|
|
429
|
+
const rawPromptTelemetry = readConfigBoolean(context, 'telemetry.includeRawPrompts', false);
|
|
430
|
+
const automationEnabled = readConfigBoolean(context, 'automation.enabled', false);
|
|
431
|
+
const automationMaxConcurrentRuns = readConfigNumber(context, 'automation.maxConcurrentRuns', 4);
|
|
432
|
+
const automationRunHistoryLimit = readConfigNumber(context, 'automation.runHistoryLimit', 100);
|
|
433
|
+
const automationDefaultTimeoutMs = readConfigNumber(context, 'automation.defaultTimeoutMs', 15 * 60 * 1000);
|
|
434
|
+
const automationCatchUpWindowMinutes = readConfigNumber(context, 'automation.catchUpWindowMinutes', 30);
|
|
435
|
+
const automationFailureCooldownMs = readConfigNumber(context, 'automation.failureCooldownMs', 5 * 60 * 1000);
|
|
436
|
+
const automationDeleteAfterRun = readConfigBoolean(context, 'automation.deleteAfterRun', false);
|
|
401
437
|
const runtimeBaseUrl = `http://${host}:${port}`;
|
|
402
438
|
const companionAccess = (() => {
|
|
403
439
|
const homeDirectory = context.workspace?.shellPaths?.homeDirectory ?? '';
|
|
@@ -425,6 +461,18 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
425
461
|
nextStep,
|
|
426
462
|
} as const;
|
|
427
463
|
})();
|
|
464
|
+
const subscriptionSnapshot = (() => {
|
|
465
|
+
try {
|
|
466
|
+
const manager = context.platform?.subscriptionManager;
|
|
467
|
+
const services = context.platform?.serviceRegistry;
|
|
468
|
+
const active = manager?.list?.().length ?? 0;
|
|
469
|
+
const pending = manager?.listPending?.().length ?? 0;
|
|
470
|
+
const available = services ? listAvailableSubscriptionProviders(services.getAll()).length : 0;
|
|
471
|
+
return { active, pending, available };
|
|
472
|
+
} catch {
|
|
473
|
+
return { active: 0, pending: 0, available: 0 };
|
|
474
|
+
}
|
|
475
|
+
})();
|
|
428
476
|
const channels = buildAgentWorkspaceChannels(context);
|
|
429
477
|
const voiceMediaReadiness = buildAgentWorkspaceVoiceMediaReadiness({
|
|
430
478
|
context,
|
|
@@ -435,6 +483,9 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
435
483
|
provider,
|
|
436
484
|
model,
|
|
437
485
|
runtimeBaseUrl,
|
|
486
|
+
activeSubscriptionCount: subscriptionSnapshot.active,
|
|
487
|
+
pendingSubscriptionCount: subscriptionSnapshot.pending,
|
|
488
|
+
availableSubscriptionProviderCount: subscriptionSnapshot.available,
|
|
438
489
|
sessionMemoryCount,
|
|
439
490
|
localMemoryCount: memorySnapshot.count,
|
|
440
491
|
localMemoryReviewQueueCount: memorySnapshot.reviewQueueCount,
|
|
@@ -463,11 +514,49 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
463
514
|
provider,
|
|
464
515
|
model,
|
|
465
516
|
modelDisplayName: currentModel?.displayName ?? model,
|
|
517
|
+
embeddingProvider,
|
|
518
|
+
reasoningEffort,
|
|
519
|
+
helperEnabled,
|
|
520
|
+
toolLlmEnabled,
|
|
521
|
+
providerFailureHints,
|
|
522
|
+
cacheEnabled,
|
|
523
|
+
cacheStableTtl,
|
|
524
|
+
cacheMonitorHitRate,
|
|
525
|
+
cacheHitRateWarningThreshold,
|
|
526
|
+
hitlMode,
|
|
527
|
+
guidanceMode,
|
|
528
|
+
saveHistory,
|
|
529
|
+
autoApprove,
|
|
530
|
+
autoCompactThreshold,
|
|
531
|
+
staleContextWarnings,
|
|
532
|
+
showThinking,
|
|
533
|
+
showReasoningSummary,
|
|
534
|
+
theme,
|
|
535
|
+
stream,
|
|
536
|
+
lineNumbers,
|
|
537
|
+
operationalMessages,
|
|
538
|
+
systemMessages,
|
|
539
|
+
releaseChannel,
|
|
540
|
+
permissionMode,
|
|
541
|
+
toolAutoHeal,
|
|
542
|
+
toolsDefaultTokenBudget,
|
|
543
|
+
artifactMaxBytes,
|
|
544
|
+
rawPromptTelemetry,
|
|
545
|
+
automationEnabled,
|
|
546
|
+
automationMaxConcurrentRuns,
|
|
547
|
+
automationRunHistoryLimit,
|
|
548
|
+
automationDefaultTimeoutMs,
|
|
549
|
+
automationCatchUpWindowMinutes,
|
|
550
|
+
automationFailureCooldownMs,
|
|
551
|
+
automationDeleteAfterRun,
|
|
466
552
|
sessionId: context.session?.runtime?.sessionId ?? 'unknown',
|
|
467
553
|
workingDirectory: context.workspace?.shellPaths?.workingDirectory ?? 'unavailable',
|
|
468
554
|
homeDirectory: context.workspace?.shellPaths?.homeDirectory ?? 'unavailable',
|
|
469
555
|
runtimeBaseUrl,
|
|
470
556
|
runtimeOwnership: 'external',
|
|
557
|
+
activeSubscriptionCount: subscriptionSnapshot.active,
|
|
558
|
+
pendingSubscriptionCount: subscriptionSnapshot.pending,
|
|
559
|
+
availableSubscriptionProviderCount: subscriptionSnapshot.available,
|
|
471
560
|
sessionMemoryCount,
|
|
472
561
|
localMemoryCount: memorySnapshot.count,
|
|
473
562
|
localMemoryReviewQueueCount: memorySnapshot.reviewQueueCount,
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { beginOpenAICodexLogin, exchangeOpenAICodexCode, getSubscriptionProviderConfig } from '@pellux/goodvibes-sdk/platform/config';
|
|
2
|
+
import type { OAuthProviderConfig, ProviderSubscription } from '@pellux/goodvibes-sdk/platform/config';
|
|
3
|
+
import { openExternalUrl } from '@pellux/goodvibes-sdk/platform/utils';
|
|
4
|
+
import type { CommandContext } from './command-registry.ts';
|
|
5
|
+
import { isAffirmative } from './agent-workspace-editors.ts';
|
|
6
|
+
import { buildAgentWorkspaceRuntimeSnapshot } from './agent-workspace-snapshot.ts';
|
|
7
|
+
import type { AgentWorkspaceActionResult, AgentWorkspaceLocalEditor, AgentWorkspaceRuntimeSnapshot } from './agent-workspace-types.ts';
|
|
8
|
+
|
|
9
|
+
export interface AgentWorkspaceSubscriptionEditorHost {
|
|
10
|
+
localEditor: AgentWorkspaceLocalEditor | null;
|
|
11
|
+
runtimeSnapshot: AgentWorkspaceRuntimeSnapshot | null;
|
|
12
|
+
status: string;
|
|
13
|
+
lastActionResult: AgentWorkspaceActionResult | null;
|
|
14
|
+
clampSelection(): void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type AgentWorkspaceSubscriptionFieldReader = (id: string) => string;
|
|
18
|
+
|
|
19
|
+
export async function submitAgentWorkspaceSubscriptionLoginStartEditor(
|
|
20
|
+
host: AgentWorkspaceSubscriptionEditorHost,
|
|
21
|
+
editor: AgentWorkspaceLocalEditor,
|
|
22
|
+
context: CommandContext | null,
|
|
23
|
+
readField: AgentWorkspaceSubscriptionFieldReader,
|
|
24
|
+
): Promise<void> {
|
|
25
|
+
if (!isAffirmative(readField('confirm'))) {
|
|
26
|
+
host.localEditor = { ...editor, message: 'Subscription login start not confirmed. Type yes, then press Enter.' };
|
|
27
|
+
host.status = 'Subscription login start not confirmed.';
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const provider = readField('provider') || 'openai';
|
|
32
|
+
const openBrowser = isAffirmative(readField('openBrowser'));
|
|
33
|
+
const { manager, services } = subscriptionServices(context);
|
|
34
|
+
const resolved = getSubscriptionProviderConfig(provider, services.get(provider));
|
|
35
|
+
if (!resolved) {
|
|
36
|
+
throw new Error(`OAuth is not configured for ${provider}. Add an OAuth provider service or choose a built-in subscription provider.`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const started = provider === 'openai' && resolved.source === 'builtin'
|
|
40
|
+
? await beginOpenAICodexLogin()
|
|
41
|
+
: null;
|
|
42
|
+
const authorizationUrl = started
|
|
43
|
+
? started.authorizationUrl
|
|
44
|
+
: (await manager.beginOAuthLogin(provider, resolveManualLoginConfig(resolved.oauth))).authorizationUrl;
|
|
45
|
+
|
|
46
|
+
if (started) {
|
|
47
|
+
manager.savePending({
|
|
48
|
+
provider,
|
|
49
|
+
state: started.state,
|
|
50
|
+
verifier: started.verifier,
|
|
51
|
+
redirectUri: started.redirectUri,
|
|
52
|
+
createdAt: Date.now(),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const browserOpened = openBrowser ? await openExternalUrl(authorizationUrl) : false;
|
|
57
|
+
host.localEditor = null;
|
|
58
|
+
host.runtimeSnapshot = context ? buildAgentWorkspaceRuntimeSnapshot(context) : host.runtimeSnapshot;
|
|
59
|
+
host.status = `Subscription login started for ${provider}.`;
|
|
60
|
+
host.lastActionResult = {
|
|
61
|
+
kind: 'refreshed',
|
|
62
|
+
title: 'Subscription login started',
|
|
63
|
+
detail: [
|
|
64
|
+
`Provider: ${provider}.`,
|
|
65
|
+
`Browser: ${openBrowser ? (browserOpened ? 'opened' : 'open failed') : 'skipped'}.`,
|
|
66
|
+
'Use Finish subscription login with the callback code or redirect URL.',
|
|
67
|
+
`Authorization URL: ${authorizationUrl}`,
|
|
68
|
+
].join(' '),
|
|
69
|
+
safety: 'safe',
|
|
70
|
+
};
|
|
71
|
+
host.clampSelection();
|
|
72
|
+
} catch (error) {
|
|
73
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
74
|
+
host.localEditor = { ...editor, message: detail };
|
|
75
|
+
host.status = detail;
|
|
76
|
+
host.lastActionResult = { kind: 'error', title: 'Subscription login start failed', detail, safety: 'safe' };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export async function submitAgentWorkspaceSubscriptionLoginFinishEditor(
|
|
81
|
+
host: AgentWorkspaceSubscriptionEditorHost,
|
|
82
|
+
editor: AgentWorkspaceLocalEditor,
|
|
83
|
+
context: CommandContext | null,
|
|
84
|
+
readField: AgentWorkspaceSubscriptionFieldReader,
|
|
85
|
+
): Promise<void> {
|
|
86
|
+
if (!isAffirmative(readField('confirm'))) {
|
|
87
|
+
host.localEditor = { ...editor, message: 'Subscription login finish not confirmed. Type yes, then press Enter.' };
|
|
88
|
+
host.status = 'Subscription login finish not confirmed.';
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
const provider = readField('provider') || 'openai';
|
|
93
|
+
const codeInput = readField('code');
|
|
94
|
+
const code = extractAuthorizationCode(codeInput) ?? codeInput;
|
|
95
|
+
const { manager, services } = subscriptionServices(context);
|
|
96
|
+
const resolved = getSubscriptionProviderConfig(provider, services.get(provider));
|
|
97
|
+
if (!resolved) {
|
|
98
|
+
throw new Error(`OAuth is not configured for ${provider}. Start with a configured or built-in subscription provider.`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const record = provider === 'openai' && resolved.source === 'builtin'
|
|
102
|
+
? (() => {
|
|
103
|
+
const pending = manager.getPending(provider);
|
|
104
|
+
if (!pending) throw new Error(`No pending OAuth login for ${provider}. Start subscription login first.`);
|
|
105
|
+
return exchangeOpenAICodexCode(code, pending.verifier).then((token) => {
|
|
106
|
+
const now = Date.now();
|
|
107
|
+
return manager.saveSubscription({
|
|
108
|
+
provider,
|
|
109
|
+
accessToken: token.accessToken,
|
|
110
|
+
tokenType: token.tokenType,
|
|
111
|
+
...(typeof token.refreshToken === 'string' && token.refreshToken.length > 0
|
|
112
|
+
? { refreshToken: token.refreshToken }
|
|
113
|
+
: {}),
|
|
114
|
+
...(typeof token.expiresAt === 'number' && Number.isFinite(token.expiresAt)
|
|
115
|
+
? { expiresAt: token.expiresAt }
|
|
116
|
+
: {}),
|
|
117
|
+
...(token.scopes ? { scopes: token.scopes } : {}),
|
|
118
|
+
authMode: 'oauth',
|
|
119
|
+
overrideAmbientApiKeys: false,
|
|
120
|
+
createdAt: manager.get(provider)?.createdAt ?? now,
|
|
121
|
+
updatedAt: now,
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
})()
|
|
125
|
+
: manager.completeOAuthLogin(provider, resolveManualLoginConfig(resolved.oauth), code);
|
|
126
|
+
|
|
127
|
+
const saved = await record;
|
|
128
|
+
host.localEditor = null;
|
|
129
|
+
host.runtimeSnapshot = context ? buildAgentWorkspaceRuntimeSnapshot(context) : host.runtimeSnapshot;
|
|
130
|
+
host.status = `Subscription session saved for ${provider}.`;
|
|
131
|
+
host.lastActionResult = {
|
|
132
|
+
kind: 'refreshed',
|
|
133
|
+
title: 'Subscription session saved',
|
|
134
|
+
detail: [
|
|
135
|
+
`Provider: ${provider}.`,
|
|
136
|
+
`Token type: ${saved.tokenType}.`,
|
|
137
|
+
`Expires: ${saved.expiresAt ? new Date(saved.expiresAt).toISOString() : 'n/a'}.`,
|
|
138
|
+
describeSubscriptionPrecedence(saved),
|
|
139
|
+
].join(' '),
|
|
140
|
+
safety: 'safe',
|
|
141
|
+
};
|
|
142
|
+
host.clampSelection();
|
|
143
|
+
} catch (error) {
|
|
144
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
145
|
+
host.localEditor = { ...editor, message: detail };
|
|
146
|
+
host.status = detail;
|
|
147
|
+
host.lastActionResult = { kind: 'error', title: 'Subscription login finish failed', detail, safety: 'safe' };
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function submitAgentWorkspaceSubscriptionLogoutEditor(
|
|
152
|
+
host: AgentWorkspaceSubscriptionEditorHost,
|
|
153
|
+
editor: AgentWorkspaceLocalEditor,
|
|
154
|
+
context: CommandContext | null,
|
|
155
|
+
readField: AgentWorkspaceSubscriptionFieldReader,
|
|
156
|
+
): void {
|
|
157
|
+
if (!isAffirmative(readField('confirm'))) {
|
|
158
|
+
host.localEditor = { ...editor, message: 'Subscription logout not confirmed. Type yes, then press Enter.' };
|
|
159
|
+
host.status = 'Subscription logout not confirmed.';
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
try {
|
|
163
|
+
const provider = readField('provider') || 'openai';
|
|
164
|
+
const { manager } = subscriptionServices(context);
|
|
165
|
+
const removed = manager.logout(provider);
|
|
166
|
+
host.localEditor = null;
|
|
167
|
+
host.runtimeSnapshot = context ? buildAgentWorkspaceRuntimeSnapshot(context) : host.runtimeSnapshot;
|
|
168
|
+
host.status = removed ? `Logged out of ${provider}.` : `No subscription session existed for ${provider}.`;
|
|
169
|
+
host.lastActionResult = {
|
|
170
|
+
kind: removed ? 'refreshed' : 'guidance',
|
|
171
|
+
title: removed ? 'Subscription session removed' : 'No subscription session found',
|
|
172
|
+
detail: removed
|
|
173
|
+
? `Removed active or pending subscription state for ${provider}. Ambient API key resolution applies if configured.`
|
|
174
|
+
: `No active or pending subscription state existed for ${provider}.`,
|
|
175
|
+
safety: 'safe',
|
|
176
|
+
};
|
|
177
|
+
host.clampSelection();
|
|
178
|
+
} catch (error) {
|
|
179
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
180
|
+
host.localEditor = { ...editor, message: detail };
|
|
181
|
+
host.status = detail;
|
|
182
|
+
host.lastActionResult = { kind: 'error', title: 'Subscription logout failed', detail, safety: 'safe' };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function subscriptionServices(context: CommandContext | null) {
|
|
187
|
+
const manager = context?.platform.subscriptionManager;
|
|
188
|
+
const services = context?.platform.serviceRegistry;
|
|
189
|
+
if (!manager || !services) throw new Error('Subscription services are unavailable in this runtime.');
|
|
190
|
+
return { manager, services };
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function extractAuthorizationCode(input: string): string | null {
|
|
194
|
+
const trimmed = input.trim();
|
|
195
|
+
if (!trimmed) return null;
|
|
196
|
+
try {
|
|
197
|
+
const url = new URL(trimmed);
|
|
198
|
+
return url.searchParams.get('code');
|
|
199
|
+
} catch {
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function resolveManualLoginConfig(config: OAuthProviderConfig): OAuthProviderConfig {
|
|
205
|
+
return config.manualRedirectUri
|
|
206
|
+
? { ...config, redirectUri: config.manualRedirectUri }
|
|
207
|
+
: config;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function describeSubscriptionPrecedence(record: Pick<ProviderSubscription, 'overrideAmbientApiKeys'>): string {
|
|
211
|
+
return record.overrideAmbientApiKeys
|
|
212
|
+
? 'Subscription routing now overrides ambient API keys for this provider.'
|
|
213
|
+
: 'Subscription session is stored for subscription-backed flows; ambient API keys are unchanged.';
|
|
214
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ModelPickerTarget } from './model-picker.ts';
|
|
1
2
|
import type { AgentWorkspaceChannelStatus } from './agent-workspace-channels.ts';
|
|
2
3
|
import type { AgentWorkspaceSetupChecklistItem } from './agent-workspace-setup.ts';
|
|
3
4
|
import type { AgentWorkspaceVoiceMediaReadiness } from './agent-workspace-voice-media.ts';
|
|
@@ -10,6 +11,14 @@ export type AgentWorkspaceFocusPane = 'categories' | 'actions';
|
|
|
10
11
|
export const AGENT_WORKSPACE_CATEGORY_IDS = [
|
|
11
12
|
'home',
|
|
12
13
|
'setup',
|
|
14
|
+
'account-model',
|
|
15
|
+
'assistant-behavior',
|
|
16
|
+
'tools-permissions',
|
|
17
|
+
'onboarding-display',
|
|
18
|
+
'onboarding-channels',
|
|
19
|
+
'onboarding-voice-media',
|
|
20
|
+
'onboarding-context',
|
|
21
|
+
'onboarding-automation',
|
|
13
22
|
'research',
|
|
14
23
|
'artifacts',
|
|
15
24
|
'conversation',
|
|
@@ -32,7 +41,7 @@ export const AGENT_WORKSPACE_CATEGORY_IDS = [
|
|
|
32
41
|
|
|
33
42
|
export type AgentWorkspaceCategoryId = (typeof AGENT_WORKSPACE_CATEGORY_IDS)[number];
|
|
34
43
|
|
|
35
|
-
export type AgentWorkspaceActionKind = 'command' | 'guidance' | 'workspace' | 'editor' | 'local-selection' | 'local-operation' | 'onboarding-complete';
|
|
44
|
+
export type AgentWorkspaceActionKind = 'command' | 'guidance' | 'workspace' | 'editor' | 'setting' | 'settings-import' | 'model-picker' | 'settings-modal' | 'local-selection' | 'local-operation' | 'onboarding-complete';
|
|
36
45
|
|
|
37
46
|
export type AgentWorkspaceLocalEditorKind = 'memory' | 'note' | 'persona' | 'skill' | 'routine' | 'profile';
|
|
38
47
|
|
|
@@ -178,6 +187,7 @@ export type AgentWorkspaceEditorKind =
|
|
|
178
187
|
| 'schedule-receipt'
|
|
179
188
|
| 'mode-preset'
|
|
180
189
|
| 'mode-domain'
|
|
190
|
+
| 'setting-set'
|
|
181
191
|
| 'model-pin'
|
|
182
192
|
| 'model-unpin'
|
|
183
193
|
| 'delegate-task'
|
|
@@ -247,6 +257,13 @@ export interface AgentWorkspaceAction {
|
|
|
247
257
|
readonly command?: string;
|
|
248
258
|
readonly targetCategoryId?: AgentWorkspaceCategoryId;
|
|
249
259
|
readonly editorKind?: AgentWorkspaceEditorKind;
|
|
260
|
+
readonly settingKey?: string;
|
|
261
|
+
readonly settingValueHint?: string;
|
|
262
|
+
readonly modelPickerTarget?: ModelPickerTarget;
|
|
263
|
+
readonly modelPickerFlow?: 'providerModel' | 'model';
|
|
264
|
+
readonly settingsTarget?: string;
|
|
265
|
+
readonly visibleWhenSettingKey?: string;
|
|
266
|
+
readonly visibleWhenSettingValue?: string | boolean | number;
|
|
250
267
|
readonly localKind?: AgentWorkspaceLocalEditorKind;
|
|
251
268
|
readonly selectionDelta?: number;
|
|
252
269
|
readonly localOperation?: AgentWorkspaceLocalOperation;
|
|
@@ -349,11 +366,49 @@ export interface AgentWorkspaceRuntimeSnapshot {
|
|
|
349
366
|
readonly provider: string;
|
|
350
367
|
readonly model: string;
|
|
351
368
|
readonly modelDisplayName: string;
|
|
369
|
+
readonly embeddingProvider: string;
|
|
370
|
+
readonly reasoningEffort: string;
|
|
371
|
+
readonly helperEnabled: boolean;
|
|
372
|
+
readonly toolLlmEnabled: boolean;
|
|
373
|
+
readonly providerFailureHints: boolean;
|
|
374
|
+
readonly cacheEnabled: boolean;
|
|
375
|
+
readonly cacheStableTtl: string;
|
|
376
|
+
readonly cacheMonitorHitRate: boolean;
|
|
377
|
+
readonly cacheHitRateWarningThreshold: number;
|
|
378
|
+
readonly hitlMode: string;
|
|
379
|
+
readonly guidanceMode: string;
|
|
380
|
+
readonly saveHistory: boolean;
|
|
381
|
+
readonly autoApprove: boolean;
|
|
382
|
+
readonly autoCompactThreshold: number;
|
|
383
|
+
readonly staleContextWarnings: boolean;
|
|
384
|
+
readonly showThinking: boolean;
|
|
385
|
+
readonly showReasoningSummary: boolean;
|
|
386
|
+
readonly theme: string;
|
|
387
|
+
readonly stream: boolean;
|
|
388
|
+
readonly lineNumbers: string;
|
|
389
|
+
readonly operationalMessages: string;
|
|
390
|
+
readonly systemMessages: string;
|
|
391
|
+
readonly releaseChannel: string;
|
|
392
|
+
readonly permissionMode: string;
|
|
393
|
+
readonly toolAutoHeal: boolean;
|
|
394
|
+
readonly toolsDefaultTokenBudget: number;
|
|
395
|
+
readonly artifactMaxBytes: number;
|
|
396
|
+
readonly rawPromptTelemetry: boolean;
|
|
397
|
+
readonly automationEnabled: boolean;
|
|
398
|
+
readonly automationMaxConcurrentRuns: number;
|
|
399
|
+
readonly automationRunHistoryLimit: number;
|
|
400
|
+
readonly automationDefaultTimeoutMs: number;
|
|
401
|
+
readonly automationCatchUpWindowMinutes: number;
|
|
402
|
+
readonly automationFailureCooldownMs: number;
|
|
403
|
+
readonly automationDeleteAfterRun: boolean;
|
|
352
404
|
readonly sessionId: string;
|
|
353
405
|
readonly workingDirectory: string;
|
|
354
406
|
readonly homeDirectory: string;
|
|
355
407
|
readonly runtimeBaseUrl: string;
|
|
356
408
|
readonly runtimeOwnership: 'external';
|
|
409
|
+
readonly activeSubscriptionCount: number;
|
|
410
|
+
readonly pendingSubscriptionCount: number;
|
|
411
|
+
readonly availableSubscriptionProviderCount: number;
|
|
357
412
|
readonly sessionMemoryCount: number;
|
|
358
413
|
readonly localMemoryCount: number;
|
|
359
414
|
readonly localMemoryReviewQueueCount: number;
|