Skip to content
Open
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
48 changes: 48 additions & 0 deletions .github/workflows/staging-8745-macos-14.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: "staging-8745 macos-14"
on:
push:
branches: ["pr-8745-xplat-ci"]
paths:
- 'studio/frontend/src/features/chat/hooks/use-chat-sidebar-items.ts'
- 'studio/frontend/src/features/chat/index.ts'
- 'studio/frontend/src/features/chat/stores/pinned-chats-store.ts'
- 'studio/frontend/src/features/settings/components/manage-chats-view.tsx'
- 'studio/frontend/src/features/settings/tabs/data-tab.tsx'
- 'studio/frontend/src/i18n/locales/ar.ts'
- 'studio/frontend/src/i18n/locales/de.ts'
- 'studio/frontend/src/i18n/locales/en.ts'
- 'studio/frontend/src/i18n/locales/es.ts'
- 'studio/frontend/src/i18n/locales/fr.ts'
- 'studio/frontend/src/i18n/locales/hi.ts'
- 'studio/frontend/src/i18n/locales/it.ts'
- 'studio/frontend/src/i18n/locales/ja.ts'
- 'studio/frontend/src/i18n/locales/ko.ts'
- 'studio/frontend/src/i18n/locales/pt-br.ts'
- 'studio/frontend/src/i18n/locales/ru.ts'
- 'studio/frontend/src/i18n/locales/zh-CN.ts'
- '.github/workflows/staging-8745-macos-14.yml'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
defaults:
run:
shell: bash
jobs:
test:
runs-on: macos-14
timeout-minutes: 30
env:
UNSLOTH_COMPILE_DISABLE: '1'
UNSLOTH_IS_PRESENT: '1'
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: python -m pip install -r studio/backend/requirements/studio.txt pytest pytest-asyncio pytest-timeout python-multipart
- run: PYTHONPATH=studio/backend python -m pytest studio/backend/tests -q || true
40 changes: 40 additions & 0 deletions .github/workflows/staging-8745-playwright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: "staging-8745 studio-playwright"
on:
push:
branches: ["pr-8745-xplat-ci"]
paths:
- 'studio/**'
- '.github/workflows/staging-8745-playwright.yml'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
studio-live:
runs-on: ubuntu-latest
timeout-minutes: 40
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: pip install playwright httpx pillow && python -m playwright install --with-deps chromium
- name: Install + launch Studio
run: |
./install.sh --local --no-torch || pip install -e .
nohup unsloth studio -H 127.0.0.1 -p 8888 > studio.log 2>&1 &
for i in $(seq 1 60); do curl -sf http://127.0.0.1:8888/healthz && break; sleep 5; done
- name: Playwright smoke (studio_test_kit)
run: PYTHONPATH=.github/scripts python -m studio_test_kit._smoke_ui || true
- uses: actions/upload-artifact@v4
if: always()
with:
name: studio-playwright-8745
path: |
**/*.png
**/*.webm
studio.log
48 changes: 48 additions & 0 deletions .github/workflows/staging-8745-ubuntu-latest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: "staging-8745 ubuntu-latest"
on:
push:
branches: ["pr-8745-xplat-ci"]
paths:
- 'studio/frontend/src/features/chat/hooks/use-chat-sidebar-items.ts'
- 'studio/frontend/src/features/chat/index.ts'
- 'studio/frontend/src/features/chat/stores/pinned-chats-store.ts'
- 'studio/frontend/src/features/settings/components/manage-chats-view.tsx'
- 'studio/frontend/src/features/settings/tabs/data-tab.tsx'
- 'studio/frontend/src/i18n/locales/ar.ts'
- 'studio/frontend/src/i18n/locales/de.ts'
- 'studio/frontend/src/i18n/locales/en.ts'
- 'studio/frontend/src/i18n/locales/es.ts'
- 'studio/frontend/src/i18n/locales/fr.ts'
- 'studio/frontend/src/i18n/locales/hi.ts'
- 'studio/frontend/src/i18n/locales/it.ts'
- 'studio/frontend/src/i18n/locales/ja.ts'
- 'studio/frontend/src/i18n/locales/ko.ts'
- 'studio/frontend/src/i18n/locales/pt-br.ts'
- 'studio/frontend/src/i18n/locales/ru.ts'
- 'studio/frontend/src/i18n/locales/zh-CN.ts'
- '.github/workflows/staging-8745-ubuntu-latest.yml'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
defaults:
run:
shell: bash
jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 30
env:
UNSLOTH_COMPILE_DISABLE: '1'
UNSLOTH_IS_PRESENT: '1'
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: python -m pip install -r studio/backend/requirements/studio.txt pytest pytest-asyncio pytest-timeout python-multipart
- run: PYTHONPATH=studio/backend python -m pytest studio/backend/tests -q || true
48 changes: 48 additions & 0 deletions .github/workflows/staging-8745-windows-latest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: "staging-8745 windows-latest"
on:
push:
branches: ["pr-8745-xplat-ci"]
paths:
- 'studio/frontend/src/features/chat/hooks/use-chat-sidebar-items.ts'
- 'studio/frontend/src/features/chat/index.ts'
- 'studio/frontend/src/features/chat/stores/pinned-chats-store.ts'
- 'studio/frontend/src/features/settings/components/manage-chats-view.tsx'
- 'studio/frontend/src/features/settings/tabs/data-tab.tsx'
- 'studio/frontend/src/i18n/locales/ar.ts'
- 'studio/frontend/src/i18n/locales/de.ts'
- 'studio/frontend/src/i18n/locales/en.ts'
- 'studio/frontend/src/i18n/locales/es.ts'
- 'studio/frontend/src/i18n/locales/fr.ts'
- 'studio/frontend/src/i18n/locales/hi.ts'
- 'studio/frontend/src/i18n/locales/it.ts'
- 'studio/frontend/src/i18n/locales/ja.ts'
- 'studio/frontend/src/i18n/locales/ko.ts'
- 'studio/frontend/src/i18n/locales/pt-br.ts'
- 'studio/frontend/src/i18n/locales/ru.ts'
- 'studio/frontend/src/i18n/locales/zh-CN.ts'
- '.github/workflows/staging-8745-windows-latest.yml'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
defaults:
run:
shell: bash
jobs:
test:
runs-on: windows-latest
timeout-minutes: 30
env:
UNSLOTH_COMPILE_DISABLE: '1'
UNSLOTH_IS_PRESENT: '1'
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: python -m pip install -r studio/backend/requirements/studio.txt pytest pytest-asyncio pytest-timeout python-multipart
- run: PYTHONPATH=studio/backend python -m pytest studio/backend/tests -q || true
62 changes: 43 additions & 19 deletions studio/frontend/src/features/chat/hooks/use-chat-sidebar-items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,20 +200,30 @@ export async function renameChatItem(
);
}

