152 lines
4.1 KiB
TypeScript
152 lines
4.1 KiB
TypeScript
import { Session, startAgent, ExtensionConfig } from './api';
|
|
import { DEFAULT_CHAT_TITLE } from './contexts/ChatContext';
|
|
import type { setViewType } from './hooks/useNavigation';
|
|
import type { FixedExtensionEntry } from './components/ConfigContext';
|
|
import { AppEvents } from './constants/events';
|
|
import { USE_ACP_CHAT } from './acpChatFeatureFlag';
|
|
import { acpChatSessionController } from './acp/chatSessionController';
|
|
import { getConfiguredGooseExtensions, gooseExtensionName } from './acp/extensions';
|
|
|
|
export function getSessionDisplayName(session: Session): string {
|
|
if (session.user_set_name) {
|
|
return session.name;
|
|
}
|
|
if (session.recipe?.title) {
|
|
return session.recipe.title;
|
|
}
|
|
if (shouldShowNewChatTitle(session)) {
|
|
return DEFAULT_CHAT_TITLE;
|
|
}
|
|
return session.name;
|
|
}
|
|
|
|
export function shouldShowNewChatTitle(session: Session): boolean {
|
|
return !session.user_set_name && session.message_count === 0 && !session.recipe?.title;
|
|
}
|
|
|
|
export function resumeSession(session: Session, setView: setViewType) {
|
|
const eventDetail = {
|
|
sessionId: session.id,
|
|
initialMessage: undefined,
|
|
};
|
|
|
|
window.dispatchEvent(
|
|
new CustomEvent(AppEvents.ADD_ACTIVE_SESSION, {
|
|
detail: eventDetail,
|
|
})
|
|
);
|
|
|
|
setView('pair', {
|
|
disableAnimation: true,
|
|
resumeSessionId: session.id,
|
|
});
|
|
}
|
|
|
|
interface CreateSessionOptions {
|
|
recipeDeeplink?: string;
|
|
recipeId?: string;
|
|
extensionConfigs?: ExtensionConfig[];
|
|
allExtensions?: FixedExtensionEntry[];
|
|
}
|
|
|
|
function selectedExtensionConfigs(options?: CreateSessionOptions): ExtensionConfig[] {
|
|
if (options?.extensionConfigs && options.extensionConfigs.length > 0) {
|
|
return options.extensionConfigs;
|
|
}
|
|
if (options?.allExtensions) {
|
|
return options.allExtensions
|
|
.filter((extension) => extension.enabled)
|
|
.map((extension) => {
|
|
const { enabled: _enabled, ...config } = extension;
|
|
return config as ExtensionConfig;
|
|
});
|
|
}
|
|
return [];
|
|
}
|
|
|
|
async function createAcpSession(
|
|
workingDir: string,
|
|
options?: CreateSessionOptions
|
|
): Promise<Session> {
|
|
const selectedNames = new Set(selectedExtensionConfigs(options).map((config) => config.name));
|
|
const gooseExtensions =
|
|
selectedNames.size > 0
|
|
? (await getConfiguredGooseExtensions())
|
|
.filter((entry) => selectedNames.has(gooseExtensionName(entry.extension)))
|
|
.map((entry) => entry.extension)
|
|
: [];
|
|
return acpChatSessionController.createSession(workingDir, gooseExtensions, {
|
|
recipeId: options?.recipeId,
|
|
recipeDeeplink: options?.recipeDeeplink,
|
|
});
|
|
}
|
|
|
|
export async function createSession(
|
|
workingDir: string,
|
|
options?: CreateSessionOptions
|
|
): Promise<Session> {
|
|
if (USE_ACP_CHAT) {
|
|
return createAcpSession(workingDir, options);
|
|
}
|
|
|
|
const body: {
|
|
working_dir: string;
|
|
recipe_deeplink?: string;
|
|
recipe_id?: string;
|
|
extension_overrides?: ExtensionConfig[];
|
|
} = {
|
|
working_dir: workingDir,
|
|
};
|
|
|
|
if (options?.recipeId) {
|
|
body.recipe_id = options.recipeId;
|
|
} else if (options?.recipeDeeplink) {
|
|
body.recipe_deeplink = options.recipeDeeplink;
|
|
}
|
|
|
|
const extensionConfigs = selectedExtensionConfigs(options);
|
|
if (extensionConfigs.length > 0) {
|
|
body.extension_overrides = extensionConfigs;
|
|
}
|
|
|
|
const newAgent = await startAgent({
|
|
body,
|
|
throwOnError: true,
|
|
});
|
|
return newAgent.data;
|
|
}
|
|
|
|
export async function startNewSession(
|
|
initialText: string | undefined,
|
|
setView: setViewType,
|
|
workingDir: string,
|
|
options?: {
|
|
recipeDeeplink?: string;
|
|
recipeId?: string;
|
|
allExtensions?: FixedExtensionEntry[];
|
|
}
|
|
): Promise<Session> {
|
|
const session = await createSession(workingDir, options);
|
|
window.dispatchEvent(new CustomEvent(AppEvents.SESSION_CREATED, { detail: { session } }));
|
|
|
|
const initialMessage = initialText ? { msg: initialText, images: [] } : undefined;
|
|
|
|
const eventDetail = {
|
|
sessionId: session.id,
|
|
initialMessage,
|
|
};
|
|
|
|
window.dispatchEvent(
|
|
new CustomEvent(AppEvents.ADD_ACTIVE_SESSION, {
|
|
detail: eventDetail,
|
|
})
|
|
);
|
|
|
|
setView('pair', {
|
|
disableAnimation: true,
|
|
initialMessage,
|
|
resumeSessionId: session.id,
|
|
});
|
|
return session;
|
|
}
|