Skip to content

Commit 36d1d61

Browse files
committed
In progress
1 parent d662413 commit 36d1d61

8 files changed

Lines changed: 11 additions & 155 deletions

File tree

‎apps/cli/ai/output-adapter.ts‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,7 @@ export class JsonAdapter implements AiOutputAdapter {
158158
}
159159

160160
async collectPassword( question: string ): Promise< string | null > {
161-
const answers = await this.askUser( [ { question, options: [], inputType: 'password' } ] );
162-
return Object.values( answers )[ 0 ] ?? null;
161+
throw new Error( `collectPassword is not available in JSON mode: ${ question }` );
163162
}
164163

165164
async askUser( questions: AskUserQuestion[] ): Promise< Record< string, string > > {
@@ -177,7 +176,6 @@ export class JsonAdapter implements AiOutputAdapter {
177176
questions: questions.map( ( q ) => ( {
178177
question: q.question,
179178
options: q.options,
180-
inputType: q.inputType,
181179
} ) ),
182180
} );
183181

‎apps/cli/ai/types.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ export interface AskUserQuestion {
22
question: string;
33
options: { label: string; description: string }[];
44
allowFreeForm?: boolean;
5-
inputType?: 'password';
65
}
76

87
export type AskUserHandler = (

‎apps/cli/commands/ai/index.ts‎

Lines changed: 9 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import { buildSkillInvocationPrompt } from '@studio/common/ai/slash-commands';
44
import { readAuthToken } from '@studio/common/lib/shared-config';
55
import { __, sprintf } from '@wordpress/i18n';
66
import {
7-
getAvailableAiProviders,
8-
isAiProviderReady,
97
prepareAiProvider,
108
resolveAiEnvironment,
119
resolveInitialAiProvider,
@@ -29,7 +27,6 @@ import { replaySessionHistory } from 'cli/ai/sessions/replay';
2927
import { setLocalSiteSelectedCallback } from 'cli/ai/site-selection';
3028
import { getActiveSlashCommands, type SlashCommandContext } from 'cli/ai/slash-commands';
3129
import { AiChatUI } from 'cli/ai/ui';
32-
import { runCommand as runLoginCommand } from 'cli/commands/auth/login';
3330
import { readCliConfig } from 'cli/lib/cli-config/core';
3431
import { findSiteByFolder } from 'cli/lib/cli-config/sites';
3532
import { Logger, LoggerError, setProgressCallback } from 'cli/logger';
@@ -55,13 +52,6 @@ function appendStudioEntry< T extends StudioCustomEntryType >(
5552
return sm.appendCustomEntry( customType, data );
5653
}
5754

58-
function isPromptAbortError( error: unknown ): boolean {
59-
return (
60-
error instanceof Error &&
61-
[ 'AbortPromptError', 'CancelPromptError', 'ExitPromptError' ].includes( error.name )
62-
);
63-
}
64-
6555
function getErrorMessage( error: unknown ): string {
6656
if ( error instanceof Error ) {
6757
return error.message;
@@ -96,12 +86,9 @@ export async function runCommand( options: {
9686
} ): Promise< void > {
9787
const ui = options.adapter;
9888
const isJsonMode = ui instanceof JsonAdapter;
99-
const isStudioAppMode = isJsonMode && typeof process.send === 'function';
100-
const config = await readCliConfig();
10189
const resumeContext = resolveResumeSessionContext( options.resumeSession );
102-
let currentProvider: AiProviderId = isStudioAppMode
103-
? 'wpcom'
104-
: resumeContext.provider ?? ( await resolveInitialAiProvider() );
90+
let currentProvider: AiProviderId =
91+
resumeContext.provider ?? ( await resolveInitialAiProvider() );
10592
let currentModel: AiModelId = resumeContext.model ?? DEFAULT_MODEL;
10693
ui.currentProvider = currentProvider;
10794
ui.currentModel = currentModel;
@@ -272,10 +259,6 @@ export async function runCommand( options: {
272259
}
273260

274261
async function maybeAutoSwitchProvider(): Promise< void > {
275-
if ( isStudioAppMode ) {
276-
return;
277-
}
278-
279262
const fallbackProvider = await resolveUnavailableAiProvider( currentProvider );
280263
if ( ! fallbackProvider || fallbackProvider === currentProvider ) {
281264
return;
@@ -314,79 +297,16 @@ export async function runCommand( options: {
314297
}
315298
}
316299

317-
if ( isStudioAppMode && ! config.aiProvider ) {
318-
await saveSelectedAiProvider( 'wpcom' );
319-
}
320-
321-
let showCapabilitiesOnConnect = ! config.aiProvider && ! isStudioAppMode;
300+
const config = await readCliConfig();
301+
let showCapabilitiesOnConnect = ! config.aiProvider;
322302

323303
if ( showCapabilitiesOnConnect ) {
304+
currentProvider = 'wpcom';
305+
ui.currentProvider = currentProvider;
306+
await saveSelectedAiProvider( currentProvider );
324307
ui.showOnboarding();
325-
326-
// Auto-trigger provider selection on first run
327-
const availableProviders = await getAvailableAiProviders();
328-
const labelToProvider = new Map< string, AiProviderId >();
329-
const providerOptions = availableProviders.map( ( id ) => {
330-
const label = id === 'wpcom' ? __( 'WordPress.com (recommended)' ) : AI_PROVIDERS[ id ];
331-
labelToProvider.set( label, id );
332-
return { label, description: id };
333-
} );
334-
const answer = await ui.askUser( [
335-
{
336-
question: __( 'Choose how to connect' ),
337-
options: providerOptions,
338-
},
339-
] );
340-
const selectedLabel = Object.values( answer )[ 0 ] as string;
341-
const selectedProvider = labelToProvider.get( selectedLabel );
342-
if ( selectedProvider ) {
343-
try {
344-
if ( selectedProvider === 'wpcom' ) {
345-
// Run login flow directly instead of prepare(), which would
346-
// just throw "login required" since there's no token yet.
347-
ui.stop();
348-
await runLoginCommand();
349-
ui.start();
350-
351-
if ( await isAiProviderReady( 'wpcom' ) ) {
352-
await switchProvider( 'wpcom', false );
353-
const token = await readAuthToken();
354-
if ( token ) {
355-
ui.showSuccess(
356-
sprintf(
357-
/* translators: 1: display name, 2: email */
358-
__( 'Logged in as %1$s (%2$s)' ),
359-
token.displayName,
360-
token.email
361-
)
362-
);
363-
ui.setStatusMessage(
364-
sprintf(
365-
/* translators: %s: display name */
366-
__( 'Logged in as %s' ),
367-
token.displayName
368-
)
369-
);
370-
showCapabilitiesOnConnect = false;
371-
ui.showCapabilities();
372-
}
373-
}
374-
} else {
375-
await prepareProviderSelection( selectedProvider );
376-
await switchProvider( selectedProvider, false );
377-
showCapabilitiesOnConnect = false;
378-
ui.showCapabilities();
379-
}
380-
} catch ( error ) {
381-
if ( ! isPromptAbortError( error ) ) {
382-
if ( error instanceof LoggerError ) {
383-
ui.showError( error.message );
384-
} else {
385-
throw error;
386-
}
387-
}
388-
}
389-
}
308+
showCapabilitiesOnConnect = false;
309+
ui.showCapabilities();
390310
} else if ( currentProvider === 'wpcom' ) {
391311
const token = await readAuthToken();
392312
if ( token ) {

‎apps/studio/src/components/studio-code-session/conversation/index.tsx‎

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ import {
99
} from '@studio/common/ai/tools';
1010
import { __ } from '@wordpress/i18n';
1111
import { useMemo, useState } from 'react';
12-
import Button from 'src/components/button';
13-
import TextControl from 'src/components/text-control';
1412
import { cx } from 'src/lib/cx';
1513
import { Markdown } from '../markdown';
1614
import { ThinkingIndicator } from '../thinking-indicator';
@@ -33,7 +31,6 @@ type RenderItem =
3331
key: string;
3432
question: string;
3533
options: Array< { label: string; description: string } >;
36-
inputType?: 'password';
3734
}
3835
| { kind: 'interrupted-marker'; key: string };
3936

@@ -133,7 +130,6 @@ function entriesToRenderItems( entries: SessionEntry[] ): RenderItem[] {
133130
key: `${ entryIndex }:question`,
134131
question: data.question,
135132
options: data.options,
136-
inputType: data.inputType,
137133
} );
138134
return;
139135
}
@@ -237,54 +233,16 @@ function ToolUseRow( {
237233
function AgentQuestion( {
238234
question,
239235
options,
240-
inputType,
241236
isInteractive,
242237
pickedLabel,
243238
onAnswer,
244239
}: {
245240
question: string;
246241
options: Array< { label: string; description: string } >;
247-
inputType?: 'password';
248242
isInteractive: boolean;
249243
pickedLabel: string | undefined;
250244
onAnswer: ( label: string ) => void;
251245
} ) {
252-
const [ inputValue, setInputValue ] = useState( '' );
253-
254-
if ( inputType === 'password' ) {
255-
return (
256-
<div className={ styles.question }>
257-
<p className={ styles.questionText }>{ question }</p>
258-
{ ! pickedLabel && isInteractive ? (
259-
<form
260-
className={ styles.passwordForm }
261-
onSubmit={ ( e ) => {
262-
e.preventDefault();
263-
if ( inputValue.trim() ) {
264-
onAnswer( inputValue.trim() );
265-
}
266-
} }
267-
>
268-
<TextControl
269-
type="password"
270-
value={ inputValue }
271-
onChange={ setInputValue }
272-
className={ styles.passwordInput }
273-
/>
274-
<Button
275-
type="submit"
276-
variant="primary"
277-
disabled={ ! inputValue.trim() }
278-
style={ { height: '40px' } }
279-
>
280-
{ __( 'Submit' ) }
281-
</Button>
282-
</form>
283-
) : null }
284-
</div>
285-
);
286-
}
287-
288246
return (
289247
<div className={ styles.question }>
290248
<p className={ styles.questionText }>{ question }</p>
@@ -357,7 +315,6 @@ export function Conversation( {
357315
key={ item.key }
358316
question={ item.question }
359317
options={ item.options }
360-
inputType={ item.inputType }
361318
isInteractive={ pendingQuestions.has( item.question ) }
362319
pickedLabel={ pendingAnswers[ item.question ] }
363320
onAnswer={ ( label ) => onAnswerQuestion( item.question, label ) }

‎apps/studio/src/components/studio-code-session/conversation/style.module.css‎

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -158,17 +158,6 @@
158158
opacity: 1;
159159
}
160160

161-
.passwordForm {
162-
display: flex;
163-
gap: var(--wpds-dimension-padding-sm);
164-
align-items: stretch;
165-
}
166-
167-
.passwordInput {
168-
flex: 1;
169-
min-width: 0;
170-
}
171-
172161
.interruptedMarker {
173162
align-self: center;
174163
margin: var(--wpds-dimension-padding-sm) 0;

‎apps/studio/src/components/studio-code-session/use-agent-run.tsx‎

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ function shortEntryId(): string {
3232
export interface PendingQuestion {
3333
question: string;
3434
options: Array< { label: string; description: string } >;
35-
inputType?: 'password';
3635
}
3736

3837
export interface QueuedPrompt {
@@ -424,11 +423,7 @@ export function AgentRunProvider( { children }: PropsWithChildren ) {
424423
parentId: null,
425424
timestamp: event.timestamp,
426425
customType: 'studio.agent_question',
427-
data: {
428-
question: q.question,
429-
options: q.options,
430-
inputType: q.inputType,
431-
},
426+
data: { question: q.question, options: q.options },
432427
} ) as SessionEntry
433428
),
434429
] );

‎tools/common/ai/json-events.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ export type JsonEvent =
3333
questions: Array< {
3434
question: string;
3535
options: Array< { label: string; description: string } >;
36-
inputType?: 'password';
3736
} >;
3837
}
3938
| { type: 'turn.started'; timestamp: string }

‎tools/common/ai/sessions/entry-types.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ export interface StudioToolProgressData {
2929
export interface StudioAgentQuestionData {
3030
question: string;
3131
options: Array< { label: string; description: string } >;
32-
inputType?: 'password';
3332
}
3433

3534
export type StudioTurnStatus = 'success' | 'error' | 'max_turns' | 'interrupted';

0 commit comments

Comments
 (0)