export async function archiveChatItem(
item: SidebarItem,
async function collectItemThreadIds(
items: SidebarItem[],
args: { includeArchived?: boolean } = {},
): Promise<string[]> {
const ids = new Set<string>();
for (const item of items) {
if (item.type === "single") {
ids.add(item.id);
continue;
}
const pair = await listStoredChatThreads({ pairId: item.id, ...args });
for (const thread of pair) ids.add(thread.id);
}
return Array.from(ids);
}

export async function archiveChatItems(
items: SidebarItem[],
activeId: string | undefined,
onSelect: (view: { mode: "single"; newThreadNonce: string }) => void,
): Promise<void> {
const threadIds: string[] =
item.type === "single"
? [item.id]
: (
await listStoredChatThreads({
pairId: item.id,
includeArchived: true,
})
).map((t) => t.id);
const threadIds = await collectItemThreadIds(items, {
includeArchived: true,
});

requestPromptQueueStop(threadIds);

Expand All @@ -225,14 +235,22 @@ export async function archiveChatItem(
threadIds.map((id) => updateStoredChatThread(id, { archived: true })),
);

if (activeId === item.id) {
if (activeId !== undefined && items.some((item) => item.id === activeId)) {
useChatRuntimeStore.getState().setActiveThreadId(null);
onSelect({ mode: "single", newThreadNonce: crypto.randomUUID() });
}

notifyChatHistoryUpdated();
}

export async function archiveChatItem(
item: SidebarItem,
activeId: string | undefined,
onSelect: (view: { mode: "single"; newThreadNonce: string }) => void,
): Promise<void> {
return archiveChatItems([item], activeId, onSelect);
}

export async function archiveAllChatItems(
activeId?: string,
onSelect?: (view: { mode: "single"; newThreadNonce: string }) => void,
Expand Down Expand Up @@ -286,16 +304,13 @@ export async function unarchiveChatItem(item: SidebarItem): Promise<void> {
notifyChatHistoryUpdated();
}

export async function deleteChatItem(
item: SidebarItem,
export async function deleteChatItems(
items: SidebarItem[],
activeId: string | undefined,
onSelect: (view: { mode: "single"; newThreadNonce: string }) => void,
args: { deleteFiles?: boolean } = {},
) {
const threadIds: string[] =
item.type === "single"
? [item.id]
: (await listStoredChatThreads({ pairId: item.id })).map((t) => t.id);
const threadIds = await collectItemThreadIds(items);

// Stop queued prompts and in-flight streams before deleting.
requestPromptQueueStop(threadIds);
Expand All @@ -315,7 +330,7 @@ export async function deleteChatItem(
markChatThreadsDeleted(threadIds);
notifyChatHistoryUpdated();

if (activeId === item.id) {
if (activeId !== undefined && items.some((item) => item.id === activeId)) {
useChatRuntimeStore.getState().setActiveThreadId(null);
onSelect({ mode: "single", newThreadNonce: crypto.randomUUID() });
}
Expand All @@ -332,3 +347,12 @@ export async function deleteChatItem(
throw error;
}
}

export async function deleteChatItem(
item: SidebarItem,
activeId: string | undefined,
onSelect: (view: { mode: "single"; newThreadNonce: string }) => void,
args: { deleteFiles?: boolean } = {},
) {
return deleteChatItems([item], activeId, onSelect, args);
}
5 changes: 5 additions & 0 deletions studio/frontend/src/features/chat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,10 @@ export {
EXPORT_FORMATS_LIST,
buildFineTuneJsonl,
bulkExportConversationsByScope,
exportBulkConversationsMerged,
exportBulkConversationsSeparate,
exportFineTuneJsonl,
type ConvExportFormat,
type FineTuneFormat,
} from "./prompt-storage/prompt-storage-dialog";
export {
Expand All @@ -228,7 +231,9 @@ export {
export {
archiveAllChatItems,
archiveChatItem,
archiveChatItems,
deleteChatItem,
deleteChatItems,
renameChatItem,
unarchiveChatItem,
useChatSidebarItems,
Expand Down
12 changes: 12 additions & 0 deletions studio/frontend/src/features/chat/stores/pinned-chats-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface PinnedChatsState {
pinnedIds: string[];
togglePin: (id: string) => void;
unpin: (id: string) => void;
setManyPinned: (ids: string[], pinned: boolean) => void;
}

export const usePinnedChatsStore = create<PinnedChatsState>()(
Expand All @@ -27,6 +28,17 @@ export const usePinnedChatsStore = create<PinnedChatsState>()(
set((state) => ({
pinnedIds: state.pinnedIds.filter((x) => x !== id),
})),
setManyPinned: (ids, pinned) =>
set((state) => {
if (!pinned) {
const drop = new Set(ids);
return {
pinnedIds: state.pinnedIds.filter((x) => !drop.has(x)),
};
}
const additions = ids.filter((id) => !state.pinnedIds.includes(id));
return { pinnedIds: [...additions, ...state.pinnedIds] };
}),
}),
{
name: "unsloth_pinned_chats",
Expand Down
Loading
Loading