Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
458eeb6
feat: Add "Thinking" toggle and status icon + redesign Chat Form Acti…
allozaur May 20, 2026
af05c5e
test: Update test reference
allozaur May 20, 2026
317e90d
fix: Icon
allozaur May 29, 2026
9acf3a7
fix: E2E test command
allozaur May 29, 2026
549d4a1
fix: wait for greeting h1 to be visible in e2e test
allozaur May 30, 2026
447f43d
fix: remove duplicate PDF option in attachment dropdown
allozaur May 30, 2026
ba48bbc
fix: use label-based group toggle to avoid stale references
allozaur May 30, 2026
36189fa
refactor: inline MCP server and tool toggles in mobile sheet
allozaur May 30, 2026
2c91354
fix: serve correct build directory in e2e playwright config
allozaur May 30, 2026
232a470
feat: add reasoning effort levels selector in model dropdown
allozaur May 30, 2026
1d9b838
feat: Reasoning effort
allozaur May 30, 2026
8984ed4
refactor: Make server origin configurable via environment variable
allozaur Jun 1, 2026
9f615f4
feat: Add chat template thinking detector utility
allozaur Jun 1, 2026
cb428af
feat: Add thinking support detection to models store
allozaur Jun 1, 2026
4d1225a
refactor: Update model selector components with thinking detection an…
allozaur Jun 1, 2026
3ca2987
feat: Update chat form components for model selection and thinking su…
allozaur Jun 1, 2026
e9232f5
feat: Improve Reasoning controls UI
allozaur Jun 1, 2026
903831d
Merge branch 'master' into allozaur/feat/thinking-mode-toggle
allozaur Jun 2, 2026
6505c46
refactor: Apply suggestions from code review
allozaur Jun 2, 2026
a6ef9e5
fix: Model tags
allozaur Jun 2, 2026
2c1d74f
refactor: Cleanup
allozaur Jun 2, 2026
2a8c39c
refactor: Remove unneeded components
allozaur Jun 2, 2026
bf15b53
refactor: Cleanup
allozaur Jun 2, 2026
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
2 changes: 0 additions & 2 deletions common/arg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4077,7 +4077,6 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
params.sampling.top_k = 0;
params.sampling.min_p = 0.01f;
params.use_jinja = true;
//params.default_template_kwargs["reasoning_effort"] = "\"high\"";
}
).set_examples({LLAMA_EXAMPLE_SERVER, LLAMA_EXAMPLE_CLI}));

Expand All @@ -4096,7 +4095,6 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
params.sampling.top_k = 0;
params.sampling.min_p = 0.01f;
params.use_jinja = true;
//params.default_template_kwargs["reasoning_effort"] = "\"high\"";
}
).set_examples({LLAMA_EXAMPLE_SERVER, LLAMA_EXAMPLE_CLI}));

Expand Down
3 changes: 2 additions & 1 deletion tools/ui/.env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
VITE_PUBLIC_APP_NAME='llama-ui'
# VITE_DEBUG='true'
VITE_DEBUG='true'
VITE_PUBLIC_SERVER_ORIGIN='http://localhost:8033'
3 changes: 3 additions & 0 deletions tools/ui/.prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ bun.lockb

# Miscellaneous
/static/
dist/
.svelte-kit/
build/

# Build output
/dist/
Expand Down
14 changes: 8 additions & 6 deletions tools/ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,18 @@ This starts:
- **Vite dev server** at `http://localhost:5173` - The main UI frontend app
- **Storybook** at `http://localhost:6006` - Component documentation

The Vite dev server proxies API requests to `http://localhost:8080` (default llama-server port):
The Vite dev server proxies API requests to `SERVER_ORIGIN` (with fallback to default llama-server `8080` port):

```typescript
// vite.config.ts proxy configuration
proxy: {
'/v1': 'http://localhost:8080',
'/props': 'http://localhost:8080',
'/slots': 'http://localhost:8080',
'/models': 'http://localhost:8080'
}
'/v1': SERVER_ORIGIN,
'/props': SERVER_ORIGIN,
'/models': SERVER_ORIGIN,
'/tools': SERVER_ORIGIN,
'/slots': SERVER_ORIGIN,
'/cors-proxy': SERVER_ORIGIN
},
```

