From c017ce802fdc44815d6dbd6d435d8fed36981381 Mon Sep 17 00:00:00 2001 From: Roland Tannous <115670425+rolandtannous@users.noreply.github.com> Date: Mon, 23 Feb 2026 17:37:40 +0400 Subject: [PATCH 01/17] Remove firebase-debug.log and setup_leo.sh from tracking and add to .gitignore --- .gitignore | 4 + firebase-debug.log | 296 --------------------------------------------- setup_leo.sh | 241 ------------------------------------ 3 files changed, 4 insertions(+), 537 deletions(-) delete mode 100644 firebase-debug.log delete mode 100644 setup_leo.sh diff --git a/.gitignore b/.gitignore index f9be87df48..3901c1c699 100755 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,9 @@ unsloth_training_checkpoints/ .DS_Store Thumbs.db +# Firebase +firebase-debug.log + # Other resources/ tmp/ @@ -45,3 +48,4 @@ auth.db studio/frontend/package-lock.json log_rtx.txt log.txt +setup_leo.sh diff --git a/firebase-debug.log b/firebase-debug.log deleted file mode 100644 index a6bea586c8..0000000000 --- a/firebase-debug.log +++ /dev/null @@ -1,296 +0,0 @@ -[debug] [2026-02-18T11:41:02.773Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T11:41:02.774Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T11:41:02.774Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T11:41:02.774Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T11:41:02.782Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T11:41:02.782Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T11:41:03.470Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T11:41:03.470Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T11:41:03.471Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T11:41:03.471Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T11:41:03.483Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T11:41:03.483Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T11:41:03.484Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T11:41:03.484Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T12:08:15.283Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T12:08:15.285Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T12:08:15.285Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T12:08:15.285Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T12:08:15.292Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T12:08:15.292Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T12:08:15.724Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T12:08:15.725Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T12:08:15.726Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T12:08:15.726Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T12:08:15.727Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T12:08:15.727Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T12:08:15.727Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T12:08:15.727Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T13:46:32.892Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T13:46:32.893Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T13:46:32.894Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T13:46:32.894Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T13:46:32.900Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T13:46:32.900Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T13:46:33.376Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T13:46:33.376Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T13:46:33.377Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T13:46:33.378Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T13:46:33.482Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T13:46:33.483Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T13:46:33.483Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T13:46:33.484Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T14:08:25.135Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T14:08:25.136Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T14:08:25.137Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T14:08:25.137Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T14:08:25.145Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T14:08:25.145Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T14:08:25.574Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T14:08:25.574Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T14:08:25.575Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T14:08:25.575Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T14:08:25.579Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T14:08:25.579Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T14:08:25.580Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T14:08:25.580Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T14:14:07.782Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T14:14:07.783Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T14:14:07.783Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T14:14:07.783Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T14:14:07.790Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T14:14:07.791Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T14:14:08.126Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T14:14:08.127Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T14:14:08.128Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T14:14:08.128Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T14:14:08.152Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T14:14:08.153Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T14:14:08.153Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T14:14:08.153Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T16:19:05.291Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T16:19:05.292Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T16:19:05.292Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T16:19:05.292Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T16:19:05.299Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T16:19:05.299Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T16:19:05.733Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T16:19:05.733Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T16:19:05.734Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T16:19:05.734Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T16:19:05.747Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T16:19:05.747Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-18T16:19:05.748Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-18T16:19:05.748Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T05:51:29.275Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T05:51:29.277Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T05:51:29.277Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T05:51:29.277Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T05:51:29.284Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T05:51:29.284Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T05:51:29.631Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T05:51:29.631Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T05:51:29.632Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T05:51:29.632Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T05:51:29.633Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T05:51:29.634Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T05:51:29.634Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T05:51:29.634Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T06:13:16.833Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T06:13:16.834Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T06:13:16.834Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T06:13:16.834Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T06:13:16.842Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T06:13:16.842Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T06:13:17.305Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T06:13:17.306Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T06:13:17.307Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T06:13:17.307Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T06:13:17.310Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T06:13:17.310Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T06:13:17.311Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T06:13:17.311Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T06:14:26.095Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T06:14:26.096Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T06:14:26.096Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T06:14:26.096Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T06:14:26.103Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T06:14:26.103Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T06:14:26.454Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T06:14:26.454Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T06:14:26.455Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T06:14:26.456Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T06:14:26.458Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T06:14:26.458Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T06:14:26.459Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T06:14:26.459Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T07:04:34.310Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T07:04:34.312Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T07:04:34.312Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T07:04:34.312Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T07:04:34.319Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T07:04:34.319Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T07:04:34.689Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T07:04:34.690Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T07:04:34.691Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T07:04:34.691Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T07:04:34.694Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T07:04:34.694Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T07:04:34.695Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T07:04:34.695Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T07:37:42.030Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T07:37:42.031Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T07:37:42.031Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T07:37:42.031Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T07:37:42.038Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T07:37:42.039Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T07:37:42.404Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T07:37:42.405Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T07:37:42.406Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T07:37:42.406Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T07:37:42.408Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T07:37:42.408Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T07:37:42.409Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T07:37:42.409Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T08:56:00.592Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T08:56:00.593Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T08:56:00.593Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T08:56:00.593Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T08:56:00.601Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T08:56:00.601Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T08:56:01.042Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T08:56:01.042Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T08:56:01.043Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T08:56:01.044Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T08:56:01.045Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T08:56:01.045Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T08:56:01.046Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T08:56:01.046Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T09:08:43.860Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T09:08:43.861Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T09:08:43.861Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T09:08:43.861Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T09:08:43.868Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T09:08:43.868Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T09:08:44.206Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T09:08:44.207Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T09:08:44.208Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T09:08:44.209Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T09:08:44.212Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T09:08:44.212Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T09:08:44.213Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T09:08:44.213Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T11:08:31.233Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T11:08:31.234Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T11:08:31.234Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T11:08:31.234Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T11:08:31.242Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T11:08:31.242Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T11:08:31.688Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T11:08:31.688Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T11:08:31.689Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T11:08:31.690Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T11:08:31.694Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T11:08:31.694Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T11:08:31.695Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T11:08:31.695Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T14:05:39.367Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T14:05:39.368Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T14:05:39.368Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T14:05:39.368Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T14:05:39.376Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T14:05:39.376Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T14:05:39.808Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T14:05:39.808Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T14:05:39.810Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T14:05:39.810Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T14:05:39.813Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T14:05:39.813Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T14:05:39.814Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T14:05:39.814Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T18:50:53.945Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T18:50:53.946Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T18:50:53.947Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T18:50:53.947Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T18:50:53.954Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T18:50:53.954Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T18:50:54.408Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T18:50:54.409Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T18:50:54.410Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T18:50:54.410Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T18:50:54.412Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T18:50:54.412Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-19T18:50:54.413Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-19T18:50:54.413Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T05:58:38.962Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T05:58:38.964Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T05:58:38.964Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T05:58:38.964Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T05:58:38.972Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T05:58:38.972Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T05:58:39.404Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T05:58:39.404Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T05:58:39.405Z] >>> [apiv2][query] POST https://developerknowledge.googleapis.com/mcp [none] -[debug] [2026-02-20T05:58:39.405Z] >>> [apiv2][body] POST https://developerknowledge.googleapis.com/mcp {"method":"tools/list","jsonrpc":"2.0","id":1} -[debug] [2026-02-20T05:58:39.407Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T05:58:39.407Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T05:58:39.408Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T05:58:39.408Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T05:58:40.459Z] <<< [apiv2][status] POST https://developerknowledge.googleapis.com/mcp 200 -[debug] [2026-02-20T05:58:40.459Z] <<< [apiv2][body] POST https://developerknowledge.googleapis.com/mcp {"id":1,"jsonrpc":"2.0","result":{"tools":[{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":true},"description":"Use this tool to find documentation about Google developer products.\nThe documents contain official APIs, code snippets, release notes, best\npractices, guides, debugging info, and more. It covers the following\nproducts and domains:\n\n* Android: developer.android.com\n* Apigee: docs.apigee.com\n* Chrome: developer.chrome.com\n* Firebase: firebase.google.com\n* Fuchsia: fuchsia.dev\n* Google AI: ai.google.dev\n* Google Cloud: docs.cloud.google.com\n* Google Developers, Ads, Search, Google Maps, Youtube: developers.google.com\n* Google Home: developers.home.google.com\n* TensorFlow: www.tensorflow.org\n* Web: web.dev\n\nThis tool returns chunks of text, names, and URLs for matching documents.\nIf the returned chunks are not detailed enough to answer the\nuser's question, use `get_document` or `batch_get_documents` with the\n`parent` from this tool's output to retrieve the full document\ncontent.","inputSchema":{"description":"Request schema for search_documents. Use the query field to search for related Google developer documentation.","properties":{"query":{"description":"Required. The raw query string provided by the user, such as \"How to create a Cloud Storage bucket?\".","type":"string"}},"required":["query"],"type":"object"},"name":"search_documents","outputSchema":{"$defs":{"DocumentChunk":{"description":"A DocumentChunk represents a piece of content from a Document in the DeveloperKnowledge corpus. To fetch the entire document content, pass the `parent` to get_document or batch_get_documents.","properties":{"content":{"description":"Output only. The content of the document chunk.","readOnly":true,"type":"string"},"id":{"description":"Output only. The ID of this chunk within the document. The chunk ID is unique within a document, but not globally unique across documents. The chunk ID is not stable and may change over time.","readOnly":true,"type":"string"},"parent":{"description":"Output only. The resource name of the document this chunk is from. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","readOnly":true,"type":"string"}},"type":"object"}},"description":"Response schema for search_documents.","properties":{"results":{"description":"The search results for the given query. Each Document in this list contains a snippet of content relevant to the search query. Use the Document.name field of each result with get_document or batch_get_documents to retrieve the full document content.","items":{"$ref":"#/$defs/DocumentChunk"},"type":"array"}},"type":"object"}},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":true},"description":"Use this tool to retrieve the full content of a single document. The\ndocument name should be obtained from the `parent` field of results from a\ncall to the `search_documents` tool. If you need to retrieve multiple\ndocuments, use `batch_get_documents` instead.","inputSchema":{"description":"Request schema for get_document.","properties":{"name":{"description":"Required. The name of the document to retrieve. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","type":"string"}},"required":["name"],"type":"object"},"name":"get_document","outputSchema":{"description":"A Document represents a piece of content from the Developer Knowledge corpus.","properties":{"content":{"description":"Output only. The content of the document in Markdown format. If this document is returned by search_documents, this field contains a snippet of text relevant to the search query. If this document is returned by get_document or batch_get_documents, this field contains the full document content.","readOnly":true,"type":"string"},"description":{"description":"Output only. A description of the document.","readOnly":true,"type":"string"},"name":{"description":"Identifier. The resource name of the document. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","type":"string","x-google-identifier":true},"uri":{"description":"Output only. The URI of the content, such as `https://cloud.google.com/storage/docs/creating-buckets`.","readOnly":true,"type":"string"}},"type":"object"}},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":true},"description":"Use this tool to retrieve the full content of up to 20 documents in a\nsingle call. The document names should be obtained from the `parent` field\nof results from a call to the `search_documents` tool. Use this tool\ninstead of calling `get_document` multiple times to fetch multiple\ndocuments.","inputSchema":{"description":"Request schema for batch_get_documents.","properties":{"names":{"description":"Required. The names of the documents to retrieve, as returned by search_documents. A maximum of 20 documents can be retrieved in a batch. The documents are returned in the same order as the `names` in the request. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","items":{"type":"string"},"type":"array"}},"required":["names"],"type":"object"},"name":"batch_get_documents","outputSchema":{"$defs":{"Document":{"description":"A Document represents a piece of content from the Developer Knowledge corpus.","properties":{"content":{"description":"Output only. The content of the document in Markdown format. If this document is returned by search_documents, this field contains a snippet of text relevant to the search query. If this document is returned by get_document or batch_get_documents, this field contains the full document content.","readOnly":true,"type":"string"},"description":{"description":"Output only. A description of the document.","readOnly":true,"type":"string"},"name":{"description":"Identifier. The resource name of the document. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","type":"string","x-google-identifier":true},"uri":{"description":"Output only. The URI of the content, such as `https://cloud.google.com/storage/docs/creating-buckets`.","readOnly":true,"type":"string"}},"type":"object"}},"description":"Response schema for batch_get_documents.","properties":{"documents":{"description":"Documents requested.","items":{"$ref":"#/$defs/Document"},"type":"array"}},"type":"object"}}]}} -[debug] [2026-02-20T05:58:40.462Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T05:58:40.462Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T11:50:13.855Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T11:50:13.856Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T11:50:13.857Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T11:50:13.857Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T11:50:13.864Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T11:50:13.864Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T11:50:14.206Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T11:50:14.206Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T11:50:14.207Z] >>> [apiv2][query] POST https://developerknowledge.googleapis.com/mcp [none] -[debug] [2026-02-20T11:50:14.207Z] >>> [apiv2][body] POST https://developerknowledge.googleapis.com/mcp {"method":"tools/list","jsonrpc":"2.0","id":1} -[debug] [2026-02-20T11:50:14.212Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T11:50:14.212Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T11:50:14.212Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T11:50:14.213Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T11:50:15.300Z] <<< [apiv2][status] POST https://developerknowledge.googleapis.com/mcp 200 -[debug] [2026-02-20T11:50:15.300Z] <<< [apiv2][body] POST https://developerknowledge.googleapis.com/mcp {"id":1,"jsonrpc":"2.0","result":{"tools":[{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":true},"description":"Use this tool to find documentation about Google developer products.\nThe documents contain official APIs, code snippets, release notes, best\npractices, guides, debugging info, and more. It covers the following\nproducts and domains:\n\n* Android: developer.android.com\n* Apigee: docs.apigee.com\n* Chrome: developer.chrome.com\n* Firebase: firebase.google.com\n* Fuchsia: fuchsia.dev\n* Google AI: ai.google.dev\n* Google Cloud: docs.cloud.google.com\n* Google Developers, Ads, Search, Google Maps, Youtube: developers.google.com\n* Google Home: developers.home.google.com\n* TensorFlow: www.tensorflow.org\n* Web: web.dev\n\nThis tool returns chunks of text, names, and URLs for matching documents.\nIf the returned chunks are not detailed enough to answer the\nuser's question, use `get_document` or `batch_get_documents` with the\n`parent` from this tool's output to retrieve the full document\ncontent.","inputSchema":{"description":"Request schema for search_documents. Use the query field to search for related Google developer documentation.","properties":{"query":{"description":"Required. The raw query string provided by the user, such as \"How to create a Cloud Storage bucket?\".","type":"string"}},"required":["query"],"type":"object"},"name":"search_documents","outputSchema":{"$defs":{"DocumentChunk":{"description":"A DocumentChunk represents a piece of content from a Document in the DeveloperKnowledge corpus. To fetch the entire document content, pass the `parent` to get_document or batch_get_documents.","properties":{"content":{"description":"Output only. The content of the document chunk.","readOnly":true,"type":"string"},"id":{"description":"Output only. The ID of this chunk within the document. The chunk ID is unique within a document, but not globally unique across documents. The chunk ID is not stable and may change over time.","readOnly":true,"type":"string"},"parent":{"description":"Output only. The resource name of the document this chunk is from. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","readOnly":true,"type":"string"}},"type":"object"}},"description":"Response schema for search_documents.","properties":{"results":{"description":"The search results for the given query. Each Document in this list contains a snippet of content relevant to the search query. Use the Document.name field of each result with get_document or batch_get_documents to retrieve the full document content.","items":{"$ref":"#/$defs/DocumentChunk"},"type":"array"}},"type":"object"}},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":true},"description":"Use this tool to retrieve the full content of a single document. The\ndocument name should be obtained from the `parent` field of results from a\ncall to the `search_documents` tool. If you need to retrieve multiple\ndocuments, use `batch_get_documents` instead.","inputSchema":{"description":"Request schema for get_document.","properties":{"name":{"description":"Required. The name of the document to retrieve. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","type":"string"}},"required":["name"],"type":"object"},"name":"get_document","outputSchema":{"description":"A Document represents a piece of content from the Developer Knowledge corpus.","properties":{"content":{"description":"Output only. The content of the document in Markdown format. If this document is returned by search_documents, this field contains a snippet of text relevant to the search query. If this document is returned by get_document or batch_get_documents, this field contains the full document content.","readOnly":true,"type":"string"},"description":{"description":"Output only. A description of the document.","readOnly":true,"type":"string"},"name":{"description":"Identifier. The resource name of the document. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","type":"string","x-google-identifier":true},"uri":{"description":"Output only. The URI of the content, such as `https://cloud.google.com/storage/docs/creating-buckets`.","readOnly":true,"type":"string"}},"type":"object"}},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":true},"description":"Use this tool to retrieve the full content of up to 20 documents in a\nsingle call. The document names should be obtained from the `parent` field\nof results from a call to the `search_documents` tool. Use this tool\ninstead of calling `get_document` multiple times to fetch multiple\ndocuments.","inputSchema":{"description":"Request schema for batch_get_documents.","properties":{"names":{"description":"Required. The names of the documents to retrieve, as returned by search_documents. A maximum of 20 documents can be retrieved in a batch. The documents are returned in the same order as the `names` in the request. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","items":{"type":"string"},"type":"array"}},"required":["names"],"type":"object"},"name":"batch_get_documents","outputSchema":{"$defs":{"Document":{"description":"A Document represents a piece of content from the Developer Knowledge corpus.","properties":{"content":{"description":"Output only. The content of the document in Markdown format. If this document is returned by search_documents, this field contains a snippet of text relevant to the search query. If this document is returned by get_document or batch_get_documents, this field contains the full document content.","readOnly":true,"type":"string"},"description":{"description":"Output only. A description of the document.","readOnly":true,"type":"string"},"name":{"description":"Identifier. The resource name of the document. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","type":"string","x-google-identifier":true},"uri":{"description":"Output only. The URI of the content, such as `https://cloud.google.com/storage/docs/creating-buckets`.","readOnly":true,"type":"string"}},"type":"object"}},"description":"Response schema for batch_get_documents.","properties":{"documents":{"description":"Documents requested.","items":{"$ref":"#/$defs/Document"},"type":"array"}},"type":"object"}}]}} -[debug] [2026-02-20T11:50:15.302Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T11:50:15.302Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T19:09:28.241Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T19:09:28.242Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T19:09:28.242Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T19:09:28.242Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T19:09:28.249Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T19:09:28.249Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T19:09:28.579Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T19:09:28.579Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T19:09:28.580Z] >>> [apiv2][query] POST https://developerknowledge.googleapis.com/mcp [none] -[debug] [2026-02-20T19:09:28.581Z] >>> [apiv2][body] POST https://developerknowledge.googleapis.com/mcp {"method":"tools/list","jsonrpc":"2.0","id":1} -[debug] [2026-02-20T19:09:28.586Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T19:09:28.586Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T19:09:28.586Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T19:09:28.586Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-20T19:09:29.538Z] <<< [apiv2][status] POST https://developerknowledge.googleapis.com/mcp 200 -[debug] [2026-02-20T19:09:29.539Z] <<< [apiv2][body] POST https://developerknowledge.googleapis.com/mcp {"id":1,"jsonrpc":"2.0","result":{"tools":[{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":true},"description":"Use this tool to find documentation about Google developer products.\nThe documents contain official APIs, code snippets, release notes, best\npractices, guides, debugging info, and more. It covers the following\nproducts and domains:\n\n* Android: developer.android.com\n* Apigee: docs.apigee.com\n* Chrome: developer.chrome.com\n* Firebase: firebase.google.com\n* Fuchsia: fuchsia.dev\n* Google AI: ai.google.dev\n* Google Cloud: docs.cloud.google.com\n* Google Developers, Ads, Search, Google Maps, Youtube: developers.google.com\n* Google Home: developers.home.google.com\n* TensorFlow: www.tensorflow.org\n* Web: web.dev\n\nThis tool returns chunks of text, names, and URLs for matching documents.\nIf the returned chunks are not detailed enough to answer the\nuser's question, use `get_document` or `batch_get_documents` with the\n`parent` from this tool's output to retrieve the full document\ncontent.","inputSchema":{"description":"Request schema for search_documents. Use the query field to search for related Google developer documentation.","properties":{"query":{"description":"Required. The raw query string provided by the user, such as \"How to create a Cloud Storage bucket?\".","type":"string"}},"required":["query"],"type":"object"},"name":"search_documents","outputSchema":{"$defs":{"DocumentChunk":{"description":"A DocumentChunk represents a piece of content from a Document in the DeveloperKnowledge corpus. To fetch the entire document content, pass the `parent` to get_document or batch_get_documents.","properties":{"content":{"description":"Output only. The content of the document chunk.","readOnly":true,"type":"string"},"id":{"description":"Output only. The ID of this chunk within the document. The chunk ID is unique within a document, but not globally unique across documents. The chunk ID is not stable and may change over time.","readOnly":true,"type":"string"},"parent":{"description":"Output only. The resource name of the document this chunk is from. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","readOnly":true,"type":"string"}},"type":"object"}},"description":"Response schema for search_documents.","properties":{"results":{"description":"The search results for the given query. Each Document in this list contains a snippet of content relevant to the search query. Use the Document.name field of each result with get_document or batch_get_documents to retrieve the full document content.","items":{"$ref":"#/$defs/DocumentChunk"},"type":"array"}},"type":"object"}},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":true},"description":"Use this tool to retrieve the full content of a single document. The\ndocument name should be obtained from the `parent` field of results from a\ncall to the `search_documents` tool. If you need to retrieve multiple\ndocuments, use `batch_get_documents` instead.","inputSchema":{"description":"Request schema for get_document.","properties":{"name":{"description":"Required. The name of the document to retrieve. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","type":"string"}},"required":["name"],"type":"object"},"name":"get_document","outputSchema":{"description":"A Document represents a piece of content from the Developer Knowledge corpus.","properties":{"content":{"description":"Output only. The content of the document in Markdown format. If this document is returned by search_documents, this field contains a snippet of text relevant to the search query. If this document is returned by get_document or batch_get_documents, this field contains the full document content.","readOnly":true,"type":"string"},"description":{"description":"Output only. A description of the document.","readOnly":true,"type":"string"},"name":{"description":"Identifier. The resource name of the document. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","type":"string","x-google-identifier":true},"uri":{"description":"Output only. The URI of the content, such as `https://cloud.google.com/storage/docs/creating-buckets`.","readOnly":true,"type":"string"}},"type":"object"}},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":true},"description":"Use this tool to retrieve the full content of up to 20 documents in a\nsingle call. The document names should be obtained from the `parent` field\nof results from a call to the `search_documents` tool. Use this tool\ninstead of calling `get_document` multiple times to fetch multiple\ndocuments.","inputSchema":{"description":"Request schema for batch_get_documents.","properties":{"names":{"description":"Required. The names of the documents to retrieve, as returned by search_documents. A maximum of 20 documents can be retrieved in a batch. The documents are returned in the same order as the `names` in the request. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","items":{"type":"string"},"type":"array"}},"required":["names"],"type":"object"},"name":"batch_get_documents","outputSchema":{"$defs":{"Document":{"description":"A Document represents a piece of content from the Developer Knowledge corpus.","properties":{"content":{"description":"Output only. The content of the document in Markdown format. If this document is returned by search_documents, this field contains a snippet of text relevant to the search query. If this document is returned by get_document or batch_get_documents, this field contains the full document content.","readOnly":true,"type":"string"},"description":{"description":"Output only. A description of the document.","readOnly":true,"type":"string"},"name":{"description":"Identifier. The resource name of the document. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","type":"string","x-google-identifier":true},"uri":{"description":"Output only. The URI of the content, such as `https://cloud.google.com/storage/docs/creating-buckets`.","readOnly":true,"type":"string"}},"type":"object"}},"description":"Response schema for batch_get_documents.","properties":{"documents":{"description":"Documents requested.","items":{"$ref":"#/$defs/Document"},"type":"array"}},"type":"object"}}]}} -[debug] [2026-02-20T19:09:29.541Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-20T19:09:29.541Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-23T10:47:00.254Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-23T10:47:00.256Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-23T10:47:00.256Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-23T10:47:00.256Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-23T10:47:00.263Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-23T10:47:00.263Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-23T10:47:00.736Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-23T10:47:00.737Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-23T10:47:00.738Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-23T10:47:00.738Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-23T10:47:00.740Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-23T10:47:00.741Z] > authorizing via signed-in user (support@gonovel.co) -[debug] [2026-02-23T10:47:00.742Z] >>> [apiv2][query] POST https://developerknowledge.googleapis.com/mcp [none] -[debug] [2026-02-23T10:47:00.742Z] >>> [apiv2][body] POST https://developerknowledge.googleapis.com/mcp {"method":"tools/list","jsonrpc":"2.0","id":1} -[debug] [2026-02-23T10:47:01.893Z] <<< [apiv2][status] POST https://developerknowledge.googleapis.com/mcp 200 -[debug] [2026-02-23T10:47:01.893Z] <<< [apiv2][body] POST https://developerknowledge.googleapis.com/mcp {"id":1,"jsonrpc":"2.0","result":{"tools":[{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":true},"description":"Use this tool to find documentation about Google developer products.\nThe documents contain official APIs, code snippets, release notes, best\npractices, guides, debugging info, and more. It covers the following\nproducts and domains:\n\n* Android: developer.android.com\n* Apigee: docs.apigee.com\n* Chrome: developer.chrome.com\n* Firebase: firebase.google.com\n* Fuchsia: fuchsia.dev\n* Google AI: ai.google.dev\n* Google Cloud: docs.cloud.google.com\n* Google Developers, Ads, Search, Google Maps, Youtube: developers.google.com\n* Google Home: developers.home.google.com\n* TensorFlow: www.tensorflow.org\n* Web: web.dev\n\nThis tool returns chunks of text, names, and URLs for matching documents.\nIf the returned chunks are not detailed enough to answer the\nuser's question, use `get_document` or `batch_get_documents` with the\n`parent` from this tool's output to retrieve the full document\ncontent.","inputSchema":{"description":"Request schema for search_documents. Use the query field to search for related Google developer documentation.","properties":{"query":{"description":"Required. The raw query string provided by the user, such as \"How to create a Cloud Storage bucket?\".","type":"string"}},"required":["query"],"type":"object"},"name":"search_documents","outputSchema":{"$defs":{"DocumentChunk":{"description":"A DocumentChunk represents a piece of content from a Document in the DeveloperKnowledge corpus. To fetch the entire document content, pass the `parent` to get_document or batch_get_documents.","properties":{"content":{"description":"Output only. The content of the document chunk.","readOnly":true,"type":"string"},"id":{"description":"Output only. The ID of this chunk within the document. The chunk ID is unique within a document, but not globally unique across documents. The chunk ID is not stable and may change over time.","readOnly":true,"type":"string"},"parent":{"description":"Output only. The resource name of the document this chunk is from. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","readOnly":true,"type":"string"}},"type":"object"}},"description":"Response schema for search_documents.","properties":{"results":{"description":"The search results for the given query. Each Document in this list contains a snippet of content relevant to the search query. Use the Document.name field of each result with get_document or batch_get_documents to retrieve the full document content.","items":{"$ref":"#/$defs/DocumentChunk"},"type":"array"}},"type":"object"}},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":true},"description":"Use this tool to retrieve the full content of a single document. The\ndocument name should be obtained from the `parent` field of results from a\ncall to the `search_documents` tool. If you need to retrieve multiple\ndocuments, use `batch_get_documents` instead.","inputSchema":{"description":"Request schema for get_document.","properties":{"name":{"description":"Required. The name of the document to retrieve. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","type":"string"}},"required":["name"],"type":"object"},"name":"get_document","outputSchema":{"description":"A Document represents a piece of content from the Developer Knowledge corpus.","properties":{"content":{"description":"Output only. The content of the document in Markdown format. If this document is returned by search_documents, this field contains a snippet of text relevant to the search query. If this document is returned by get_document or batch_get_documents, this field contains the full document content.","readOnly":true,"type":"string"},"description":{"description":"Output only. A description of the document.","readOnly":true,"type":"string"},"name":{"description":"Identifier. The resource name of the document. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","type":"string","x-google-identifier":true},"uri":{"description":"Output only. The URI of the content, such as `https://cloud.google.com/storage/docs/creating-buckets`.","readOnly":true,"type":"string"}},"type":"object"}},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":true},"description":"Use this tool to retrieve the full content of up to 20 documents in a\nsingle call. The document names should be obtained from the `parent` field\nof results from a call to the `search_documents` tool. Use this tool\ninstead of calling `get_document` multiple times to fetch multiple\ndocuments.","inputSchema":{"description":"Request schema for batch_get_documents.","properties":{"names":{"description":"Required. The names of the documents to retrieve, as returned by search_documents. A maximum of 20 documents can be retrieved in a batch. The documents are returned in the same order as the `names` in the request. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","items":{"type":"string"},"type":"array"}},"required":["names"],"type":"object"},"name":"batch_get_documents","outputSchema":{"$defs":{"Document":{"description":"A Document represents a piece of content from the Developer Knowledge corpus.","properties":{"content":{"description":"Output only. The content of the document in Markdown format. If this document is returned by search_documents, this field contains a snippet of text relevant to the search query. If this document is returned by get_document or batch_get_documents, this field contains the full document content.","readOnly":true,"type":"string"},"description":{"description":"Output only. A description of the document.","readOnly":true,"type":"string"},"name":{"description":"Identifier. The resource name of the document. Format: `documents/{uri_without_scheme}` Example: `documents/docs.cloud.google.com/storage/docs/creating-buckets`","type":"string","x-google-identifier":true},"uri":{"description":"Output only. The URI of the content, such as `https://cloud.google.com/storage/docs/creating-buckets`.","readOnly":true,"type":"string"}},"type":"object"}},"description":"Response schema for batch_get_documents.","properties":{"documents":{"description":"Documents requested.","items":{"$ref":"#/$defs/Document"},"type":"array"}},"type":"object"}}]}} -[debug] [2026-02-23T10:47:01.896Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2026-02-23T10:47:01.896Z] > authorizing via signed-in user (support@gonovel.co) diff --git a/setup_leo.sh b/setup_leo.sh deleted file mode 100644 index 98d878421f..0000000000 --- a/setup_leo.sh +++ /dev/null @@ -1,241 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -# ── Helper: run command quietly, show output only on failure ── -run_quiet() { - local label="$1" - shift - local tmplog - tmplog=$(mktemp) - if "$@" > "$tmplog" 2>&1; then - rm -f "$tmplog" - else - local exit_code=$? - echo "❌ $label failed (exit code $exit_code):" - cat "$tmplog" - rm -f "$tmplog" - exit $exit_code - fi -} - -echo "╔══════════════════════════════════════╗" -echo "║ Unsloth Studio Setup Script ║" -echo "╚══════════════════════════════════════╝" - -# ── Detect Colab (like unsloth does) ── -IS_COLAB=false -keynames=$'\n'$(printenv | cut -d= -f1) -if [[ "$keynames" == *$'\nCOLAB_'* ]]; then - IS_COLAB=true -fi - -# ── 1. Check existing Node/npm versions ── -NEED_NODE=true -if command -v node &>/dev/null && command -v npm &>/dev/null; then - NODE_MAJOR=$(node -v | sed 's/v//' | cut -d. -f1) - NPM_MAJOR=$(npm -v | cut -d. -f1) - if [ "$NODE_MAJOR" -ge 20 ] && [ "$NPM_MAJOR" -ge 11 ]; then - echo "✅ Node $(node -v) and npm $(npm -v) already meet requirements. Skipping nvm install." - NEED_NODE=false - else - if [ "$IS_COLAB" = true ]; then - echo "✅ Node $(node -v) and npm $(npm -v) detected in Colab." - # In Colab, just upgrade npm directly - nvm doesn't work well - if [ "$NPM_MAJOR" -lt 11 ]; then - echo " Upgrading npm to latest..." - npm install -g npm@latest > /dev/null 2>&1 - fi - NEED_NODE=false - else - echo "⚠️ Node $(node -v) / npm $(npm -v) too old. Installing via nvm..." - fi - fi -else - echo "⚠️ Node/npm not found. Installing via nvm..." -fi - -if [ "$NEED_NODE" = true ]; then - # ── 2. Install nvm ── - echo "Installing nvm..." - curl -so- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash > /dev/null 2>&1 - - # Load nvm (source ~/.bashrc won't work inside a script) - export NVM_DIR="$HOME/.nvm" - [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" - - # ── 3. Install Node LTS ── - echo "Installing Node LTS..." - run_quiet "nvm install" nvm install --lts - nvm use --lts > /dev/null 2>&1 - - # ── 4. Verify versions ── - NODE_MAJOR=$(node -v | sed 's/v//' | cut -d. -f1) - NPM_MAJOR=$(npm -v | cut -d. -f1) - - if [ "$NODE_MAJOR" -lt 20 ]; then - echo "❌ ERROR: Node version must be >= 20 (got $(node -v))" - exit 1 - fi - if [ "$NPM_MAJOR" -lt 11 ]; then - echo "⚠️ npm version is $(npm -v), expected >= 11. Updating..." - run_quiet "npm update" npm install -g npm@latest - fi -fi - -echo "✅ Node $(node -v) | npm $(npm -v)" - -# ── 5. Build frontend ── -echo "" -echo "Building frontend..." -cd "$SCRIPT_DIR/studio/frontend" -run_quiet "npm install" npm install -run_quiet "npm run build" npm run build -cd "$SCRIPT_DIR" -echo "✅ Frontend built to studio/frontend/dist" - -# ── 6. Python venv + deps ── -echo "" -echo "Setting up Python environment..." - -# ── 6a. Discover best Python <= 3.12.x ── -BEST_PY="" -BEST_MAJOR=0 -BEST_MINOR=0 - -# Collect candidate python3 binaries (python3, python3.9, python3.10, …) -for candidate in $(compgen -c python3 2>/dev/null | grep -E '^python3(\.[0-9]+)?$' | sort -u); do - if ! command -v "$candidate" &>/dev/null; then - continue - fi - # Get version string, e.g. "Python 3.11.5" - ver_str=$("$candidate" --version 2>&1 | awk '{print $2}') - py_major=$(echo "$ver_str" | cut -d. -f1) - py_minor=$(echo "$ver_str" | cut -d. -f2) - - # Skip anything that isn't Python 3 - if [ "$py_major" -ne 3 ] 2>/dev/null; then - continue - fi - - # Skip versions above 3.12 - if [ "$py_minor" -gt 12 ] 2>/dev/null; then - continue - fi - - # Keep the highest qualifying version - if [ "$py_minor" -gt "$BEST_MINOR" ]; then - BEST_PY="$candidate" - BEST_MAJOR="$py_major" - BEST_MINOR="$py_minor" - fi -done - -if [ -z "$BEST_PY" ]; then - echo "❌ ERROR: No Python version <= 3.12.x found on this system." - echo " Detected Python 3 installations:" - for candidate in $(compgen -c python3 2>/dev/null | grep -E '^python3(\.[0-9]+)?$' | sort -u); do - if command -v "$candidate" &>/dev/null; then - echo " - $candidate ($($candidate --version 2>&1))" - fi - done - echo "" - echo " Please install Python <= 3.12.x for maximum compatibility." - echo " For example: sudo apt install python3.12 python3.12-venv" - exit 1 -fi - -BEST_VER=$("$BEST_PY" --version 2>&1 | awk '{print $2}') -echo "✅ Using $BEST_PY ($BEST_VER) — compatible (≤ 3.12.x)" - -if [ "$IS_COLAB" = true ]; then - # Colab: install packages directly without venv - run_quiet "pip upgrade" pip install --upgrade pip - echo " Installing unsloth-zoo + unsloth..." - run_quiet "pip install unsloth" pip install unsloth-zoo unsloth - echo " Installing studio dependencies..." - run_quiet "pip install extras" pip install typer fastapi uvicorn pydantic matplotlib pandas nest_asyncio "datasets==4.3.0" pyjwt easydict addict - echo "✅ Python dependencies installed" -else - # Local: create venv - "$BEST_PY" -m venv .venv - source .venv/bin/activate - run_quiet "pip upgrade" pip install --upgrade pip - echo " Installing unsloth-zoo + unsloth..." - run_quiet "pip install unsloth" pip install unsloth-zoo unsloth - echo " Installing studio dependencies..." - run_quiet "pip install extras" pip install typer fastapi uvicorn pydantic matplotlib pandas nest_asyncio "datasets==4.3.0" pyjwt easydict addict - echo "✅ Python dependencies installed" -fi - -# ── 7. Add shell alias (skip in Colab) ── -# Note: venv activation does NOT persist across terminal sessions. -# This alias hardcodes the venv python path so users don't need to activate. -if [ "$IS_COLAB" = false ]; then -echo "" -REPO_DIR="$SCRIPT_DIR" - -# Detect the user's default shell and pick the right rc file -USER_SHELL="$(basename "${SHELL:-/bin/bash}")" -case "$USER_SHELL" in - zsh) - SHELL_RC="$HOME/.zshrc" - ALIAS_BLOCK="alias unsloth-ui='${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py ui -f ${REPO_DIR}/studio/frontend/dist'" - ;; - fish) - SHELL_RC="$HOME/.config/fish/config.fish" - # fish uses 'abbr' or 'function'; a simple alias works via 'alias' in config.fish - ALIAS_BLOCK="alias unsloth-ui '${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py ui -f ${REPO_DIR}/studio/frontend/dist'" - ;; - ksh) - SHELL_RC="$HOME/.kshrc" - ALIAS_BLOCK="alias unsloth-ui='${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py ui -f ${REPO_DIR}/studio/frontend/dist'" - ;; - *) - # Default to bash for bash and any other POSIX-compatible shell - SHELL_RC="$HOME/.bashrc" - ALIAS_BLOCK="alias unsloth-ui='${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py ui -f ${REPO_DIR}/studio/frontend/dist'" - ;; -esac - -echo " Detected shell: $USER_SHELL → $SHELL_RC" - -ALIAS_ADDED=false -if ! grep -qF "unsloth-ui" "$SHELL_RC" 2>/dev/null; then - mkdir -p "$(dirname "$SHELL_RC")" # needed for fish's nested config path - cat >> "$SHELL_RC" < Date: Wed, 25 Feb 2026 00:36:25 -0800 Subject: [PATCH 02/17] rebase with nightly --- .../assistant-ui/model-selector/pickers.tsx | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx b/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx index 441fdf0f02..a2dbccc52e 100644 --- a/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx +++ b/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx @@ -44,6 +44,7 @@ function ModelRow({ vramStatus, vramEst, gpuGb, + tooltipText, }: { label: string; meta?: string; @@ -52,6 +53,7 @@ function ModelRow({ vramStatus?: VramFitStatus | null; vramEst?: number; gpuGb?: number; + tooltipText?: ReactNode; }) { const exceeds = vramStatus === "exceeds"; const showVramTooltip = @@ -111,6 +113,17 @@ function ModelRow({ ); } + + if (tooltipText) { + return ( + + {content} + + {tooltipText} + + + ); + } return content; } @@ -382,6 +395,14 @@ export function LoraModelPicker({ source: isExported ? "exported" : "lora", isLora: !isMerged, })} + tooltipText={ + <> + {adapter.name} + + {adapter.id} + + + } /> ); })} From 0eab63566663ab72120ce7f878d2183c5cdea900 Mon Sep 17 00:00:00 2001 From: samit Date: Wed, 25 Feb 2026 02:32:50 -0800 Subject: [PATCH 03/17] added space to show model/dataset name --- .../assistant-ui/model-selector/pickers.tsx | 6 +-- .../frontend/src/components/ui/combobox.tsx | 50 +++++++++---------- .../components/steps/dataset-step.tsx | 8 +-- .../studio/sections/dataset-section.tsx | 6 +-- .../studio/sections/model-section.tsx | 12 ++--- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx b/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx index 441fdf0f02..319f4fd484 100644 --- a/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx +++ b/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx @@ -70,20 +70,20 @@ function ModelRow({ type="button" onClick={onClick} className={cn( - "flex w-full items-center justify-between gap-2 rounded-md px-2.5 py-1.5 text-left text-sm transition-colors hover:bg-accent", + "flex w-full items-center gap-2 rounded-md px-2.5 py-1.5 text-left text-sm transition-colors hover:bg-accent", selected && "bg-accent/60", exceeds && "opacity-50", )} > {label} - + {vramStatus === "exceeds" && ( OOM )} diff --git a/studio/frontend/src/components/ui/combobox.tsx b/studio/frontend/src/components/ui/combobox.tsx index 9c1e970c57..e9f61eef70 100644 --- a/studio/frontend/src/components/ui/combobox.tsx +++ b/studio/frontend/src/components/ui/combobox.tsx @@ -6,8 +6,8 @@ import { Combobox as ComboboxPrimitive } from "@base-ui/react"; import * as React from "react"; import { createContext, useContext, useState } from "react"; -import { Button } from "@/components/ui/button"; -import { useDialogPortalContainer } from "@/components/ui/dialog"; +import { Button } from "@/components/ui/button"; +import { useDialogPortalContainer } from "@/components/ui/dialog"; import { InputGroup, InputGroupAddon, @@ -140,28 +140,28 @@ function ComboboxInput({ ); } -function ComboboxContent({ - className, - side = "bottom", - sideOffset = 6, - align = "start", - alignOffset = 0, - anchor, - container, - ...props -}: ComboboxPrimitive.Popup.Props & - Pick< - ComboboxPrimitive.Positioner.Props, - "side" | "align" | "sideOffset" | "alignOffset" | "anchor" - > & { - container?: HTMLElement | null; - }): React.ReactElement { - const dialogContainer = useDialogPortalContainer(); - return ( - - & { + container?: HTMLElement | null; + }): React.ReactElement { + const dialogContainer = useDialogPortalContainer(); + return ( + + - + {id} @@ -275,11 +275,11 @@ export function DatasetStep() { {detail ? ( - + {detail} ) : r?.downloads != null ? ( - + ↓{formatCompact(r.downloads)} ) : null} diff --git a/studio/frontend/src/features/studio/sections/dataset-section.tsx b/studio/frontend/src/features/studio/sections/dataset-section.tsx index 6f6a6a401e..629df50200 100644 --- a/studio/frontend/src/features/studio/sections/dataset-section.tsx +++ b/studio/frontend/src/features/studio/sections/dataset-section.tsx @@ -234,11 +234,11 @@ export function DatasetSection() { - + {id} @@ -250,7 +250,7 @@ export function DatasetSection() { {detail && ( - + {detail} )} diff --git a/studio/frontend/src/features/studio/sections/model-section.tsx b/studio/frontend/src/features/studio/sections/model-section.tsx index 5157e9f8fc..f06014a279 100644 --- a/studio/frontend/src/features/studio/sections/model-section.tsx +++ b/studio/frontend/src/features/studio/sections/model-section.tsx @@ -319,10 +319,10 @@ export function ModelSection() { const source = model?.source === "hf_cache" ? "HF cache" : "Local dir"; return ( - + - + {model?.display_name ?? id} @@ -330,7 +330,7 @@ export function ModelSection() { {model?.path ?? id} - + {source} @@ -434,11 +434,11 @@ export function ModelSection() { - + {id} @@ -458,7 +458,7 @@ export function ModelSection() { )} - + {fitStatus === "exceeds" && ( OOM From bbe208ea3855fe7c1ac5ebc83df6ebcf7525ff0c Mon Sep 17 00:00:00 2001 From: samit Date: Wed, 25 Feb 2026 03:31:45 -0800 Subject: [PATCH 04/17] reduced broad padding --- studio/frontend/src/components/ui/combobox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/studio/frontend/src/components/ui/combobox.tsx b/studio/frontend/src/components/ui/combobox.tsx index e9f61eef70..157fe3ab68 100644 --- a/studio/frontend/src/components/ui/combobox.tsx +++ b/studio/frontend/src/components/ui/combobox.tsx @@ -206,7 +206,7 @@ function ComboboxItem({ Date: Wed, 25 Feb 2026 18:08:02 -0800 Subject: [PATCH 05/17] passed checkpoint as a parameter to presets --- studio/frontend/src/features/chat/chat-settings-sheet.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/studio/frontend/src/features/chat/chat-settings-sheet.tsx b/studio/frontend/src/features/chat/chat-settings-sheet.tsx index 2d7ae781fa..1bc61cd25d 100644 --- a/studio/frontend/src/features/chat/chat-settings-sheet.tsx +++ b/studio/frontend/src/features/chat/chat-settings-sheet.tsx @@ -165,7 +165,11 @@ export function ChatSettingsPanel({ function applyPreset(name: string) { const p = presets.find((pr) => pr.name === name); if (p) { - onParamsChange({ ...p.params, systemPrompt: params.systemPrompt }); + onParamsChange({ + ...p.params, + systemPrompt: params.systemPrompt, + checkpoint: params.checkpoint, + }); setActivePreset(name); } } From 1c55e2fbaa98b2497c4d9d36bb1fbd32ec194238 Mon Sep 17 00:00:00 2001 From: imagineer99 Date: Thu, 26 Feb 2026 03:57:55 +0000 Subject: [PATCH 06/17] fix: remove dataset metadata badges from HF dataset dropdowns --- .../components/steps/dataset-step.tsx | 21 ++----------------- .../studio/sections/dataset-section.tsx | 21 +------------------ 2 files changed, 3 insertions(+), 39 deletions(-) diff --git a/studio/frontend/src/features/onboarding/components/steps/dataset-step.tsx b/studio/frontend/src/features/onboarding/components/steps/dataset-step.tsx index 1ad4fad8f0..99434f1285 100644 --- a/studio/frontend/src/features/onboarding/components/steps/dataset-step.tsx +++ b/studio/frontend/src/features/onboarding/components/steps/dataset-step.tsx @@ -38,7 +38,7 @@ import { useHfTokenValidation, useInfiniteScroll, } from "@/hooks"; -import { cn, formatCompact } from "@/lib/utils"; +import { cn } from "@/lib/utils"; import { HfDatasetSubsetSplitSelectors, useTrainingConfigStore, @@ -251,16 +251,8 @@ export function DatasetStep() { > {(id: string) => { - const r = hfResults.find((r) => r.id === id); - const detail = r?.totalExamples - ? `${formatCompact(r.totalExamples)} rows` - : (r?.sizeCategory ?? null); return ( - + @@ -274,15 +266,6 @@ export function DatasetStep() { {id} - {detail ? ( - - {detail} - - ) : r?.downloads != null ? ( - - ↓{formatCompact(r.downloads)} - - ) : null} ); }} diff --git a/studio/frontend/src/features/studio/sections/dataset-section.tsx b/studio/frontend/src/features/studio/sections/dataset-section.tsx index 6f6a6a401e..cf0fb7d90f 100644 --- a/studio/frontend/src/features/studio/sections/dataset-section.tsx +++ b/studio/frontend/src/features/studio/sections/dataset-section.tsx @@ -33,7 +33,6 @@ import { useHfTokenValidation, useInfiniteScroll, } from "@/hooks"; -import { formatCompact } from "@/lib/utils"; import { HfDatasetSubsetSplitSelectors, useDatasetPreviewDialogStore, @@ -221,21 +220,8 @@ export function DatasetSection() { > {(id: string) => { - const r = hfResults.find((ds) => ds.id === id); - let detail: string | null = null; - if (r?.totalExamples) { - detail = `${formatCompact(r.totalExamples)} rows`; - } else if (r?.sizeCategory) { - detail = r.sizeCategory; - } else if (r?.downloads != null) { - detail = `↓${formatCompact(r.downloads)}`; - } return ( - + @@ -249,11 +235,6 @@ export function DatasetSection() { {id} - {detail && ( - - {detail} - - )} ); }} From 04aee4a4c64150abb2497cb489cbf83bed74916d Mon Sep 17 00:00:00 2001 From: samit Date: Wed, 25 Feb 2026 21:36:50 -0800 Subject: [PATCH 07/17] updated to make the delete preset work --- .../src/features/chat/chat-settings-sheet.tsx | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/studio/frontend/src/features/chat/chat-settings-sheet.tsx b/studio/frontend/src/features/chat/chat-settings-sheet.tsx index 2d7ae781fa..4bfc3351e8 100644 --- a/studio/frontend/src/features/chat/chat-settings-sheet.tsx +++ b/studio/frontend/src/features/chat/chat-settings-sheet.tsx @@ -157,6 +157,7 @@ export function ChatSettingsPanel({ }: ChatSettingsPanelProps) { const [presets, setPresets] = useState(BUILTIN_PRESETS); const [activePreset, setActivePreset] = useState("Default"); + const isBuiltinPreset = BUILTIN_PRESETS.some((p) => p.name === activePreset); function set(key: K) { return (v: InferenceParams[K]) => onParamsChange({ ...params, [key]: v }); @@ -219,24 +220,7 @@ export function ChatSettingsPanel({ {presets.map((p) => ( -
- {p.name} - {!BUILTIN_PRESETS.some((bp) => bp.name === p.name) && ( - - )} -
+ {p.name}
))}
@@ -250,6 +234,20 @@ export function ChatSettingsPanel({ Save + From 782af3994911f426fbe6c128437dc11e2724b347 Mon Sep 17 00:00:00 2001 From: Roland Tannous <115670425+rolandtannous@users.noreply.github.com> Date: Thu, 26 Feb 2026 10:54:49 +0400 Subject: [PATCH 08/17] Add gguf to frontend export_type unions --- .../src/components/assistant-ui/model-selector/types.ts | 2 +- studio/frontend/src/features/chat/types/api.ts | 2 +- studio/frontend/src/features/chat/types/runtime.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/studio/frontend/src/components/assistant-ui/model-selector/types.ts b/studio/frontend/src/components/assistant-ui/model-selector/types.ts index 43f5e935b3..0e8cf5fb4d 100644 --- a/studio/frontend/src/components/assistant-ui/model-selector/types.ts +++ b/studio/frontend/src/components/assistant-ui/model-selector/types.ts @@ -11,7 +11,7 @@ export interface LoraModelOption extends ModelOption { baseModel?: string; updatedAt?: number; source?: "training" | "exported"; - exportType?: "lora" | "merged"; + exportType?: "lora" | "merged" | "gguf"; } export interface ModelSelectorChangeMeta { diff --git a/studio/frontend/src/features/chat/types/api.ts b/studio/frontend/src/features/chat/types/api.ts index 5dd0cd7a6b..d0b37f5cce 100644 --- a/studio/frontend/src/features/chat/types/api.ts +++ b/studio/frontend/src/features/chat/types/api.ts @@ -16,7 +16,7 @@ export interface BackendLoraInfo { adapter_path: string; base_model?: string | null; source?: "training" | "exported" | null; - export_type?: "lora" | "merged" | null; + export_type?: "lora" | "merged" | "gguf" | null; } export interface ListLorasResponse { diff --git a/studio/frontend/src/features/chat/types/runtime.ts b/studio/frontend/src/features/chat/types/runtime.ts index 953f4ebbaa..710898713b 100644 --- a/studio/frontend/src/features/chat/types/runtime.ts +++ b/studio/frontend/src/features/chat/types/runtime.ts @@ -35,5 +35,5 @@ export interface ChatLoraSummary { baseModel: string; updatedAt?: number; source?: "training" | "exported"; - exportType?: "lora" | "merged"; + exportType?: "lora" | "merged" | "gguf"; } From 1b822a943c342f70d1d4005c2ee14baaadf63c5f Mon Sep 17 00:00:00 2001 From: Roland Tannous <115670425+rolandtannous@users.noreply.github.com> Date: Thu, 26 Feb 2026 10:56:26 +0400 Subject: [PATCH 09/17] Revert "Add gguf to frontend export_type unions" This reverts commit 782af3994911f426fbe6c128437dc11e2724b347. --- .../src/components/assistant-ui/model-selector/types.ts | 2 +- studio/frontend/src/features/chat/types/api.ts | 2 +- studio/frontend/src/features/chat/types/runtime.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/studio/frontend/src/components/assistant-ui/model-selector/types.ts b/studio/frontend/src/components/assistant-ui/model-selector/types.ts index 0e8cf5fb4d..43f5e935b3 100644 --- a/studio/frontend/src/components/assistant-ui/model-selector/types.ts +++ b/studio/frontend/src/components/assistant-ui/model-selector/types.ts @@ -11,7 +11,7 @@ export interface LoraModelOption extends ModelOption { baseModel?: string; updatedAt?: number; source?: "training" | "exported"; - exportType?: "lora" | "merged" | "gguf"; + exportType?: "lora" | "merged"; } export interface ModelSelectorChangeMeta { diff --git a/studio/frontend/src/features/chat/types/api.ts b/studio/frontend/src/features/chat/types/api.ts index d0b37f5cce..5dd0cd7a6b 100644 --- a/studio/frontend/src/features/chat/types/api.ts +++ b/studio/frontend/src/features/chat/types/api.ts @@ -16,7 +16,7 @@ export interface BackendLoraInfo { adapter_path: string; base_model?: string | null; source?: "training" | "exported" | null; - export_type?: "lora" | "merged" | "gguf" | null; + export_type?: "lora" | "merged" | null; } export interface ListLorasResponse { diff --git a/studio/frontend/src/features/chat/types/runtime.ts b/studio/frontend/src/features/chat/types/runtime.ts index 710898713b..953f4ebbaa 100644 --- a/studio/frontend/src/features/chat/types/runtime.ts +++ b/studio/frontend/src/features/chat/types/runtime.ts @@ -35,5 +35,5 @@ export interface ChatLoraSummary { baseModel: string; updatedAt?: number; source?: "training" | "exported"; - exportType?: "lora" | "merged" | "gguf"; + exportType?: "lora" | "merged"; } From cd7bdf42248ab111505d17ee023c58a83dacab93 Mon Sep 17 00:00:00 2001 From: Manan17 Date: Fri, 27 Feb 2026 04:35:52 +0000 Subject: [PATCH 10/17] rebuild llama cpp for setup --- setup.sh | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/setup.sh b/setup.sh index 368d62eb2f..8314ef6d75 100755 --- a/setup.sh +++ b/setup.sh @@ -224,11 +224,10 @@ fi # unsloth-zoo's GGUF export pipeline. We build: # - llama-server: for GGUF model inference # - llama-quantize: for GGUF export quantization (symlinked to root for check_llama_cpp()) -LLAMA_SERVER_BIN="$SCRIPT_DIR/llama.cpp/build/bin/llama-server" -if [ -f "$LLAMA_SERVER_BIN" ]; then - echo "" - echo "✅ llama-server already exists at $LLAMA_SERVER_BIN" -else +LLAMA_CPP_DIR="$SCRIPT_DIR/llama.cpp" +LLAMA_SERVER_BIN="$LLAMA_CPP_DIR/build/bin/llama-server" +rm -rf "$LLAMA_CPP_DIR" +{ # Check prerequisites if ! command -v cmake &>/dev/null; then echo "" @@ -240,17 +239,9 @@ else else echo "" echo "Building llama-server for GGUF inference..." - LLAMA_CPP_DIR="$SCRIPT_DIR/llama.cpp" BUILD_OK=true - if [ -d "$LLAMA_CPP_DIR/.git" ]; then - echo " llama.cpp repo already cloned, pulling latest..." - run_quiet "pull llama.cpp" git -C "$LLAMA_CPP_DIR" pull || true - else - # Remove any non-git llama.cpp directory (stale build artifacts) - rm -rf "$LLAMA_CPP_DIR" - run_quiet "clone llama.cpp" git clone --depth 1 https://github.com/ggml-org/llama.cpp.git "$LLAMA_CPP_DIR" || BUILD_OK=false - fi + run_quiet "clone llama.cpp" git clone --depth 1 https://github.com/ggml-org/llama.cpp.git "$LLAMA_CPP_DIR" || BUILD_OK=false if [ "$BUILD_OK" = true ]; then CMAKE_ARGS="" @@ -309,7 +300,7 @@ else echo "⚠️ llama-server build failed — GGUF inference won't be available, but everything else works" fi fi -fi +} # ── 9. Add shell alias (skip in Colab) ── # Note: venv activation does NOT persist across terminal sessions. From 4aecfb80d4f48b8cb98a2cd70ebb847692b53b19 Mon Sep 17 00:00:00 2001 From: imagineer99 Date: Fri, 27 Feb 2026 06:16:26 +0000 Subject: [PATCH 11/17] fix: reorder model type cards in onboarding to show Text first --- studio/frontend/src/config/training.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/studio/frontend/src/config/training.ts b/studio/frontend/src/config/training.ts index 33249a044a..4df5107022 100644 --- a/studio/frontend/src/config/training.ts +++ b/studio/frontend/src/config/training.ts @@ -39,6 +39,11 @@ export const MODEL_TYPES: ReadonlyArray<{ label: string; description: string; }> = [ + { + value: "text", + label: "Text", + description: "Language models", + }, { value: "vision", label: "Vision", @@ -54,11 +59,6 @@ export const MODEL_TYPES: ReadonlyArray<{ label: "Embeddings", description: "Text embedding models", }, - { - value: "text", - label: "Text", - description: "Language models", - }, ]; export const CONTEXT_LENGTHS = [512, 1024, 2048, 4096, 8192, 16384, 32768]; From 2fea4cadd319efb0d68869c790a2ad7764004935 Mon Sep 17 00:00:00 2001 From: Manan17 Date: Fri, 27 Feb 2026 00:15:25 +0000 Subject: [PATCH 12/17] Passes metadata to get model size --- studio/backend/utils/models/model_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/studio/backend/utils/models/model_config.py b/studio/backend/utils/models/model_config.py index 8bb9e60ed2..88cc997d81 100644 --- a/studio/backend/utils/models/model_config.py +++ b/studio/backend/utils/models/model_config.py @@ -530,7 +530,7 @@ def list_gguf_variants( """ from huggingface_hub import model_info as hf_model_info - info = hf_model_info(repo_id, token=hf_token) + info = hf_model_info(repo_id, token=hf_token, files_metadata=True) variants: list[GgufVariantInfo] = [] has_vision = False From b18a14d36908db5c0257b0220c426c6a5ddffd71 Mon Sep 17 00:00:00 2001 From: samit Date: Fri, 27 Feb 2026 00:20:36 -0800 Subject: [PATCH 13/17] added auth to inference endpoints --- studio/backend/routes/inference.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/studio/backend/routes/inference.py b/studio/backend/routes/inference.py index bc450add0d..ab29f1eeb0 100644 --- a/studio/backend/routes/inference.py +++ b/studio/backend/routes/inference.py @@ -5,7 +5,7 @@ import sys import time import uuid from pathlib import Path -from fastapi import APIRouter, HTTPException, Request +from fastapi import APIRouter, Depends, HTTPException, Request from fastapi.responses import StreamingResponse, JSONResponse from typing import Optional import json @@ -50,6 +50,7 @@ from models.inference import ( CompletionChoice, CompletionMessage, ) +from auth.authentication import get_current_subject router = APIRouter() logger = logging.getLogger(__name__) @@ -71,7 +72,10 @@ def get_llama_cpp_backend() -> LlamaCppBackend: @router.post("/load", response_model=LoadResponse) -async def load_model(request: LoadRequest): +async def load_model( + request: LoadRequest, + current_subject: str = Depends(get_current_subject), +): """ Load a model for inference. @@ -194,7 +198,10 @@ async def load_model(request: LoadRequest): @router.post("/unload", response_model=UnloadResponse) -async def unload_model(request: UnloadRequest): +async def unload_model( + request: UnloadRequest, + current_subject: str = Depends(get_current_subject), +): """ Unload a model from memory. Routes to the correct backend (llama-server for GGUF, Unsloth otherwise). @@ -222,7 +229,10 @@ async def unload_model(request: UnloadRequest): @router.post("/generate/stream") -async def generate_stream(request: GenerateRequest): +async def generate_stream( + request: GenerateRequest, + current_subject: str = Depends(get_current_subject), +): """ Generate a chat response with Server-Sent Events (SSE) streaming. @@ -295,7 +305,9 @@ async def generate_stream(request: GenerateRequest): @router.get("/status", response_model=InferenceStatusResponse) -async def get_status(): +async def get_status( + current_subject: str = Depends(get_current_subject), +): """ Get current inference backend status. Reports whichever backend (Unsloth or llama-server) is currently active. @@ -398,7 +410,11 @@ def _extract_content_parts( @router.post("/chat/completions") -async def openai_chat_completions(payload: ChatCompletionRequest, request: Request): +async def openai_chat_completions( + payload: ChatCompletionRequest, + request: Request, + current_subject: str = Depends(get_current_subject), +): """ OpenAI-compatible chat completions endpoint. From 168957a87af4f1607966c8a81fba0eefc1fd5218 Mon Sep 17 00:00:00 2001 From: Manan17 Date: Fri, 27 Feb 2026 08:23:15 +0000 Subject: [PATCH 14/17] Aggregating sharded models, showing fit/oom for quantizations --- studio/backend/core/inference/llama_cpp.py | 4 ++ studio/backend/models/inference.py | 1 + studio/backend/routes/inference.py | 1 + studio/backend/utils/models/model_config.py | 41 ++++++++---- .../assistant-ui/model-selector.tsx | 14 +++- .../assistant-ui/model-selector/pickers.tsx | 65 ++++++++++++------- .../frontend/src/features/chat/chat-page.tsx | 9 ++- .../chat/hooks/use-chat-model-runtime.ts | 9 +-- .../chat/stores/chat-runtime-store.ts | 8 ++- .../frontend/src/features/chat/types/api.ts | 1 + 10 files changed, 105 insertions(+), 48 deletions(-) diff --git a/studio/backend/core/inference/llama_cpp.py b/studio/backend/core/inference/llama_cpp.py index 30fe660404..68bf871590 100644 --- a/studio/backend/core/inference/llama_cpp.py +++ b/studio/backend/core/inference/llama_cpp.py @@ -62,6 +62,10 @@ class LlamaCppBackend: def is_vision(self) -> bool: return self._is_vision + @property + def hf_variant(self) -> Optional[str]: + return self._hf_variant + # ── Binary discovery ────────────────────────────────────────── @staticmethod diff --git a/studio/backend/models/inference.py b/studio/backend/models/inference.py index fc3f788ac6..3a908dcfc3 100644 --- a/studio/backend/models/inference.py +++ b/studio/backend/models/inference.py @@ -59,6 +59,7 @@ class InferenceStatusResponse(BaseModel): active_model: Optional[str] = Field(None, description="Currently active model identifier") is_vision: bool = Field(False, description="Whether the active model is a vision model") is_gguf: bool = Field(False, description="Whether the active model is a GGUF model (llama.cpp)") + gguf_variant: Optional[str] = Field(None, description="GGUF quantization variant (e.g. Q4_K_M)") loading: List[str] = Field(default_factory=list, description="Models currently being loaded") loaded: List[str] = Field(default_factory=list, description="Models currently loaded") diff --git a/studio/backend/routes/inference.py b/studio/backend/routes/inference.py index bc450add0d..c685a3ab10 100644 --- a/studio/backend/routes/inference.py +++ b/studio/backend/routes/inference.py @@ -309,6 +309,7 @@ async def get_status(): active_model=llama_backend.model_identifier, is_vision=llama_backend.is_vision, is_gguf=True, + gguf_variant=llama_backend.hf_variant, loading=[], loaded=[llama_backend.model_identifier], ) diff --git a/studio/backend/utils/models/model_config.py b/studio/backend/utils/models/model_config.py index 88cc997d81..b84a14d226 100644 --- a/studio/backend/utils/models/model_config.py +++ b/studio/backend/utils/models/model_config.py @@ -491,21 +491,28 @@ def _extract_quant_label(filename: str) -> str: Extract quantization label like Q4_K_M, IQ4_XS, BF16 from a GGUF filename. Examples: - "gemma-3-4b-it-Q4_K_M.gguf" → "Q4_K_M" - "model-IQ4_NL.gguf" → "IQ4_NL" - "model-BF16.gguf" → "BF16" - "model-UD-IQ1_S.gguf" → "UD-IQ1_S" + "gemma-3-4b-it-Q4_K_M.gguf" → "Q4_K_M" + "model-IQ4_NL.gguf" → "IQ4_NL" + "model-BF16.gguf" → "BF16" + "model-UD-IQ1_S.gguf" → "UD-IQ1_S" + "model-UD-TQ1_0.gguf" → "UD-TQ1_0" + "MXFP4_MOE/model-MXFP4_MOE-0001.gguf"→ "MXFP4_MOE" """ import re - stem = filename.rsplit(".", 1)[0] # Remove .gguf - # Match known quantization patterns (UD- prefix, IQ, Q, BF/F variants) + # Use only the basename (rfilename may include directory) + basename = filename.rsplit("/", 1)[-1] + # Strip .gguf and any shard suffix (-00001-of-00010) + stem = re.sub(r'-\d{3,}-of-\d{3,}', '', basename.rsplit(".", 1)[0]) + # Match known quantization patterns match = re.search( r'(UD-)?' # Optional UD- prefix (Ultra Discrete) - r'(IQ[0-9]+_[A-Z]+(?:_[A-Z0-9]+)?' # IQ variants: IQ4_XS, IQ4_NL, IQ1_S - r'|Q[0-9]+_K_[A-Z]+' # K-quant: Q4_K_M, Q3_K_S - r'|Q[0-9]+_[0-9]+' # Standard: Q8_0, Q5_1 - r'|Q[0-9]+_K' # Short K-quant: Q6_K - r'|BF16|F16|F32)', # Full precision + r'(MXFP[0-9]+(?:_[A-Z0-9]+)*' # MXFP variants: MXFP4, MXFP4_MOE + r'|IQ[0-9]+_[A-Z]+(?:_[A-Z0-9]+)?' # IQ variants: IQ4_XS, IQ4_NL, IQ1_S + r'|TQ[0-9]+_[0-9]+' # Ternary quant: TQ1_0, TQ2_0 + r'|Q[0-9]+_K_[A-Z]+' # K-quant: Q4_K_M, Q3_K_S + r'|Q[0-9]+_[0-9]+' # Standard: Q8_0, Q5_1 + r'|Q[0-9]+_K' # Short K-quant: Q6_K + r'|BF16|F16|F32)', # Full precision stem, re.IGNORECASE, ) if match: @@ -534,6 +541,9 @@ def list_gguf_variants( variants: list[GgufVariantInfo] = [] has_vision = False + quant_totals: dict[str, int] = {} # quant -> total bytes + quant_first_file: dict[str, str] = {} # quant -> first filename (for display) + for sibling in info.siblings: fname = sibling.rfilename if not fname.endswith(".gguf"): @@ -546,10 +556,15 @@ def list_gguf_variants( continue quant = _extract_quant_label(fname) + quant_totals[quant] = quant_totals.get(quant, 0) + size + if quant not in quant_first_file: + quant_first_file[quant] = fname + + for quant, total_size in quant_totals.items(): variants.append(GgufVariantInfo( - filename=fname, + filename=quant_first_file[quant], quant=quant, - size_bytes=size, + size_bytes=total_size, )) return variants, has_vision diff --git a/studio/frontend/src/components/assistant-ui/model-selector.tsx b/studio/frontend/src/components/assistant-ui/model-selector.tsx index d470034832..c6685f0214 100644 --- a/studio/frontend/src/components/assistant-ui/model-selector.tsx +++ b/studio/frontend/src/components/assistant-ui/model-selector.tsx @@ -27,6 +27,7 @@ interface ModelSelectorProps { loraModels?: LoraModelOption[]; value?: string; defaultValue?: string; + activeGgufVariant?: string | null; onValueChange?: (value: string, meta: ModelSelectorChangeMeta) => void; onEject?: () => void; variant?: "outline" | "ghost" | "muted"; @@ -158,6 +159,7 @@ export function ModelSelector({ loraModels = [], value, defaultValue, + activeGgufVariant, onValueChange, onEject, variant = "outline", @@ -202,9 +204,15 @@ export function ModelSelector({ return all; }, [loraModels, models]); - const currentModel = selected - ? optionById.get(selected) ?? { id: selected, name: selected } - : undefined; + const currentModel = useMemo(() => { + if (!selected) return undefined; + const found = optionById.get(selected); + if (activeGgufVariant) { + const desc = `GGUF · ${activeGgufVariant}`; + return found ? { ...found, description: desc } : { id: selected, name: selected, description: desc }; + } + return found ?? { id: selected, name: selected }; + }, [selected, optionById, activeGgufVariant]); function handleSelect(id: string, meta: ModelSelectorChangeMeta) { if (onValueChange) { diff --git a/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx b/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx index 26f0e6e028..ca1e6c73d0 100644 --- a/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx +++ b/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx @@ -130,9 +130,11 @@ function ModelRow({ function GgufVariantExpander({ repoId, onSelect, + gpuGb, }: { repoId: string; onSelect: (id: string, meta: ModelSelectorChangeMeta) => void; + gpuGb?: number; }) { const [variants, setVariants] = useState(null); const [defaultVariant, setDefaultVariant] = useState(null); @@ -209,28 +211,45 @@ function GgufVariantExpander({ Vision )} - {variants.map((v) => ( - - ))} + > + + {v.quant} + {v.quant === defaultVariant && ( + + recommended + + )} + + + {fitStatus === "exceeds" && ( + OOM + )} + {fitStatus === "tight" && ( + TIGHT + )} + {fitStatus === "fits" && ( + FIT + )} + + {formatBytes(v.size_bytes)} + + + + ); + })} ); } @@ -390,7 +409,7 @@ export function HubModelPicker({ gpuGb={gpu.available ? gpu.memoryTotalGb : undefined} /> {expandedGguf === id && ( - + )} ); @@ -425,7 +444,7 @@ export function HubModelPicker({ gpuGb={gpu.available ? gpu.memoryTotalGb : undefined} /> {expandedGguf === id && ( - + )} ); diff --git a/studio/frontend/src/features/chat/chat-page.tsx b/studio/frontend/src/features/chat/chat-page.tsx index 7e986721ab..14a457ad76 100644 --- a/studio/frontend/src/features/chat/chat-page.tsx +++ b/studio/frontend/src/features/chat/chat-page.tsx @@ -314,6 +314,7 @@ export function ChatPage(): ReactElement { ); const inferenceParams = useChatRuntimeStore((state) => state.params); const setInferenceParams = useChatRuntimeStore((state) => state.setParams); + const activeGgufVariant = useChatRuntimeStore((state) => state.activeGgufVariant); const autoTitle = useChatRuntimeStore((state) => state.autoTitle); const setAutoTitle = useChatRuntimeStore((state) => state.setAutoTitle); const modelsFromStore = useChatRuntimeStore((state) => state.models); @@ -336,9 +337,10 @@ export function ChatPage(): ReactElement { const handleCheckpointChange = useCallback( (value: string, meta?: { isLora: boolean; ggufVariant?: string }) => { - const currentCheckpoint = - useChatRuntimeStore.getState().params.checkpoint; - if (!value || value === currentCheckpoint) return; + const store = useChatRuntimeStore.getState(); + const currentCheckpoint = store.params.checkpoint; + const currentVariant = store.activeGgufVariant; + if (!value || (value === currentCheckpoint && (meta?.ggufVariant ?? null) === (currentVariant ?? null))) return; void (async () => { let switchNote: string | undefined; const activeThreadId = await resolveActiveSingleThreadId(view); @@ -591,6 +593,7 @@ export function ChatPage(): ReactElement { models={models} loraModels={loraModels} value={inferenceParams.checkpoint} + activeGgufVariant={activeGgufVariant} onValueChange={handleCheckpointChange} onEject={handleEject} variant="ghost" diff --git a/studio/frontend/src/features/chat/hooks/use-chat-model-runtime.ts b/studio/frontend/src/features/chat/hooks/use-chat-model-runtime.ts index a0ea17e304..fece047cd8 100644 --- a/studio/frontend/src/features/chat/hooks/use-chat-model-runtime.ts +++ b/studio/frontend/src/features/chat/hooks/use-chat-model-runtime.ts @@ -144,7 +144,7 @@ export function useChatModelRuntime() { setLoras(lorasRes.loras.map(toLoraSummary)); if (statusRes.active_model) { - setCheckpoint(statusRes.active_model); + setCheckpoint(statusRes.active_model, statusRes.gguf_variant); } } catch (error) { const message = @@ -159,14 +159,15 @@ export function useChatModelRuntime() { const selectModel = useCallback( async (selection: string | SelectedModelInput) => { const modelId = typeof selection === "string" ? selection : selection.id; - if (!modelId || params.checkpoint === modelId) { + const ggufVariant = + typeof selection === "string" ? undefined : selection.ggufVariant; + const currentVariant = useChatRuntimeStore.getState().activeGgufVariant; + if (!modelId || (params.checkpoint === modelId && (ggufVariant ?? null) === (currentVariant ?? null))) { return; } const explicitIsLora = typeof selection === "string" ? undefined : selection.isLora; - const ggufVariant = - typeof selection === "string" ? undefined : selection.ggufVariant; const extraLoadingDescription = typeof selection === "string" ? undefined : selection.loadingDescription; const model = models.find((entry) => entry.id === modelId); diff --git a/studio/frontend/src/features/chat/stores/chat-runtime-store.ts b/studio/frontend/src/features/chat/stores/chat-runtime-store.ts index 03825b5861..2e3b43d606 100644 --- a/studio/frontend/src/features/chat/stores/chat-runtime-store.ts +++ b/studio/frontend/src/features/chat/stores/chat-runtime-store.ts @@ -39,13 +39,14 @@ type ChatRuntimeStore = { runningByThreadId: Record; autoTitle: boolean; modelsError: string | null; + activeGgufVariant: string | null; setParams: (params: InferenceParams) => void; setModels: (models: ChatModelSummary[]) => void; setLoras: (loras: ChatLoraSummary[]) => void; setThreadRunning: (threadId: string, running: boolean) => void; setAutoTitle: (enabled: boolean) => void; setModelsError: (error: string | null) => void; - setCheckpoint: (modelId: string) => void; + setCheckpoint: (modelId: string, ggufVariant?: string | null) => void; clearCheckpoint: () => void; }; @@ -56,6 +57,7 @@ export const useChatRuntimeStore = create((set) => ({ runningByThreadId: {}, autoTitle: loadBool(AUTO_TITLE_KEY, false), modelsError: null, + activeGgufVariant: null, setParams: (params) => set({ params }), setModels: (models) => set({ models }), setLoras: (loras) => set({ loras }), @@ -75,12 +77,13 @@ export const useChatRuntimeStore = create((set) => ({ return { autoTitle }; }), setModelsError: (modelsError) => set({ modelsError }), - setCheckpoint: (modelId) => + setCheckpoint: (modelId, ggufVariant) => set((state) => ({ params: { ...state.params, checkpoint: modelId, }, + activeGgufVariant: ggufVariant ?? null, })), clearCheckpoint: () => set((state) => ({ @@ -88,5 +91,6 @@ export const useChatRuntimeStore = create((set) => ({ ...state.params, checkpoint: "", }, + activeGgufVariant: null, })), })); diff --git a/studio/frontend/src/features/chat/types/api.ts b/studio/frontend/src/features/chat/types/api.ts index d0b37f5cce..edf8fecae3 100644 --- a/studio/frontend/src/features/chat/types/api.ts +++ b/studio/frontend/src/features/chat/types/api.ts @@ -69,6 +69,7 @@ export interface InferenceStatusResponse { active_model: string | null; is_vision: boolean; is_gguf?: boolean; + gguf_variant?: string | null; loading: string[]; loaded: string[]; } From 6d74943dea7d897e5036cf1f7b305d8fc72b07b0 Mon Sep 17 00:00:00 2001 From: Shine1i Date: Fri, 27 Feb 2026 10:36:07 +0100 Subject: [PATCH 15/17] keep checkpoint on preset apply --- studio/frontend/src/features/chat/chat-settings-sheet.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/studio/frontend/src/features/chat/chat-settings-sheet.tsx b/studio/frontend/src/features/chat/chat-settings-sheet.tsx index 4bfc3351e8..e70b24fb54 100644 --- a/studio/frontend/src/features/chat/chat-settings-sheet.tsx +++ b/studio/frontend/src/features/chat/chat-settings-sheet.tsx @@ -166,7 +166,11 @@ export function ChatSettingsPanel({ function applyPreset(name: string) { const p = presets.find((pr) => pr.name === name); if (p) { - onParamsChange({ ...p.params, systemPrompt: params.systemPrompt }); + onParamsChange({ + ...p.params, + systemPrompt: params.systemPrompt, + checkpoint: params.checkpoint, + }); setActivePreset(name); } } From 49c319c2f78195d0da52809cad9c3c9a3eb8d514 Mon Sep 17 00:00:00 2001 From: imagineer99 Date: Fri, 27 Feb 2026 11:31:53 +0000 Subject: [PATCH 16/17] fix: only apply HF task filter for empty model search queries --- studio/frontend/src/hooks/use-hf-model-search.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/studio/frontend/src/hooks/use-hf-model-search.ts b/studio/frontend/src/hooks/use-hf-model-search.ts index 8fc0b32cf8..dd5f9cf8a7 100644 --- a/studio/frontend/src/hooks/use-hf-model-search.ts +++ b/studio/frontend/src/hooks/use-hf-model-search.ts @@ -133,8 +133,8 @@ export function useHfModelSearch( ...(accessToken ? { credentials: { accessToken } } : {}), }) as AsyncGenerator; } - // Dual-query: unsloth first, then general - return mergedModelIterator(trimmed, task, accessToken) as AsyncGenerator; + // Typed query: disable task filter so explicitly searched models still appear even if HF task metadata is wrong/missing. + return mergedModelIterator(trimmed, undefined, accessToken) as AsyncGenerator; }, [query, task, accessToken], ); From ce33d673b90e7cf98a033a6cf7fa022a560d356a Mon Sep 17 00:00:00 2001 From: Shine1i Date: Fri, 27 Feb 2026 20:00:46 +0100 Subject: [PATCH 17/17] feat(markdown): fix Mermaid integration with error handling and copy button --- studio/frontend/package.json | 4 +- .../components/assistant-ui/markdown-text.tsx | 81 ++++++++++++++++++- .../src/components/markdown/mermaid-error.tsx | 28 +++++++ 3 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 studio/frontend/src/components/markdown/mermaid-error.tsx diff --git a/studio/frontend/package.json b/studio/frontend/package.json index f4b636c2c6..3d6881cc53 100644 --- a/studio/frontend/package.json +++ b/studio/frontend/package.json @@ -66,7 +66,7 @@ "remark-gfm": "^4.0.1", "shadcn": "^3.8.4", "sonner": "^2.0.7", - "streamdown": "^2.2.0", + "streamdown": "^2.3.0", "tailwind-merge": "^3.4.0", "tailwindcss": "^4.1.18", "tw-animate-css": "^1.4.0", @@ -90,4 +90,4 @@ "typescript-eslint": "^8.55.0", "vite": "^7.3.1" } -} \ No newline at end of file +} diff --git a/studio/frontend/src/components/assistant-ui/markdown-text.tsx b/studio/frontend/src/components/assistant-ui/markdown-text.tsx index 3f18cfb940..a3f07ab885 100644 --- a/studio/frontend/src/components/assistant-ui/markdown-text.tsx +++ b/studio/frontend/src/components/assistant-ui/markdown-text.tsx @@ -1,14 +1,83 @@ "use client"; import { INTERNAL, useMessagePartText } from "@assistant-ui/react"; +import { copyToClipboard } from "@/lib/copy-to-clipboard"; +import { Copy02Icon, Tick02Icon } from "@hugeicons/core-free-icons"; +import { HugeiconsIcon } from "@hugeicons/react"; import { code } from "@streamdown/code"; import { math } from "@streamdown/math"; import { mermaid } from "@streamdown/mermaid"; -import { Streamdown } from "streamdown"; +import { Block, type BlockProps, Streamdown } from "streamdown"; +import { useEffect, useRef, useState } from "react"; import "katex/dist/katex.min.css"; const { withSmoothContextProvider, useSmoothStatus } = INTERNAL; +function getMermaidSource(blockContent: string): string | null { + const source = blockContent.match(/```mermaid\s*([\s\S]*?)```/i)?.[1]?.trim(); + return source && source.length > 0 ? source : null; +} + +const COPY_RESET_MS = 2000; + +function MermaidCopyButton({ source }: { source: string }) { + const [copied, setCopied] = useState(false); + const resetTimeoutRef = useRef | null>(null); + + useEffect(() => { + return () => { + if (resetTimeoutRef.current) { + clearTimeout(resetTimeoutRef.current); + } + }; + }, []); + + return ( + + ); +} + +function StreamdownBlock(props: BlockProps) { + const hasMermaidFence = props.content.includes("```mermaid"); + const mermaidSource = getMermaidSource(props.content); + + if (props.isIncomplete && hasMermaidFence) { + return ( +
+ Loading diagram... +
+ ); + } + + if (mermaidSource) { + return ( +
+ + +
+ ); + } + + return ; +} + const MarkdownTextImpl = () => { const { text } = useMessagePartText(); const status = useSmoothStatus(); @@ -19,8 +88,16 @@ const MarkdownTextImpl = () => { mode="streaming" isAnimating={status.type === "running"} plugins={{ code, math, mermaid }} - controls={true} + controls={{ + mermaid: { + fullscreen: true, + download: true, + copy: false, + panZoom: true, + }, + }} shikiTheme={["github-light", "github-dark"]} + BlockComponent={StreamdownBlock} > {text} diff --git a/studio/frontend/src/components/markdown/mermaid-error.tsx b/studio/frontend/src/components/markdown/mermaid-error.tsx new file mode 100644 index 0000000000..4e352d4768 --- /dev/null +++ b/studio/frontend/src/components/markdown/mermaid-error.tsx @@ -0,0 +1,28 @@ +import type { MermaidErrorComponentProps } from "streamdown"; + +function hasSlashComment(chart: string): boolean { + return /(^|[^:])\/\/.*/m.test(chart); +} + +export function MermaidError({ + error, + chart, + retry, +}: MermaidErrorComponentProps) { + return ( +
+

Mermaid render failed

+

{error}

+ {hasSlashComment(chart) ? ( +

Hint: Mermaid comments use `%%`, not `//`.

+ ) : null} + +
+ ); +}