Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 51 additions & 14 deletions packages/backend/src/managers/playgroundV2Manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import { type McpServerManager } from './playground/McpServerManager';
import type { ToolSet } from 'ai';
import { simulateStreamingMiddleware, wrapLanguageModel } from 'ai';
import type { InferenceServer } from '@shared/models/IInference';

export class PlaygroundV2Manager implements Disposable {
readonly #conversationRegistry: ConversationRegistry;
Expand All @@ -57,7 +58,7 @@
this.#conversationRegistry.deleteConversation(conversationId);
}

async requestCreatePlayground(name: string, model: ModelInfo): Promise<string> {
async requestCreatePlayground(name: string, model: ModelInfo, selectedService?: InferenceServer): Promise<string> {
const trackingId: string = getRandomString();
const task = this.taskRegistry.createTask('Creating Playground environment', 'loading', {
trackingId: trackingId,
Expand All @@ -67,7 +68,7 @@
hasName: !!name,
modelId: getHash(model.id),
};
this.createPlayground(name, model, trackingId)
this.createPlayground(name, model, trackingId, selectedService)
.then((playgroundId: string) => {
this.taskRegistry.updateTask({
...task,
Expand All @@ -86,7 +87,7 @@
});
// Filter the one no in loading state
tasks
.filter(t => t.state === 'loading' && t.id !== task.id)

Check failure on line 90 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / windows-2022

Unhandled error

TypeError: Cannot read properties of undefined (reading 'filter') ❯ src/managers/playgroundV2Manager.ts:90:12 ❯ processTicksAndRejections ../../node:internal/process/task_queues:105:5 This error originated in "src/managers/playgroundV2Manager.spec.ts" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.

Check failure on line 90 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / macos-14

Unhandled error

TypeError: Cannot read properties of undefined (reading 'filter') ❯ src/managers/playgroundV2Manager.ts:90:12 ❯ processTicksAndRejections ../../node:internal/process/task_queues:105:5 This error originated in "src/managers/playgroundV2Manager.spec.ts" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.

Check failure on line 90 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / ubuntu-22.04

Unhandled error

TypeError: Cannot read properties of undefined (reading 'filter') ❯ src/managers/playgroundV2Manager.ts:90:12 ❯ processTicksAndRejections ../../node:internal/process/task_queues:105:5 This error originated in "src/managers/playgroundV2Manager.spec.ts" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.
.forEach(t => {
this.taskRegistry.updateTask({
...t,
Expand All @@ -106,33 +107,51 @@
return trackingId;
}

async createPlayground(name: string, model: ModelInfo, trackingId: string): Promise<string> {
async createPlayground(
name: string,
model: ModelInfo,
trackingId: string,
selectedService?: InferenceServer,
): Promise<string> {
if (!name) {
name = this.getFreeName();
}
if (!this.isNameFree(name)) {
throw new Error(`a playground with the name ${name} already exists`);
}

// Create conversation
const conversationId = this.#conversationRegistry.createConversation(name, model.id);
let server: InferenceServer | undefined;
let containerId: string;

// create/start inference server if necessary
const servers = this.inferenceManager.getServers();
const server = servers.find(s => s.models.map(mi => mi.id).includes(model.id));
if (!server) {
await this.inferenceManager.createInferenceServer(
if (selectedService) {
// Use selected running service
server = this.inferenceManager
.getServers()
.find(s => s.container.containerId === selectedService.container.containerId);
if (!server) {
throw new Error(`Selected inference server ${selectedService.container.containerId} not found`);
}
if (server.status === 'stopped') {
await this.inferenceManager.startInferenceServer(server.container.containerId);
}
containerId = server.container.containerId;
} else {
// Create new inference server and get its containerId
containerId = await this.inferenceManager.createInferenceServer(
await withDefaultConfiguration({
modelsInfo: [model],
labels: {
trackingId: trackingId,
},
}),
);
} else if (server.status === 'stopped') {
await this.inferenceManager.startInferenceServer(server.container.containerId);
// Retrieve the server after creation
server = this.inferenceManager.getServers().find(s => s.container.containerId === containerId);

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / windows-2022

src/managers/playgroundV2Manager.spec.ts > creating a new playground with the model already served should not start an inference server

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:470:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / windows-2022

src/managers/playgroundV2Manager.spec.ts > error

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:317:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / windows-2022

src/managers/playgroundV2Manager.spec.ts > valid submit should create IPlaygroundMessage and notify the webview

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:238:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / windows-2022

src/managers/playgroundV2Manager.spec.ts > create playground should create conversation.

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:192:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / windows-2022

src/managers/playgroundV2Manager.spec.ts > submit should throw an error if the server is unhealthy

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:159:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / windows-2022

src/managers/playgroundV2Manager.spec.ts > submit should throw an error if the server is stopped

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:119:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / macos-14

src/managers/playgroundV2Manager.spec.ts > creating a new playground with the model already served should not start an inference server

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:470:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / macos-14

src/managers/playgroundV2Manager.spec.ts > error

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:317:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / macos-14

src/managers/playgroundV2Manager.spec.ts > valid submit should create IPlaygroundMessage and notify the webview

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:238:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / macos-14

src/managers/playgroundV2Manager.spec.ts > create playground should create conversation.

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:192:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / macos-14

src/managers/playgroundV2Manager.spec.ts > submit should throw an error if the server is unhealthy

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:159:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / macos-14

src/managers/playgroundV2Manager.spec.ts > submit should throw an error if the server is stopped

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:119:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / ubuntu-22.04

src/managers/playgroundV2Manager.spec.ts > creating a new playground with the model already served should not start an inference server

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:470:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / ubuntu-22.04

src/managers/playgroundV2Manager.spec.ts > error

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:317:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / ubuntu-22.04

src/managers/playgroundV2Manager.spec.ts > valid submit should create IPlaygroundMessage and notify the webview

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:238:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / ubuntu-22.04

src/managers/playgroundV2Manager.spec.ts > create playground should create conversation.

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:192:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / ubuntu-22.04

src/managers/playgroundV2Manager.spec.ts > submit should throw an error if the server is unhealthy

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:159:3

Check failure on line 149 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / ubuntu-22.04

src/managers/playgroundV2Manager.spec.ts > submit should throw an error if the server is stopped

TypeError: Cannot read properties of undefined (reading 'containerId') ❯ src/managers/playgroundV2Manager.ts:149:73 ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:149:51 ❯ src/managers/playgroundV2Manager.spec.ts:119:3
if (!server) {
throw new Error(`Inference server with containerId ${containerId} was not registered correctly.`);

Check failure on line 151 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / windows-2022

src/managers/playgroundV2Manager.spec.ts > creating a new playground with no model served should start an inference server

Error: Inference server with containerId undefined was not registered correctly. ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:151:15 ❯ src/managers/playgroundV2Manager.spec.ts:425:3

Check failure on line 151 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / windows-2022

src/managers/playgroundV2Manager.spec.ts > creating a new playground with no name should send new playground to frontend with generated name

Error: Inference server with containerId undefined was not registered correctly. ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:151:15 ❯ src/managers/playgroundV2Manager.spec.ts:392:3

Check failure on line 151 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / windows-2022

src/managers/playgroundV2Manager.spec.ts > creating a new playground should send new playground to frontend

Error: Inference server with containerId undefined was not registered correctly. ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:151:15 ❯ src/managers/playgroundV2Manager.spec.ts:360:3

Check failure on line 151 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / macos-14

src/managers/playgroundV2Manager.spec.ts > creating a new playground with no model served should start an inference server

Error: Inference server with containerId undefined was not registered correctly. ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:151:15 ❯ src/managers/playgroundV2Manager.spec.ts:425:3

Check failure on line 151 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / macos-14

src/managers/playgroundV2Manager.spec.ts > creating a new playground with no name should send new playground to frontend with generated name

Error: Inference server with containerId undefined was not registered correctly. ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:151:15 ❯ src/managers/playgroundV2Manager.spec.ts:392:3

Check failure on line 151 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / macos-14

src/managers/playgroundV2Manager.spec.ts > creating a new playground should send new playground to frontend

Error: Inference server with containerId undefined was not registered correctly. ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:151:15 ❯ src/managers/playgroundV2Manager.spec.ts:360:3

Check failure on line 151 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / ubuntu-22.04

src/managers/playgroundV2Manager.spec.ts > creating a new playground with no model served should start an inference server

Error: Inference server with containerId undefined was not registered correctly. ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:151:15 ❯ src/managers/playgroundV2Manager.spec.ts:425:3

Check failure on line 151 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / ubuntu-22.04

src/managers/playgroundV2Manager.spec.ts > creating a new playground with no name should send new playground to frontend with generated name

Error: Inference server with containerId undefined was not registered correctly. ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:151:15 ❯ src/managers/playgroundV2Manager.spec.ts:392:3

Check failure on line 151 in packages/backend/src/managers/playgroundV2Manager.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / ubuntu-22.04

src/managers/playgroundV2Manager.spec.ts > creating a new playground should send new playground to frontend

Error: Inference server with containerId undefined was not registered correctly. ❯ PlaygroundV2Manager.createPlayground src/managers/playgroundV2Manager.ts:151:15 ❯ src/managers/playgroundV2Manager.spec.ts:360:3
}
}

const conversationId = this.#conversationRegistry.createConversation(name, model.id, containerId);
return conversationId;
}

Expand Down Expand Up @@ -192,8 +211,26 @@
async submit(conversationId: string, userInput: string, options?: ModelOptions): Promise<number> {
const conversation = this.#conversationRegistry.get(conversationId);

console.log('conversation model id', conversation.modelId);

const servers = this.inferenceManager.getServers();
const server = servers.find(s => s.models.map(mi => mi.id).includes(conversation.modelId));

console.log('Available Inference Services:');
servers.forEach((server, index) => {
console.log(`--- Service ${index + 1} ---`);
console.log('Container ID:', server.container?.containerId);
console.log('Status:', server.status || 'unknown');
console.log('Health:', server.health?.Status ?? 'unknown');
console.log('Models:', server.models?.map(m => m.id).join(', ') || 'No models');
console.log('Inference Type:', server.type || 'N/A');
});

const server = this.inferenceManager.getServers().find(s => s.container.containerId === conversation.containerId);

console.log('picked service', server?.container.containerId);
console.log('picked service status', server?.status);
console.log('picked service health', server?.health?.Status);

if (server === undefined) throw new Error('Inference server not found.');

if (server.status !== 'running') throw new Error('Inference server is not running.');
Expand Down
3 changes: 2 additions & 1 deletion packages/backend/src/registries/ConversationRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,12 @@ export class ConversationRegistry extends Publisher<Conversation[]> implements D
this.notify();
}

createConversation(name: string, modelId: string): string {
createConversation(name: string, modelId: string, containerId?: string): string {
const conversationId = this.getUniqueId();
this.#conversations.set(conversationId, {
name: name,
modelId: modelId,
containerId: containerId,
messages: [],
id: conversationId,
usage: {
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/studio-api-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ export class StudioApiImpl implements StudioAPI {
});
}

async requestCreatePlayground(name: string, model: ModelInfo): Promise<string> {
async requestCreatePlayground(name: string, model: ModelInfo, selectedService?: InferenceServer): Promise<string> {
try {
return await this.playgroundV2.requestCreatePlayground(name, model);
return await this.playgroundV2.requestCreatePlayground(name, model, selectedService);
} catch (err: unknown) {
console.error('Something went wrong while trying to create playground environment', err);
throw err;
Expand Down
30 changes: 30 additions & 0 deletions packages/frontend/src/lib/select/InferenceRuntimeSelect.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script lang="ts">
import Select from '/@/lib/select/Select.svelte';
import { InferenceType } from '@shared/models/IInference';

interface Props {
disabled?: boolean;
value: InferenceType | undefined;
}
let { value = $bindable(), disabled }: Props = $props();
const options = Object.values(InferenceType).filter(type => type !== InferenceType.NONE) as Array<InferenceType>;
function handleOnChange(nValue: { value: string } | undefined): void {
if (nValue) {
value = nValue.value as InferenceType;
} else {
value = undefined;
}
}
</script>

<Select
label="Select Inference Runtime"
name="select-inference-runtime"
disabled={disabled}
value={value ? { label: value, value: value } : undefined}
onchange={handleOnChange}
placeholder="Select Inference Runtime to use"
items={options.map(type => ({
value: type,
label: type,
}))} />
49 changes: 49 additions & 0 deletions packages/frontend/src/lib/select/ModelServiceSelect.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<script lang="ts">
import Select from '/@/lib/select/Select.svelte';
import type { InferenceServer } from '@shared/models/IInference';

interface Props {
servers: InferenceServer[];
disabled?: boolean;
value: InferenceServer | undefined;
}

let { servers = [], disabled = false, value = $bindable() }: Props = $props();

// Format each server to an option for the select component
const options = servers.map(server => ({
...server,
value: server.container.containerId,
label: `${server.container.containerId.slice(0, 8)} (port ${server.connection.port}) - ${server.type} - ${server.status}`,
}));

let selected: (InferenceServer & { label: string; value: string }) | undefined = $derived.by(() => {
if (value) {
return {
...value,
label: `${value.container.containerId.slice(0, 8)} (port ${value.connection.port}) - ${value.type} - ${value.status}`,
value: value.container.containerId,
};
} else {
return undefined;
}
});

function handleOnChange(nValue: (InferenceServer & { label: string; value: string }) | undefined): void {
if (nValue) {
const { label, ...server } = nValue;
value = server as InferenceServer;
} else {
value = undefined;
}
}
</script>

<Select
label="Select Model Service"
name="select-model-service"
disabled={disabled}
value={selected}
onchange={handleOnChange}
placeholder="Select an inference server"
items={options} />
62 changes: 45 additions & 17 deletions packages/frontend/src/pages/PlaygroundCreate.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,20 @@ import { filterByLabel } from '../utils/taskUtils';
import type { Unsubscriber } from 'svelte/store';
import { Button, ErrorMessage, FormPage, Input } from '@podman-desktop/ui-svelte';
import ModelSelect from '/@/lib/select/ModelSelect.svelte';
import ModelServiceSelect from '/@/lib/select/ModelServiceSelect.svelte';
import { InferenceType } from '@shared/models/IInference';
import type { InferenceServer } from '@shared/models/IInference';
import { inferenceServers } from '/@/stores/inferenceServers';

let localModels: ModelInfo[];
let ModelServices: InferenceServer[];
$: localModels = $modelsInfo.filter(model => model.file && model.backend !== InferenceType.WHISPER_CPP);
$: availModels = $modelsInfo.filter(model => !model.file);
let model: ModelInfo | undefined = undefined;
let submitted: boolean = false;
let playgroundName: string;
let errorMsg: string | undefined = undefined;
let selectedService: InferenceServer | undefined;

// The tracking id is a unique identifier provided by the
// backend when calling requestCreateInferenceServer
Expand All @@ -34,12 +39,22 @@ $: {
if (!model && localModels.length > 0) {
model = localModels[0];
}
ModelServices = model ? $inferenceServers.filter(server => server.models.some(m => m.id === model?.id)) : [];
if (ModelServices.length > 0) {
selectedService = ModelServices[0];
} else {
selectedService = undefined;
}
}

function openModelsPage(): void {
router.goto(`/models`);
}

function openModelServicePage(): void {
router.goto(`/services`);
}

// Navigate to the new created playground environment
const openPlaygroundPage = (playgroundId: string): void => {
router.goto(`/playground/${playgroundId}`);
Expand All @@ -56,10 +71,10 @@ async function submit(): Promise<void> {
submitted = true;
try {
// Using || and not && as we want to have the empty string systemPrompt passed as undefined
trackingId = await studioClient.requestCreatePlayground(playgroundName, model);
trackingId = await studioClient.requestCreatePlayground(playgroundName, model, selectedService);
} catch (err: unknown) {
trackingId = undefined;
console.error('Something wrong while trying to create the playground.', err);
console.error('Something wrong while tryinfghfghgfhfghgg to create the playground.', err);
errorMsg = String(err);
submitted = false;
}
Expand Down Expand Up @@ -122,19 +137,17 @@ export function goToUpPage(): void {
</svelte:fragment>
<svelte:fragment slot="content">
<div class="flex flex-col w-full">
<!-- tasks tracked -->
{#if trackedTasks.length > 0}
<div class="mx-5 mt-5" role="status">
<TasksProgress tasks={trackedTasks} />
</div>
{/if}

<!-- form -->
<div class="bg-[var(--pd-content-card-bg)] m-5 pt-5 space-y-6 px-8 sm:pb-6 xl:pb-8 rounded-lg h-fit">
<div class="w-full">
<!-- playground name input -->
<label for="playgroundName" class="block mb-2 font-bold text-[var(--pd-content-card-header-text)]"
>Playground name</label>
<label for="playgroundName" class="block mb-2 font-bold text-[var(--pd-content-card-header-text)]">
Playground name
</label>
<Input
disabled={submitted}
id="playgroundName"
Expand All @@ -145,38 +158,53 @@ export function goToUpPage(): void {
placeholder="Leave blank to generate a name"
aria-label="playgroundName" />

<!-- model input -->
<label for="model" class="pt-4 block mb-2 font-bold text-[var(--pd-content-card-header-text)]">Model</label>
<label for="model" class="pt-4 block mb-2 font-bold text-[var(--pd-content-card-header-text)]"> Model </label>
<ModelSelect models={localModels} disabled={submitted} bind:value={model} />

{#if localModels.length === 0}
<div class="text-red-500 p-1 flex flex-row items-center">
<Fa size="1.1x" class="cursor-pointer text-red-500" icon={faExclamationCircle} />
<div role="alert" aria-label="Error Message Content" class="ml-2">
You don't have any models downloaded. You can download them in <a
<div class="ml-2">
You don't have any models downloaded. Download them from the
<a href="javascript:void(0);" class="underline" title="Models page" on:click={openModelsPage}
>models page</a
>.
</div>
</div>
{:else if availModels.length > 0}
<div class="text-sm p-1 flex flex-row items-center text-[var(--pd-content-card-text)]">
<Fa size="1.1x" class="cursor-pointer" icon={faInfoCircle} />
<div class="ml-2">
Other models are available on the <a
href="javascript:void(0);"
class="underline"
title="Models page"
on:click={openModelsPage}>models page</a
>.
</div>
</div>
{:else if availModels.length > 0}
{/if}
{#if ModelServices.length > 0}
<label class="pt-4 block mb-2 font-bold text-[var(--pd-content-card-header-text)]"> Model Services </label>
{#key ModelServices}
<ModelServiceSelect bind:value={selectedService} servers={ModelServices} disabled={submitted} />
{/key}
<div class="text-sm p-1 flex flex-row items-center text-[var(--pd-content-card-text)]">
<Fa size="1.1x" class="cursor-pointer" icon={faInfoCircle} />
<div role="alert" aria-label="Info Message Content" class="ml-2">
Other models are available, but must be downloaded from the <a
<div class="ml-2">
Create additional model services here <a
href="javascript:void(0);"
class="underline"
title="Models page"
on:click={openModelsPage}>models page</a
on:click={openModelServicePage}>model service page</a
>.
</div>
</div>
{/if}
</div>

{#if errorMsg !== undefined}
<ErrorMessage error={errorMsg} />
{/if}

<footer>
<div class="w-full flex flex-col">
<Button
Expand Down
2 changes: 1 addition & 1 deletion packages/shared/src/StudioAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ export interface StudioAPI {
*/
createSnippet(options: RequestOptions, language: string, variant: string): Promise<string>;

requestCreatePlayground(name: string, model: ModelInfo): Promise<string>;
requestCreatePlayground(name: string, model: ModelInfo, selectedService?: InferenceServer): Promise<string>;

/**
* Delete a conversation
Expand Down
1 change: 1 addition & 0 deletions packages/shared/src/models/IPlaygroundMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export interface Conversation {
id: string;
messages: Message[];
modelId: string;
containerId?: string;
name: string;
usage?: ModelUsage;
}
Expand Down
Loading