### Development Workflow
Expand Down
2 changes: 1 addition & 1 deletion tools/ui/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { defineConfig } from '@playwright/test';

export default defineConfig({
webServer: {
command: 'npm run build && http-server ../../build/tools/ui/dist -p 8181',
command: 'npm run build && npx http-server ./dist -p 8181',
port: 8181,
timeout: 120000,
reuseExistingServer: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
let preSelectedResourceUri = $state<string | undefined>(undefined);

let currentConfig = $derived(config());

let pasteLongTextToFileLength = $derived.by(() => {
const n = Number(currentConfig.pasteLongTextToFileLen);
return Number.isNaN(n) ? Number(SETTING_CONFIG_DEFAULT.pasteLongTextToFileLen) : n;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
<script lang="ts">
import { Plus } from '@lucide/svelte';
import { Plus, File, MessageSquare, Zap, FolderOpen } from '@lucide/svelte';
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
import * as Tooltip from '$lib/components/ui/tooltip';
import { buttonVariants } from '$lib/components/ui/button';
import { cn } from '$lib/components/ui/utils';
import {
ATTACHMENT_FILE_ITEMS,
ATTACHMENT_EXTRA_ITEMS,
ATTACHMENT_MCP_ITEMS,
ATTACHMENT_TOOLTIP_TEXT,
TOOLTIP_DELAY_DURATION
} from '$lib/constants';
import { AttachmentMenuItemId } from '$lib/enums';
import {
ChatFormActionAddToolsSubmenu,
ChatFormActionAddMcpServersSubmenu
} from '$lib/components/app';

import { useAttachmentMenu } from '$lib/hooks/use-attachment-menu.svelte';

interface Props {
Expand Down Expand Up @@ -97,107 +93,87 @@
</Tooltip.Root>

<DropdownMenu.Content align="start" class="w-48">
{#each ATTACHMENT_FILE_ITEMS as item (item.id)}
{@const enabled = attachmentMenu.isItemEnabled(item.enabledWhen)}
{#if enabled}
<DropdownMenu.Item
class="{item.class ?? ''} flex cursor-pointer items-center gap-2"
onclick={() => attachmentMenu.callbacks[item.action]()}
>
<item.icon class="h-4 w-4" />

<span>{item.label}</span>
</DropdownMenu.Item>
{:else if item.disabledTooltip}
<Tooltip.Root delayDuration={TOOLTIP_DELAY_DURATION}>
<Tooltip.Trigger tabindex={-1}>
{#snippet child({ props })}
<div {...props} class="cursor-default">
<DropdownMenu.Item class="{item.class ?? ''} flex items-center gap-2" disabled>
<item.icon class="h-4 w-4" />

<span>{item.label}</span>
</DropdownMenu.Item>
</div>
{/snippet}
</Tooltip.Trigger>

<Tooltip.Content side="right">
<p>{item.disabledTooltip}</p>
</Tooltip.Content>
</Tooltip.Root>
{/if}
{/each}

{#if !attachmentMenu.isItemEnabled('hasVisionModality')}
<Tooltip.Root delayDuration={TOOLTIP_DELAY_DURATION}>
<Tooltip.Trigger>
{#snippet child({ props })}
<DropdownMenu.Sub>
<DropdownMenu.SubTrigger class="flex cursor-pointer items-center gap-2">
<File class="h-4 w-4" />

<span>Add files</span>
</DropdownMenu.SubTrigger>

<DropdownMenu.SubContent class="w-48">
{#each ATTACHMENT_FILE_ITEMS as item (item.id)}
{@const enabled = attachmentMenu.isItemEnabled(item.enabledWhen)}
{#if enabled}
<DropdownMenu.Item
{...props}
class="flex cursor-pointer items-center gap-2"
onclick={attachmentMenu.callbacks.onFileUpload}
class="{item.class ?? ''} flex cursor-pointer items-center gap-2"
onclick={() => attachmentMenu.callbacks[item.action]()}
>
{@const pdfItem = ATTACHMENT_FILE_ITEMS.find(
(i) => i.id === AttachmentMenuItemId.PDF
)}
{#if pdfItem}
<pdfItem.icon class="h-4 w-4" />

<span>{pdfItem.label}</span>
{/if}
</DropdownMenu.Item>
{/snippet}
</Tooltip.Trigger>

<Tooltip.Content side="right">
<p>PDFs will be converted to text. Image-based PDFs may not work properly.</p>
</Tooltip.Content>
</Tooltip.Root>
{/if}
<item.icon class="h-4 w-4" />

<DropdownMenu.Separator />

{#each ATTACHMENT_EXTRA_ITEMS as item (item.id)}
{#if item.id === AttachmentMenuItemId.SYSTEM_MESSAGE}
<Tooltip.Root delayDuration={TOOLTIP_DELAY_DURATION}>
<Tooltip.Trigger>
{#snippet child({ props })}
<DropdownMenu.Item
{...props}
class="flex cursor-pointer items-center gap-2"
onclick={() => attachmentMenu.callbacks[item.action]()}
>
<item.icon class="h-4 w-4" />

<span>{item.label}</span>
</DropdownMenu.Item>
{/snippet}
</Tooltip.Trigger>

<Tooltip.Content side="right">
<p>{attachmentMenu.getSystemMessageTooltip()}</p>
</Tooltip.Content>
</Tooltip.Root>
{/if}
{/each}
<span>{item.label}</span>
</DropdownMenu.Item>
{:else if item.disabledTooltip}
<Tooltip.Root delayDuration={TOOLTIP_DELAY_DURATION}>
<Tooltip.Trigger tabindex={-1}>
{#snippet child({ props })}
<div {...props} class="cursor-default">
<DropdownMenu.Item
class="{item.class ?? ''} flex items-center gap-2"
disabled
>
<item.icon class="h-4 w-4" />

<span>{item.label}</span>
</DropdownMenu.Item>
</div>
{/snippet}
</Tooltip.Trigger>

<Tooltip.Content side="right">
<p>{item.disabledTooltip}</p>
</Tooltip.Content>
</Tooltip.Root>
{/if}
{/each}
</DropdownMenu.SubContent>
</DropdownMenu.Sub>

<DropdownMenu.Item
class="flex cursor-pointer items-center gap-2"
onclick={onSystemPromptClick}
>
<MessageSquare class="h-4 w-4" />

<span>System Message</span>
</DropdownMenu.Item>

<ChatFormActionAddToolsSubmenu />

<ChatFormActionAddMcpServersSubmenu onMcpSettingsClick={handleMcpSettingsClick} />

{#each ATTACHMENT_MCP_ITEMS as item (item.id)}
{#if attachmentMenu.isItemVisible(item.visibleWhen)}
<DropdownMenu.Item
class="flex cursor-pointer items-center gap-2"
onclick={() => attachmentMenu.callbacks[item.action]()}
>
<item.icon class="h-4 w-4" />
{#if hasMcpPromptsSupport}
<DropdownMenu.Separator />

<span>{item.label}</span>
</DropdownMenu.Item>
{/if}
{/each}
<DropdownMenu.Item
class="flex cursor-pointer items-center gap-2"
onclick={onMcpPromptClick}
>
<Zap class="h-4 w-4" />

<span>MCP Prompt</span>
</DropdownMenu.Item>
{/if}

{#if hasMcpResourcesSupport}
<DropdownMenu.Item
class="flex cursor-pointer items-center gap-2"
onclick={onMcpResourcesClick}
>
<FolderOpen class="h-4 w-4" />

<span>MCP Resources</span>
</DropdownMenu.Item>
{/if}
</DropdownMenu.Content>
</DropdownMenu.Root>
</div>
Loading
Loading