mirror of
https://github.com/runebookai/tome.git
synced 2025-07-21 00:27:30 +03:00
Back to line length of 100 + some svelte/ts settings
- Goes back to a max line length of 100
- Makes whitespace insignificant in Svelte files (see below)
- Avoids parens around single argument closures, in TS, when unncessary
*Whitespace Significance*
In HTML, `<p><b> 1 </b></p>` and `<p><b>1</b></p>` are not the same
thing. In the former, the "1" has spaces around it. If you were to try
to split this into multiple lines...
```html
<p>
<b>
1
</b>
</p>
```
...you would lose that whitespace. The newlines reset any significance
around individual tokens. This meant prettier would format that code
as...
```html
<p>
<b
> 1 </b>
</p>
```
...which is insane and hideous.
We're saying all whitespace is insignificant from now on. Meaning
prettier no longer needs to retain it and can format that code as a sane
person.
This means you need to explicitly use ` ` characters if you
explicitly need whitespace around things. OR put it in a `span` and use
css.
TL;DR: do not rely on whitespace significance in HTML.
This commit is contained in:
@@ -4,7 +4,8 @@
|
|||||||
"tabWidth": 4,
|
"tabWidth": 4,
|
||||||
"semi": true,
|
"semi": true,
|
||||||
"trailingComma": "es5",
|
"trailingComma": "es5",
|
||||||
"printWidth": 80,
|
"printWidth": 100,
|
||||||
|
"arrowParens": "avoid",
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"prettier-plugin-svelte",
|
"prettier-plugin-svelte",
|
||||||
"prettier-plugin-tailwindcss"
|
"prettier-plugin-tailwindcss"
|
||||||
@@ -14,7 +15,7 @@
|
|||||||
"files": "*.svelte",
|
"files": "*.svelte",
|
||||||
"options": {
|
"options": {
|
||||||
"parser": "svelte",
|
"parser": "svelte",
|
||||||
"printWidth": 100
|
"htmlWhitespaceSensitivity": "ignore"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -13,11 +13,13 @@
|
|||||||
></path>
|
></path>
|
||||||
</g>
|
</g>
|
||||||
<g>
|
<g>
|
||||||
<path d="m24 12h-16c-.553 0-1-.448-1-1s.447-1 1-1h16c.553 0 1 .448 1 1s-.447 1-1 1z"
|
<path
|
||||||
|
d="m24 12h-16c-.553 0-1-.448-1-1s.447-1 1-1h16c.553 0 1 .448 1 1s-.447 1-1 1z"
|
||||||
></path>
|
></path>
|
||||||
</g>
|
</g>
|
||||||
<g>
|
<g>
|
||||||
<path d="m16 16h-8c-.553 0-1-.448-1-1s.447-1 1-1h8c.553 0 1 .448 1 1s-.447 1-1 1z"
|
<path
|
||||||
|
d="m16 16h-8c-.553 0-1-.448-1-1s.447-1 1-1h8c.553 0 1 .448 1 1s-.447 1-1 1z"
|
||||||
></path>
|
></path>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 946 B After Width: | Height: | Size: 978 B |
@@ -4,8 +4,8 @@
|
|||||||
width="100%"
|
width="100%"
|
||||||
height="100%"
|
height="100%"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
><path
|
>
|
||||||
|
<path
|
||||||
d="m2 12c0-1.8129.44444-3.48538 1.33333-5.01754.90059-1.53217 2.11696-2.74269 3.64913-3.63158 1.54386-.90059 3.21634-1.35088 5.01754-1.35088 1.8129 0 3.4854.45029 5.0175 1.35088 1.5322.88889 2.7427 2.10526 3.6316 3.64912.9006 1.53216 1.3509 3.1988 1.3509 5s-.4503 3.4737-1.3509 5.0175c-.8889 1.5322-2.1052 2.7486-3.6491 3.6492-1.5322.8889-3.1988 1.3333-5 1.3333s-3.47368-.4444-5.01754-1.3333c-1.53217-.9006-2.74854-2.117-3.64913-3.6492-.88889-1.5438-1.33333-3.2163-1.33333-5.0175zm4.50877 0c0 .2807.09942.5146.29825.7018l2.89473 2.8947c.22223.2105.49125.3158.80705.3158.3275 0 .5965-.1053.807-.3158l5.8947-5.89475c.1989-.17543.2983-.40935.2983-.70175 0-.2807-.0994-.51462-.2983-.70175-.1871-.19884-.421-.29825-.7017-.29825s-.5146.09941-.7018.29825l-5.2982 5.28065-2.29827-2.2807c-.17544-.1988-.40936-.2982-.70176-.2982-.269 0-.50292.0994-.70175.2982-.19883.1872-.29825.4211-.29825.7018z"
|
d="m2 12c0-1.8129.44444-3.48538 1.33333-5.01754.90059-1.53217 2.11696-2.74269 3.64913-3.63158 1.54386-.90059 3.21634-1.35088 5.01754-1.35088 1.8129 0 3.4854.45029 5.0175 1.35088 1.5322.88889 2.7427 2.10526 3.6316 3.64912.9006 1.53216 1.3509 3.1988 1.3509 5s-.4503 3.4737-1.3509 5.0175c-.8889 1.5322-2.1052 2.7486-3.6491 3.6492-1.5322.8889-3.1988 1.3333-5 1.3333s-3.47368-.4444-5.01754-1.3333c-1.53217-.9006-2.74854-2.117-3.64913-3.6492-.88889-1.5438-1.33333-3.2163-1.33333-5.0175zm4.50877 0c0 .2807.09942.5146.29825.7018l2.89473 2.8947c.22223.2105.49125.3158.80705.3158.3275 0 .5965-.1053.807-.3158l5.8947-5.89475c.1989-.17543.2983-.40935.2983-.70175 0-.2807-.0994-.51462-.2983-.70175-.1871-.19884-.421-.29825-.7017-.29825s-.5146.09941-.7018.29825l-5.2982 5.28065-2.29827-2.2807c-.17544-.1988-.40936-.2982-.70176-.2982-.269 0-.50292.0994-.70175.2982-.19883.1872-.29825.4211-.29825.7018z"
|
||||||
>
|
></path>
|
||||||
</path>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
@@ -41,7 +41,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function remove(key: string) {
|
async function remove(key: string) {
|
||||||
env = env.filter((e) => e[0] !== key);
|
env = env.filter(e => e[0] !== key);
|
||||||
await save();
|
await save();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
<Flex bind:this={ref} class="bg-medium relative h-16 w-full hover:cursor-pointer">
|
<Flex bind:this={ref} class="bg-medium relative h-16 w-full hover:cursor-pointer">
|
||||||
<Flex
|
<Flex
|
||||||
onclick={(e) => toggle(e)}
|
onclick={e => toggle(e)}
|
||||||
class="border-light absolute top-0 left-0 w-full justify-between
|
class="border-light absolute top-0 left-0 w-full justify-between
|
||||||
rounded-md border p-2 px-4"
|
rounded-md border p-2 px-4"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -60,13 +60,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isValid() {
|
function isValid() {
|
||||||
return config.every((prop) => prop.valid);
|
return config.every(prop => prop.valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateAll() {
|
function validateAll() {
|
||||||
config
|
config
|
||||||
.filter((c) => c.required)
|
.filter(c => c.required)
|
||||||
.forEach((prop) => {
|
.forEach(prop => {
|
||||||
prop.valid = validate(prop.value);
|
prop.valid = validate(prop.value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -115,8 +115,13 @@
|
|||||||
<svelte:window onmessage={onMessage} />
|
<svelte:window onmessage={onMessage} />
|
||||||
|
|
||||||
{#if srcdoc}
|
{#if srcdoc}
|
||||||
<iframe title="stdioFunction" class="hidden h-0 w-0" sandbox="allow-scripts" allow="" {srcdoc}>
|
<iframe
|
||||||
</iframe>
|
title="stdioFunction"
|
||||||
|
class="hidden h-0 w-0"
|
||||||
|
sandbox="allow-scripts"
|
||||||
|
allow=""
|
||||||
|
{srcdoc}
|
||||||
|
></iframe>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if server && config}
|
{#if server && config}
|
||||||
@@ -126,7 +131,7 @@
|
|||||||
|
|
||||||
{#if config.length > 0}
|
{#if config.length > 0}
|
||||||
<div class="w-full px-8">
|
<div class="w-full px-8">
|
||||||
{#each config.filter((p) => p.required) as prop (prop.name)}
|
{#each config.filter(p => p.required) as prop (prop.name)}
|
||||||
<Input
|
<Input
|
||||||
label={prop.name}
|
label={prop.name}
|
||||||
name={prop.name}
|
name={prop.name}
|
||||||
@@ -137,7 +142,7 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if config.some((p) => !p.required)}
|
{#if config.some(p => !p.required)}
|
||||||
<Flex class="mt-8 w-full flex-col items-start">
|
<Flex class="mt-8 w-full flex-col items-start">
|
||||||
<button
|
<button
|
||||||
onclick={() => toggleOptional()}
|
onclick={() => toggleOptional()}
|
||||||
@@ -148,7 +153,7 @@
|
|||||||
|
|
||||||
{#if optionalIsOpen}
|
{#if optionalIsOpen}
|
||||||
<div class="w-full px-8">
|
<div class="w-full px-8">
|
||||||
{#each config.filter((p) => !p.required) as prop (prop.name)}
|
{#each config.filter(p => !p.required) as prop (prop.name)}
|
||||||
<Input
|
<Input
|
||||||
label={prop.name}
|
label={prop.name}
|
||||||
name={prop.name}
|
name={prop.name}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
async function install() {
|
async function install() {
|
||||||
update = await availableUpdate();
|
update = await availableUpdate();
|
||||||
|
|
||||||
await update?.downloadAndInstall((event) => {
|
await update?.downloadAndInstall(event => {
|
||||||
switch (event.event) {
|
switch (event.event) {
|
||||||
case 'Started':
|
case 'Started':
|
||||||
totalDownload = (event.data.contentLength as number) / 1000.0;
|
totalDownload = (event.data.contentLength as number) / 1000.0;
|
||||||
|
|||||||
@@ -21,8 +21,8 @@
|
|||||||
<h1 class="text-purple text-3xl">Welcome to Tome</h1>
|
<h1 class="text-purple text-3xl">Welcome to Tome</h1>
|
||||||
<p>
|
<p>
|
||||||
Thanks for being an early adopter! We appreciate you kicking the tires of our
|
Thanks for being an early adopter! We appreciate you kicking the tires of our
|
||||||
<strong>Technical Preview</strong> as we explore making local LLMs, MCP, and AI app composition
|
<strong>Technical Preview</strong>
|
||||||
a better experience.
|
as we explore making local LLMs, MCP, and AI app composition a better experience.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
This is an extremely early build. There will be problems – edges are rough – features
|
This is an extremely early build. There will be problems – edges are rough – features
|
||||||
|
|||||||
@@ -39,19 +39,13 @@ export const init: ClientInit = async () => {
|
|||||||
await Config.migrate();
|
await Config.migrate();
|
||||||
info('[green]✔ config migrated');
|
info('[green]✔ config migrated');
|
||||||
|
|
||||||
await startup.addCheck(
|
await startup.addCheck(StartupCheck.Agreement, async () => Config.agreedToWelcome);
|
||||||
StartupCheck.Agreement,
|
|
||||||
async () => Config.agreedToWelcome,
|
|
||||||
);
|
|
||||||
|
|
||||||
await startup.addCheck(
|
await startup.addCheck(StartupCheck.UpdateAvailable, async () => await isUpToDate());
|
||||||
StartupCheck.UpdateAvailable,
|
|
||||||
async () => await isUpToDate(),
|
|
||||||
);
|
|
||||||
|
|
||||||
await startup.addCheck(
|
await startup.addCheck(
|
||||||
StartupCheck.NoModels,
|
StartupCheck.NoModels,
|
||||||
async () => Engine.all().flatMap(e => e.models).length > 0,
|
async () => Engine.all().flatMap(e => e.models).length > 0
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export enum DeepLinks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function setupDeeplinks() {
|
export function setupDeeplinks() {
|
||||||
listen<string>(DeepLinks.InstallMcpServer, async (event) => {
|
listen<string>(DeepLinks.InstallMcpServer, async event => {
|
||||||
goto(`/mcp-servers/install?config=${event.payload}`);
|
goto(`/mcp-servers/install?config=${event.payload}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export default class Gemini implements Client {
|
|||||||
tools?: Tool[],
|
tools?: Tool[],
|
||||||
options?: Options
|
options?: Options
|
||||||
): Promise<IMessage> {
|
): Promise<IMessage> {
|
||||||
const messages = history.map((m) => GeminiMessage.from(m)).compact();
|
const messages = history.map(m => GeminiMessage.from(m)).compact();
|
||||||
|
|
||||||
let config: GenerateContentConfig = {
|
let config: GenerateContentConfig = {
|
||||||
temperature: options?.temperature,
|
temperature: options?.temperature,
|
||||||
@@ -50,7 +50,7 @@ export default class Gemini implements Client {
|
|||||||
let toolCalls: ToolCall[] = [];
|
let toolCalls: ToolCall[] = [];
|
||||||
|
|
||||||
if (functionCalls) {
|
if (functionCalls) {
|
||||||
toolCalls = functionCalls.map((tc) => ({
|
toolCalls = functionCalls.map(tc => ({
|
||||||
function: {
|
function: {
|
||||||
name: tc.name as string,
|
name: tc.name as string,
|
||||||
arguments: tc.args || {},
|
arguments: tc.args || {},
|
||||||
@@ -69,8 +69,8 @@ export default class Gemini implements Client {
|
|||||||
|
|
||||||
async models(): Promise<IModel[]> {
|
async models(): Promise<IModel[]> {
|
||||||
return (await this.client.models.list()).page
|
return (await this.client.models.list()).page
|
||||||
.filter((model) => this.supportedModels.includes(model.name as string))
|
.filter(model => this.supportedModels.includes(model.name as string))
|
||||||
.map((model) => {
|
.map(model => {
|
||||||
const metadata = model;
|
const metadata = model;
|
||||||
const name = metadata.name?.replace('models/', '') as string;
|
const name = metadata.name?.replace('models/', '') as string;
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ function fromToolResponse(message: IMessage): Content {
|
|||||||
// Find the `toolCall` message for this response
|
// Find the `toolCall` message for this response
|
||||||
const session = Session.find(message.sessionId as number);
|
const session = Session.find(message.sessionId as number);
|
||||||
const messages = Session.messages(session);
|
const messages = Session.messages(session);
|
||||||
const call = messages.flatMap((m) => m.toolCalls).find((tc) => tc.id == message.toolCallId);
|
const call = messages.flatMap(m => m.toolCalls).find(tc => tc.id == message.toolCallId);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
role: 'user',
|
role: 'user',
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ function from(tools: Tool | Tool[]): ToolListUnion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function fromMany(tools: Tool[]): FunctionDeclaration[] {
|
function fromMany(tools: Tool[]): FunctionDeclaration[] {
|
||||||
return tools.map((tool) => fromOne(tool));
|
return tools.map(tool => fromOne(tool));
|
||||||
}
|
}
|
||||||
|
|
||||||
function fromOne(tool: Tool): FunctionDeclaration {
|
function fromOne(tool: Tool): FunctionDeclaration {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export default class Ollama implements Client {
|
|||||||
tools: Tool[] = [],
|
tools: Tool[] = [],
|
||||||
options: Options = {}
|
options: Options = {}
|
||||||
): Promise<IMessage> {
|
): Promise<IMessage> {
|
||||||
const messages = history.map((m) => this.message.from(m));
|
const messages = history.map(m => this.message.from(m));
|
||||||
const response = await this.client.chat({
|
const response = await this.client.chat({
|
||||||
model: model.name,
|
model: model.name,
|
||||||
messages,
|
messages,
|
||||||
@@ -57,9 +57,7 @@ export default class Ollama implements Client {
|
|||||||
async models(): Promise<IModel[]> {
|
async models(): Promise<IModel[]> {
|
||||||
const models = (await this.client.list()).models;
|
const models = (await this.client.list()).models;
|
||||||
|
|
||||||
return Promise.all(
|
return Promise.all(models.map(async model => await this.info(model.name)));
|
||||||
models.map(async (model) => await this.info(model.name))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async info(name: string): Promise<IModel> {
|
async info(name: string): Promise<IModel> {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export function from(message: IMessage): Message {
|
|||||||
return {
|
return {
|
||||||
role: message.role,
|
role: message.role,
|
||||||
content: message.content,
|
content: message.content,
|
||||||
tool_calls: message.toolCalls?.map((c) => ({
|
tool_calls: message.toolCalls?.map(c => ({
|
||||||
function: {
|
function: {
|
||||||
name: c.function.name,
|
name: c.function.name,
|
||||||
arguments: c.function.arguments,
|
arguments: c.function.arguments,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export default class OpenAI implements Client {
|
|||||||
tools: Tool[] = [],
|
tools: Tool[] = [],
|
||||||
options: Options = {}
|
options: Options = {}
|
||||||
): Promise<IMessage> {
|
): Promise<IMessage> {
|
||||||
const messages = history.map((m) => OpenAiMessage.from(m));
|
const messages = history.map(m => OpenAiMessage.from(m));
|
||||||
const response = await this.client.chat.completions.create({
|
const response = await this.client.chat.completions.create({
|
||||||
model: model.name,
|
model: model.name,
|
||||||
messages,
|
messages,
|
||||||
@@ -45,7 +45,7 @@ export default class OpenAI implements Client {
|
|||||||
let toolCalls: ToolCall[] = [];
|
let toolCalls: ToolCall[] = [];
|
||||||
|
|
||||||
if (tool_calls) {
|
if (tool_calls) {
|
||||||
toolCalls = tool_calls.map((tc) => ({
|
toolCalls = tool_calls.map(tc => ({
|
||||||
function: {
|
function: {
|
||||||
name: tc.function.name,
|
name: tc.function.name,
|
||||||
arguments: JSON.parse(tc.function.arguments),
|
arguments: JSON.parse(tc.function.arguments),
|
||||||
@@ -66,10 +66,10 @@ export default class OpenAI implements Client {
|
|||||||
let allModels = (await this.client.models.list()).data;
|
let allModels = (await this.client.models.list()).data;
|
||||||
|
|
||||||
if (this.supportedModels !== 'all') {
|
if (this.supportedModels !== 'all') {
|
||||||
allModels = allModels.filter((model) => this.supportedModels.includes(model.id));
|
allModels = allModels.filter(model => this.supportedModels.includes(model.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
return allModels.map((model) => {
|
return allModels.map(model => {
|
||||||
const { id, ...metadata } = model;
|
const { id, ...metadata } = model;
|
||||||
const name = id.replace('models/', ''); // Gemini model ids are prefixed with "model/"
|
const name = id.replace('models/', ''); // Gemini model ids are prefixed with "model/"
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ function toolCalls(message: IMessage): OpenAI.ChatCompletionMessageToolCall[] |
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return message.toolCalls.map((call) => ({
|
return message.toolCalls.map(call => ({
|
||||||
id: call.id as string,
|
id: call.id as string,
|
||||||
type: 'function',
|
type: 'function',
|
||||||
function: {
|
function: {
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ Array.prototype.findBy = function <T extends Obj>(
|
|||||||
key: string,
|
key: string,
|
||||||
value: any
|
value: any
|
||||||
): T | undefined {
|
): T | undefined {
|
||||||
return this.find((item) => item[key] == value);
|
return this.find(item => item[key] == value);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,5 +106,5 @@ Array.prototype.findBy = function <T extends Obj>(
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
Array.prototype.compact = function <T>(this: T[]): Exclude<T, undefined>[] {
|
Array.prototype.compact = function <T>(this: T[]): Exclude<T, undefined>[] {
|
||||||
return this.filter((i) => i !== undefined) as Exclude<T, undefined>[];
|
return this.filter(i => i !== undefined) as Exclude<T, undefined>[];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ export interface HttpOptions extends RequestInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function fetch(url: string | URL | Request, options?: RequestInit) {
|
export async function fetch(url: string | URL | Request, options?: RequestInit) {
|
||||||
const response: globalThis.Response = await invoke('fetch', { url, options });
|
const response: globalThis.Response = await invoke('fetch', {
|
||||||
|
url,
|
||||||
|
options,
|
||||||
|
});
|
||||||
const { body, ...init } = response;
|
const { body, ...init } = response;
|
||||||
return new globalThis.Response(body, init);
|
return new globalThis.Response(body, init);
|
||||||
}
|
}
|
||||||
@@ -37,7 +40,10 @@ export abstract class HttpClient {
|
|||||||
async post<T>(uri: string, options: HttpOptions = {}): Promise<Response<T>> {
|
async post<T>(uri: string, options: HttpOptions = {}): Promise<Response<T>> {
|
||||||
const raw = Object.remove(options, 'raw');
|
const raw = Object.remove(options, 'raw');
|
||||||
const raise: boolean | undefined = Object.remove(options, 'raise');
|
const raise: boolean | undefined = Object.remove(options, 'raise');
|
||||||
const response = await this.request(uri, { ...options, method: 'POST' });
|
const response = await this.request(uri, {
|
||||||
|
...options,
|
||||||
|
method: 'POST',
|
||||||
|
});
|
||||||
return raw ? response : await this.parse(response, raise);
|
return raw ? response : await this.parse(response, raise);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,14 +57,20 @@ export abstract class HttpClient {
|
|||||||
async delete<T>(uri: string, options: HttpOptions = {}): Promise<Response<T>> {
|
async delete<T>(uri: string, options: HttpOptions = {}): Promise<Response<T>> {
|
||||||
const raw = Object.remove(options, 'raw');
|
const raw = Object.remove(options, 'raw');
|
||||||
const raise: boolean | undefined = Object.remove(options, 'raise');
|
const raise: boolean | undefined = Object.remove(options, 'raise');
|
||||||
const response = await this.request(uri, { ...options, method: 'DELETE' });
|
const response = await this.request(uri, {
|
||||||
|
...options,
|
||||||
|
method: 'DELETE',
|
||||||
|
});
|
||||||
return raw ? response : await this.parse(response, raise);
|
return raw ? response : await this.parse(response, raise);
|
||||||
}
|
}
|
||||||
|
|
||||||
async head<T>(uri: string, options: HttpOptions = {}): Promise<Response<T>> {
|
async head<T>(uri: string, options: HttpOptions = {}): Promise<Response<T>> {
|
||||||
const raw = Object.remove(options, 'raw');
|
const raw = Object.remove(options, 'raw');
|
||||||
const raise: boolean | undefined = Object.remove(options, 'raise');
|
const raise: boolean | undefined = Object.remove(options, 'raise');
|
||||||
const response = await this.request(uri, { ...options, method: 'HEAD' });
|
const response = await this.request(uri, {
|
||||||
|
...options,
|
||||||
|
method: 'HEAD',
|
||||||
|
});
|
||||||
return raw ? response : await this.parse(response, raise);
|
return raw ? response : await this.parse(response, raise);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ export class OllamaClient extends HttpClient {
|
|||||||
stream: false,
|
stream: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = (await this.post('/api/chat', { body })) as OllamaResponse;
|
const response = (await this.post('/api/chat', {
|
||||||
|
body,
|
||||||
|
})) as OllamaResponse;
|
||||||
|
|
||||||
let thought: string | undefined;
|
let thought: string | undefined;
|
||||||
let content: string = response.message.content
|
let content: string = response.message.content
|
||||||
@@ -75,7 +77,12 @@ export class OllamaClient extends HttpClient {
|
|||||||
|
|
||||||
async connected(): Promise<boolean> {
|
async connected(): Promise<boolean> {
|
||||||
return (
|
return (
|
||||||
((await this.get('', { raw: true, timeout: 500 })) as globalThis.Response).status == 200
|
(
|
||||||
|
(await this.get('', {
|
||||||
|
raw: true,
|
||||||
|
timeout: 500,
|
||||||
|
})) as globalThis.Response
|
||||||
|
).status == 200
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ function _log(args: any[], level: Level) {
|
|||||||
if (typeof args[0] !== 'string') {
|
if (typeof args[0] !== 'string') {
|
||||||
console[level](...fmt(level, ''), ...args);
|
console[level](...fmt(level, ''), ...args);
|
||||||
} else {
|
} else {
|
||||||
console[level](...args.flatMap((arg) => (typeof arg === 'string' ? fmt(level, arg) : arg)));
|
console[level](...args.flatMap(arg => (typeof arg === 'string' ? fmt(level, arg) : arg)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ function fmt(level: Level, text: string): string[] {
|
|||||||
function colorize(text: string): string[] {
|
function colorize(text: string): string[] {
|
||||||
let args: string[] = [];
|
let args: string[] = [];
|
||||||
|
|
||||||
text = text.replace(/\[\w+\]/g, (block) => {
|
text = text.replace(/\[\w+\]/g, block => {
|
||||||
const code = block.replace('[', '').replace(']', '');
|
const code = block.replace('[', '').replace(']', '');
|
||||||
const color = (colors as Obj)[code];
|
const color = (colors as Obj)[code];
|
||||||
args.push(`color: ${color};`);
|
args.push(`color: ${color};`);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export * from '$lib/mcp.d';
|
|||||||
// can send to the LLM.
|
// can send to the LLM.
|
||||||
//
|
//
|
||||||
export async function getMCPTools(session: ISession): Promise<Tool[]> {
|
export async function getMCPTools(session: ISession): Promise<Tool[]> {
|
||||||
return (await invoke<McpTool[]>('get_mcp_tools', { sessionId: session.id })).map((tool) => {
|
return (await invoke<McpTool[]>('get_mcp_tools', { sessionId: session.id })).map(tool => {
|
||||||
return {
|
return {
|
||||||
type: 'function',
|
type: 'function',
|
||||||
function: {
|
function: {
|
||||||
|
|||||||
@@ -57,13 +57,13 @@ export default class App extends Model<IApp, Row>('apps') {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static hasContext(app: IApp): boolean {
|
static hasContext(app: IApp): boolean {
|
||||||
return app.nodes?.find((n) => n.type == NodeType.Context) !== undefined;
|
return app.nodes?.find(n => n.type == NodeType.Context) !== undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
static context(app: IApp): string {
|
static context(app: IApp): string {
|
||||||
return app.nodes
|
return app.nodes
|
||||||
.filter((n) => n.type == NodeType.Context)
|
.filter(n => n.type == NodeType.Context)
|
||||||
.map((n) => n.config.value)
|
.map(n => n.config.value)
|
||||||
.join('\n\n');
|
.join('\n\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ export default class App extends Model<IApp, Row>('apps') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static removeNode(app: IApp, node: Node): IApp {
|
static removeNode(app: IApp, node: Node): IApp {
|
||||||
app.nodes = app.nodes.filter((n) => n.uuid !== node.uuid);
|
app.nodes = app.nodes.filter(n => n.uuid !== node.uuid);
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ export default class App extends Model<IApp, Row>('apps') {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
if (result.rowsAffected == 1) {
|
if (result.rowsAffected == 1) {
|
||||||
app.mcpServers = app.mcpServers.filter((m) => m.id == mcpServer.id);
|
app.mcpServers = app.mcpServers.filter(m => m.id == mcpServer.id);
|
||||||
return app.mcpServers;
|
return app.mcpServers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ export default function Model<Interface extends Obj, Row extends Obj>(table: str
|
|||||||
static async sync(): Promise<void> {
|
static async sync(): Promise<void> {
|
||||||
repo = [];
|
repo = [];
|
||||||
|
|
||||||
(await this.query(`SELECT * FROM ${table}`)).forEach((record) => this.syncOne(record));
|
(await this.query(`SELECT * FROM ${table}`)).forEach(record => this.syncOne(record));
|
||||||
|
|
||||||
info(`[green]✔ synced ${table}`);
|
info(`[green]✔ synced ${table}`);
|
||||||
}
|
}
|
||||||
@@ -175,7 +175,7 @@ export default function Model<Interface extends Obj, Row extends Obj>(table: str
|
|||||||
* Find an individual record by`id`.
|
* Find an individual record by`id`.
|
||||||
*/
|
*/
|
||||||
static find(id: number | string): Interface {
|
static find(id: number | string): Interface {
|
||||||
return this.all().find((m) => m.id == Number(id)) as Interface;
|
return this.all().find(m => m.id == Number(id)) as Interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -189,7 +189,7 @@ export default function Model<Interface extends Obj, Row extends Obj>(table: str
|
|||||||
* Find a collection of records by a set of the model's properties.
|
* Find a collection of records by a set of the model's properties.
|
||||||
*/
|
*/
|
||||||
static where(params: Partial<Interface>): Interface[] {
|
static where(params: Partial<Interface>): Interface[] {
|
||||||
return repo.filter((m) => {
|
return repo.filter(m => {
|
||||||
return Object.entries(params).every(([key, value]) => m[key] == value);
|
return Object.entries(params).every(([key, value]) => m[key] == value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -329,7 +329,7 @@ export default function Model<Interface extends Obj, Row extends Obj>(table: str
|
|||||||
).rowsAffected >= 1;
|
).rowsAffected >= 1;
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
instances.forEach((instance) => {
|
instances.forEach(instance => {
|
||||||
this.syncRemove(instance);
|
this.syncRemove(instance);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -343,7 +343,7 @@ export default function Model<Interface extends Obj, Row extends Obj>(table: str
|
|||||||
protected static async query(sql: string, values: unknown[] = []): Promise<Interface[]> {
|
protected static async query(sql: string, values: unknown[] = []): Promise<Interface[]> {
|
||||||
const result: Row[] = await (await this.db()).select<Row[]>(sql, values);
|
const result: Row[] = await (await this.db()).select<Row[]>(sql, values);
|
||||||
|
|
||||||
return await Promise.all(result.map(async (row) => await this.fromSql(row)));
|
return await Promise.all(result.map(async row => await this.fromSql(row)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -374,7 +374,7 @@ export default function Model<Interface extends Obj, Row extends Obj>(table: str
|
|||||||
* Remove an instance from the repo
|
* Remove an instance from the repo
|
||||||
*/
|
*/
|
||||||
private static syncRemove(instance: Interface) {
|
private static syncRemove(instance: Interface) {
|
||||||
repo = repo.filter((i) => i.id !== instance.id);
|
repo = repo.filter(i => i.id !== instance.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -389,7 +389,7 @@ export default function Model<Interface extends Obj, Row extends Obj>(table: str
|
|||||||
* This leaves only persisted records(ones with an`id`).
|
* This leaves only persisted records(ones with an`id`).
|
||||||
*/
|
*/
|
||||||
private static removeEphemeralInstances() {
|
private static removeEphemeralInstances() {
|
||||||
repo = repo.filter((record) => record.id !== undefined);
|
repo = repo.filter(record => record.id !== undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -490,7 +490,7 @@ export function BareModel<T extends Obj>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static delete(instance: T) {
|
static delete(instance: T) {
|
||||||
repo = repo.filter((i) => i !== instance);
|
repo = repo.filter(i => i !== instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
static all(): T[] {
|
static all(): T[] {
|
||||||
|
|||||||
@@ -14,11 +14,7 @@ interface Row {
|
|||||||
value: string;
|
value: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConfigKey =
|
type ConfigKey = 'latest-session-id' | 'welcome-agreed' | 'skipped-version' | 'default-model';
|
||||||
| 'latest-session-id'
|
|
||||||
| 'welcome-agreed'
|
|
||||||
| 'skipped-version'
|
|
||||||
| 'default-model';
|
|
||||||
|
|
||||||
export default class Config extends Model<IConfig, Row>('config') {
|
export default class Config extends Model<IConfig, Row>('config') {
|
||||||
@getset('latest-session-id')
|
@getset('latest-session-id')
|
||||||
@@ -81,7 +77,7 @@ export default class Config extends Model<IConfig, Row>('config') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getset(key: ConfigKey) {
|
function getset(key: ConfigKey) {
|
||||||
return function(target: object, property: string) {
|
return function (target: object, property: string) {
|
||||||
function get() {
|
function get() {
|
||||||
return Config.get(key);
|
return Config.get(key);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,6 @@ export default class Engine extends BareModel<IEngine>() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Model.reset(this.all().flatMap((engine) => engine.models));
|
Model.reset(this.all().flatMap(engine => engine.models));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export function from(message: IMessage): Message {
|
|||||||
return {
|
return {
|
||||||
role: message.role,
|
role: message.role,
|
||||||
content: message.content,
|
content: message.content,
|
||||||
tool_calls: message.toolCalls?.map((c) => ({
|
tool_calls: message.toolCalls?.map(c => ({
|
||||||
function: {
|
function: {
|
||||||
name: c.function.name,
|
name: c.function.name,
|
||||||
arguments: c.function.arguments,
|
arguments: c.function.arguments,
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ function toolCalls(message: IMessage): OpenAI.ChatCompletionMessageToolCall[] |
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return message.toolCalls.map((call) => ({
|
return message.toolCalls.map(call => ({
|
||||||
id: call.id as string,
|
id: call.id as string,
|
||||||
type: 'function',
|
type: 'function',
|
||||||
function: {
|
function: {
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ export default class Session extends Base<ISession, Row>('sessions') {
|
|||||||
|
|
||||||
static async removeMcpServer(session: ISession, server: IMcpServer): Promise<ISession> {
|
static async removeMcpServer(session: ISession, server: IMcpServer): Promise<ISession> {
|
||||||
session.config.enabledMcpServers = session.config.enabledMcpServers.filter(
|
session.config.enabledMcpServers = session.config.enabledMcpServers.filter(
|
||||||
(s) => s !== server.name
|
s => s !== server.name
|
||||||
);
|
);
|
||||||
return await this.update(session);
|
return await this.update(session);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ import Message from '$lib/models/message';
|
|||||||
|
|
||||||
export async function migrate() {
|
export async function migrate() {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
Message.all().map(async (message) => {
|
Message.all().map(async message => {
|
||||||
if (message.toolCalls.length == 0) {
|
if (message.toolCalls.length == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
message.toolCalls.map(async (tc) => {
|
message.toolCalls.map(async tc => {
|
||||||
// Ollama tool calls didn't always have an `id`. Add one
|
// Ollama tool calls didn't always have an `id`. Add one
|
||||||
// now if that's the case.
|
// now if that's the case.
|
||||||
if (!tc.id) {
|
if (!tc.id) {
|
||||||
|
|||||||
@@ -25,12 +25,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onNavigate((navigation) => {
|
onNavigate(navigation => {
|
||||||
if (!document.startViewTransition) {
|
if (!document.startViewTransition) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise(resolve => {
|
||||||
document.startViewTransition(async () => {
|
document.startViewTransition(async () => {
|
||||||
resolve();
|
resolve();
|
||||||
await navigation.complete;
|
await navigation.complete;
|
||||||
|
|||||||
@@ -7,11 +7,7 @@
|
|||||||
import Svg from '$components/Svg.svelte';
|
import Svg from '$components/Svg.svelte';
|
||||||
import Updater from '$components/Updater.svelte';
|
import Updater from '$components/Updater.svelte';
|
||||||
import Welcome from '$components/Welcome.svelte';
|
import Welcome from '$components/Welcome.svelte';
|
||||||
import startup, {
|
import startup, { type Condition, type OnSuccess, StartupCheck } from '$lib/startup';
|
||||||
type Condition,
|
|
||||||
type OnSuccess,
|
|
||||||
StartupCheck,
|
|
||||||
} from '$lib/startup';
|
|
||||||
|
|
||||||
const messages = {
|
const messages = {
|
||||||
[StartupCheck.NoModels]: 'No Engines Connected',
|
[StartupCheck.NoModels]: 'No Engines Connected',
|
||||||
@@ -73,9 +69,6 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</Modal>
|
</Modal>
|
||||||
{:else}
|
{:else}
|
||||||
<Svg
|
<Svg name="Logo" class="text-dark fixed top-[50%] left-[50%] h-32 w-32 -translate-[50%]" />
|
||||||
name="Logo"
|
|
||||||
class="text-dark fixed top-[50%] left-[50%] h-32 w-32 -translate-[50%]"
|
|
||||||
/>
|
|
||||||
{/if}
|
{/if}
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|||||||
@@ -20,14 +20,12 @@
|
|||||||
import Session, { type ISession } from '$lib/models/session';
|
import Session, { type ISession } from '$lib/models/session';
|
||||||
|
|
||||||
const session: ISession = $derived(Session.find(page.params.session_id));
|
const session: ISession = $derived(Session.find(page.params.session_id));
|
||||||
const model: IModel | undefined = $derived(
|
const model: IModel | undefined = $derived(Model.find(session.config.model));
|
||||||
Model.find(session.config.model)
|
|
||||||
);
|
|
||||||
|
|
||||||
const sessions: ISession[] = $derived(Session.all());
|
const sessions: ISession[] = $derived(Session.all());
|
||||||
const mcpServers: IMcpServer[] = $derived(McpServer.all());
|
const mcpServers: IMcpServer[] = $derived(McpServer.all());
|
||||||
const engines: IEngine[] = $derived(Engine.all());
|
const engines: IEngine[] = $derived(Engine.all());
|
||||||
const hasModels = $derived(engines.flatMap((e) => e.models).length > 0);
|
const hasModels = $derived(engines.flatMap(e => e.models).length > 0);
|
||||||
|
|
||||||
let advancedIsOpen = $state(false);
|
let advancedIsOpen = $state(false);
|
||||||
|
|
||||||
@@ -37,8 +35,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function startMcpServers(session: ISession) {
|
async function startMcpServers(session: ISession) {
|
||||||
session.config.enabledMcpServers.forEach(async (name) => {
|
session.config.enabledMcpServers.forEach(async name => {
|
||||||
const server = mcpServers.find((s) => s.name == name);
|
const server = mcpServers.find(s => s.name == name);
|
||||||
|
|
||||||
if (server) {
|
if (server) {
|
||||||
await startMcpServer(server);
|
await startMcpServer(server);
|
||||||
@@ -102,9 +100,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#snippet titlebar()}
|
{#snippet titlebar()}
|
||||||
<Flex
|
<Flex class="border-r-light z-10 h-full w-[300px] items-center border-r px-8 pr-4">
|
||||||
class="border-r-light z-10 h-full w-[300px] items-center border-r px-8 pr-4"
|
|
||||||
>
|
|
||||||
<h1 class="grow font-[500]">Chat</h1>
|
<h1 class="grow font-[500]">Chat</h1>
|
||||||
<button
|
<button
|
||||||
onclick={() => addSession()}
|
onclick={() => addSession()}
|
||||||
@@ -118,18 +114,14 @@
|
|||||||
|
|
||||||
<Layout {titlebar}>
|
<Layout {titlebar}>
|
||||||
<Flex class="h-full items-start">
|
<Flex class="h-full items-start">
|
||||||
<Flex
|
<Flex class="border-light bg-medium h-content w-[300px] flex-col overflow-auto border-r">
|
||||||
class="border-light bg-medium h-content w-[300px] flex-col overflow-auto border-r"
|
|
||||||
>
|
|
||||||
{#each sessions as sess (sess.id)}
|
{#each sessions as sess (sess.id)}
|
||||||
<Flex
|
<Flex
|
||||||
class={`text-medium border-b-light w-full justify-between border-b
|
class={`text-medium border-b-light w-full justify-between border-b
|
||||||
border-l-transparent text-sm ${sess.id == session?.id ? '!border-l-purple border-l' : ''}`}
|
border-l-transparent text-sm ${sess.id == session?.id ? '!border-l-purple border-l' : ''}`}
|
||||||
>
|
>
|
||||||
<Menu items={menuItems(sess)}>
|
<Menu items={menuItems(sess)}>
|
||||||
<Deleteable
|
<Deleteable ondelete={async () => await deleteSession(sess)}>
|
||||||
ondelete={async () => await deleteSession(sess)}
|
|
||||||
>
|
|
||||||
<Link
|
<Link
|
||||||
href={`/chat/${sess.id}`}
|
href={`/chat/${sess.id}`}
|
||||||
class="w-full py-3 pl-8 text-left"
|
class="w-full py-3 pl-8 text-left"
|
||||||
@@ -145,17 +137,13 @@
|
|||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
{#if session}
|
{#if session}
|
||||||
<Flex
|
<Flex class="bg-medium h-full w-[calc(100%-600px)] grow items-start">
|
||||||
class="bg-medium h-full w-[calc(100%-600px)] grow items-start"
|
|
||||||
>
|
|
||||||
{#key session.id}
|
{#key session.id}
|
||||||
<Chat {session} bind:model={session.config.model} />
|
<Chat {session} bind:model={session.config.model} />
|
||||||
{/key}
|
{/key}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Flex
|
<Flex class="bg-medium border-light h-full w-[300px] flex-col items-start border-l p-4">
|
||||||
class="bg-medium border-light h-full w-[300px] flex-col items-start border-l p-4"
|
|
||||||
>
|
|
||||||
{#key session.config.model}
|
{#key session.config.model}
|
||||||
<ModelMenu
|
<ModelMenu
|
||||||
{engines}
|
{engines}
|
||||||
@@ -190,10 +178,8 @@
|
|||||||
<Flex class="text-light z-0 mb-4 ml-2">
|
<Flex class="text-light z-0 mb-4 ml-2">
|
||||||
<Toggle
|
<Toggle
|
||||||
label={server.name}
|
label={server.name}
|
||||||
value={Session.hasMcpServer(
|
value={Session.hasMcpServer(session, server.name) &&
|
||||||
session,
|
model?.supportsTools
|
||||||
server.name
|
|
||||||
) && model?.supportsTools
|
|
||||||
? 'on'
|
? 'on'
|
||||||
: 'off'}
|
: 'off'}
|
||||||
disabled={!model?.supportsTools}
|
disabled={!model?.supportsTools}
|
||||||
@@ -209,19 +195,14 @@
|
|||||||
class="text-dark mb-4 ml-2 self-start text-sm font-medium hover:cursor-pointer"
|
class="text-dark mb-4 ml-2 self-start text-sm font-medium hover:cursor-pointer"
|
||||||
onclick={() => toggleAdvanced()}
|
onclick={() => toggleAdvanced()}
|
||||||
>
|
>
|
||||||
Advanced <span class="ml-4"
|
Advanced <span class="ml-4">
|
||||||
>{advancedIsOpen ? '⏷' : '⏵'}</span
|
{advancedIsOpen ? '⏷' : '⏵'}
|
||||||
>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{#if advancedIsOpen}
|
{#if advancedIsOpen}
|
||||||
<Flex
|
<Flex class="m-auto w-full flex-col items-start px-4 pt-4 pl-0">
|
||||||
class="m-auto w-full flex-col items-start px-4 pt-4 pl-0"
|
<label for="ctx_num" class="text-medium mb-1 ml-2 text-sm">
|
||||||
>
|
|
||||||
<label
|
|
||||||
for="ctx_num"
|
|
||||||
class="text-medium mb-1 ml-2 text-sm"
|
|
||||||
>
|
|
||||||
Context Window Size
|
Context Window Size
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
@@ -234,10 +215,7 @@
|
|||||||
bind:value={session.config.contextWindow}
|
bind:value={session.config.contextWindow}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<label
|
<label for="temperature" class="text-medium mt-4 mb-1 ml-2 text-sm">
|
||||||
for="temperature"
|
|
||||||
class="text-medium mt-4 mb-1 ml-2 text-sm"
|
|
||||||
>
|
|
||||||
Temperature
|
Temperature
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,10 @@
|
|||||||
{#if config.type !== 'stdio'}
|
{#if config.type !== 'stdio'}
|
||||||
<Flex class="text-red w-full">
|
<Flex class="text-red w-full">
|
||||||
<Svg name="Warning" class="mr-8 h-6 w-6" />
|
<Svg name="Warning" class="mr-8 h-6 w-6" />
|
||||||
<p>Tome only supports <code>stdio</code> MCP servers</p>
|
<p>
|
||||||
|
Tome only supports <code>stdio</code>
|
||||||
|
MCP servers
|
||||||
|
</p>
|
||||||
</Flex>
|
</Flex>
|
||||||
{:else}
|
{:else}
|
||||||
<Flex class="w-full flex-col items-start">
|
<Flex class="w-full flex-col items-start">
|
||||||
|
|||||||
Reference in New Issue
Block a user