helloadhavan/github_issues huggingface dataset:
Repository: electron/electron
Pull request: perf: have `ErrorThrower` lazily lookup the current isolate

Backport of #46388

See that PR for details.


Notes: none.

Changed files:
filename: shell/common/gin_helper/error_thrower.cc
patch: @@ -10,12 +10,11 @@
 
 namespace gin_helper {
 
-ErrorThrower::ErrorThrower(v8::Isolate* isolate) : isolate_(isolate) {}
-
-// This constructor should be rarely if ever used, since
-// v8::Isolate::GetCurrent() uses atomic loads and is thus a bit
-// costly to invoke
-ErrorThrower::ErrorThrower() : isolate_(v8::Isolate::GetCurrent()) {}
+v8::Isolate* ErrorThrower::isolate() const {
+  // Callers should prefer to specify the isolate in the constructor,
+  // since GetCurrent() uses atomic loads and is thus a bit costly to invoke
+  return isolate_ ? isolate_.get() : v8::Isolate::GetCurrent();
+}
 
 void ErrorThrower::ThrowError(const std::string_view err_msg) const {
   Throw(v8::Exception::Error, err_msg);
@@ -39,9 +38,10 @@ void ErrorThrower::ThrowSyntaxError(const std::string_view err_msg) const {
 
 void ErrorThrower::Throw(ErrorGenerator gen,
                          const std::string_view err_msg) const {
-  v8::Local<v8::Value> exception = gen(gin::StringToV8(isolate_, err_msg), {});
-  if (!isolate_->IsExecutionTerminating())
-    isolate_->ThrowException(exception);
+  v8::Isolate* isolate = this->isolate();
+
+  if (!isolate->IsExecutionTerminating())
+    isolate->ThrowException(gen(gin::StringToV8(isolate, err_msg), {}));
 }
 
 }  // namespace gin_helper

filename: shell/common/gin_helper/error_thrower.h
patch: @@ -14,8 +14,8 @@ namespace gin_helper {
 
 class ErrorThrower {
  public:
-  explicit ErrorThrower(v8::Isolate* isolate);
-  ErrorThrower();
+  constexpr explicit ErrorThrower(v8::Isolate* isolate) : isolate_{isolate} {}
+  constexpr ErrorThrower() = default;
   ~ErrorThrower() = default;
 
   void ThrowError(std::string_view err_msg) const;
@@ -24,14 +24,14 @@ class ErrorThrower {
   void ThrowReferenceError(std::string_view err_msg) const;
   void ThrowSyntaxError(std::string_view err_msg) const;
 
-  v8::Isolate* isolate() const { return isolate_; }
+  v8::Isolate* isolate() const;
 
  private:
   using ErrorGenerator = v8::Local<v8::Value> (*)(v8::Local<v8::String> err_msg,
                                                   v8::Local<v8::Value> options);
   void Throw(ErrorGenerator gen, std::string_view err_msg) const;
 
-  raw_ptr<v8::Isolate> isolate_;
+  raw_ptr<v8::Isolate> isolate_ = {};
 };
 
 }  // namespace gin_helper
Repository: vercel/next.js
Pull request: Turbopack: run snapshot in normal task instead of blocking task

### What?

Following the guideline that all CPU work should happen on a normal task.

Closes PACK-5262

Changed files:
filename: turbopack/crates/turbo-tasks-backend/src/backend/mod.rs
patch: @@ -2172,7 +2172,7 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
                     }
 
                     let this = self.clone();
-                    let snapshot = turbo_tasks::spawn_blocking(move || this.snapshot()).await;
+                    let snapshot = this.snapshot();
                     if let Some((snapshot_start, new_data)) = snapshot {
                         last_snapshot = snapshot_start;
                         if new_data {
Repository: ollama/ollama
Pull request: create the blobs directory correctly


Changed files:
filename: server/modelpath.go
patch: @@ -133,7 +133,12 @@ func GetBlobsPath(digest string) (string, error) {
 	}
 
 	path := filepath.Join(home, ".ollama", "models", "blobs", digest)
-	if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
+	dirPath := filepath.Dir(path)
+	if digest == "" {
+		dirPath = path
+	}
+
+	if err := os.MkdirAll(dirPath, 0o755); err != nil {
 		return "", err
 	}
Repository: denoland/deno
Pull request: fix(bundle): don't error when using npm package without bin as entrypoint

Fixes #30266.

Changed files:
filename: cli/tools/bundle/mod.rs
patch: @@ -1093,9 +1093,12 @@ fn resolve_roots(
         let package_folder = npm_resolver
           .resolve_pkg_folder_from_deno_module_req(v.req(), &referrer)
           .unwrap();
-        let main_module = node_resolver
-          .resolve_binary_export(&package_folder, v.sub_path())
-          .unwrap();
+        let Ok(main_module) =
+          node_resolver.resolve_binary_export(&package_folder, v.sub_path())
+        else {
+          roots.push(url);
+          continue;
+        };
         Url::from_file_path(&main_module).unwrap()
       }
       _ => url,

filename: tests/specs/bundle/npm_no_bin_entry/__test__.jsonc
patch: @@ -0,0 +1,13 @@
+{
+  "tempDir": true,
+  "steps": [
+    {
+      "args": "bundle -o add.cjs --format=cjs npm:@denotest/add@1.0.0",
+      "output": "bundle.out"
+    },
+    {
+      "args": "run -A main.ts",
+      "output": "3\n"
+    }
+  ]
+}

filename: tests/specs/bundle/npm_no_bin_entry/bundle.out
patch: @@ -0,0 +1,4 @@
+[WILDCARD]
+Bundled 1 module in [WILDLINE]
+  add.cjs [WILDLINE]
+

filename: tests/specs/bundle/npm_no_bin_entry/main.ts
patch: @@ -0,0 +1,3 @@
+import add from "./add.cjs";
+
+console.log(add.add(1, 2));
Repository: ollama/ollama
Pull request: Add `format` to model config layer


Changed files:
filename: server/images.go
patch: @@ -116,6 +116,7 @@ type LayerReader struct {
 type ConfigV2 struct {
 	ModelFamily llm.ModelFamily `json:"model_family"`
 	ModelType   string          `json:"model_type"`
+	ModelFormat string          `json:"model_format"`
 	FileType    string          `json:"file_type"`
 	RootFS      RootFS          `json:"rootfs"`
 
@@ -335,6 +336,7 @@ func CreateModel(ctx context.Context, name string, path string, fn func(resp api
 
 					config.ModelFamily = ggml.ModelFamily()
 					config.ModelType = ggml.ModelType().String()
+					config.ModelFormat = ggml.Name()
 					config.FileType = ggml.FileType().String()
 
 					// reset the file
@@ -369,6 +371,7 @@ func CreateModel(ctx context.Context, name string, path string, fn func(resp api
 				// copie the model metadata
 				config.ModelFamily = source.ModelFamily
 				config.ModelType = source.ModelType
+				config.ModelFormat = source.ModelFormat
 				config.FileType = source.FileType
 
 				for _, l := range mf.Layers {
Repository: ggml-org/llama.cpp
Pull request: ggml-alloc : fix leak when reusing a tensor with a larger size


Changed files:
filename: ggml/src/ggml-alloc.c
patch: @@ -598,6 +598,26 @@ static bool ggml_gallocr_is_allocated(ggml_gallocr_t galloc, struct ggml_tensor
     return t->data != NULL || ggml_gallocr_hash_get(galloc, t)->allocated;
 }
 
+// free the extra space at the end if the new tensor is smaller
+static void ggml_gallocr_free_extra_space(ggml_gallocr_t galloc, struct ggml_tensor * node, struct ggml_tensor * parent) {
+    struct hash_node * hn = ggml_gallocr_hash_get(galloc, node);
+    struct hash_node * p_hn = ggml_gallocr_hash_get(galloc, parent);
+
+    size_t parent_size = ggml_backend_buft_get_alloc_size(galloc->bufts[p_hn->buffer_id], parent);
+    size_t node_size = ggml_backend_buft_get_alloc_size(galloc->bufts[hn->buffer_id], node);
+
+    GGML_ASSERT(parent_size >= node_size);
+
+    if (parent_size > node_size) {
+        struct ggml_dyn_tallocr * p_alloc = galloc->buf_tallocs[p_hn->buffer_id];
+        struct buffer_address p_addr = p_hn->addr;
+        p_addr.offset += node_size;
+        size_t extra_size = parent_size - node_size;
+        AT_PRINTF("freeing extra %zu bytes from parent %s for %s\n", extra_size, parent->name, node->name);
+        ggml_dyn_tallocr_free_tensor(p_alloc, p_addr, extra_size, parent);
+    }
+}
+
 static void ggml_gallocr_allocate_node(ggml_gallocr_t galloc, struct ggml_tensor * node, int buffer_id) {
     GGML_ASSERT(buffer_id >= 0);
     struct hash_node * hn = ggml_gallocr_hash_get(galloc, node);
@@ -643,13 +663,15 @@ static void ggml_gallocr_allocate_node(ggml_gallocr_t galloc, struct ggml_tensor
                             hn->addr = p_hn->addr;
                             p_hn->allocated = false; // avoid freeing the parent
                             view_src_hn->allocated = false;
+                            ggml_gallocr_free_extra_space(galloc, node, view_src);
                             return;
                         }
                     } else {
                         AT_PRINTF("reusing parent %s for %s\n", parent->name, node->name);
                         hn->buffer_id = p_hn->buffer_id;
                         hn->addr = p_hn->addr;
                         p_hn->allocated = false; // avoid freeing the parent
+                        ggml_gallocr_free_extra_space(galloc, node, parent);
                         return;
                     }
                 }
Repository: ollama/ollama
Pull request: remove file on digest mismatch

ideally this never happens (the download resume should prevent this), but if there is a digest mismatch the specific blob should be removed rather than the user manually removing it

related to #170 

Changed files:
filename: server/images.go
patch: @@ -700,6 +700,17 @@ func PullModel(name string, regOpts *RegistryOptions, fn func(api.ProgressRespon
 	fn(api.ProgressResponse{Status: "verifying sha256 digest"})
 	for _, layer := range layers {
 		if err := verifyBlob(layer.Digest); err != nil {
+			if errors.Is(err, errDigestMismatch) {
+				// something went wrong, delete the blob
+				fp, err := GetBlobsPath(layer.Digest)
+				if err != nil {
+					return err
+				}
+				if err := os.Remove(fp); err != nil {
+					// log this, but return the original error
+					log.Printf("couldn't remove file with digest mismatch '%s': %v", fp, err)
+				}
+			}
 			return err
 		}
 	}
@@ -1067,6 +1078,8 @@ func makeRequest(method, url string, headers map[string]string, body io.Reader,
 	return resp, nil
 }
 
+var errDigestMismatch = fmt.Errorf("digest mismatch, file must be downloaded again")
+
 func verifyBlob(digest string) error {
 	fp, err := GetBlobsPath(digest)
 	if err != nil {
@@ -1081,7 +1094,7 @@ func verifyBlob(digest string) error {
 
 	fileDigest, _ := GetSHA256Digest(f)
 	if digest != fileDigest {
-		return fmt.Errorf("digest mismatch: want %s, got %s", digest, fileDigest)
+		return fmt.Errorf("%w: want %s, got %s", errDigestMismatch, digest, fileDigest)
 	}
 
 	return nil
Repository: huggingface/transformers
Pull request: fix which routing method

# What does this PR do?
Fixes  #40031! Tested on both TP and DP
Run output:
```python
  arthur   transformers   fix-dp-gpt-oss ≢  ~1     cd /fsx/arthur/transformers ; /usr/bin/env /fsx/arthur/.venv/bin/python /admin/home/arthur/.vscode-server/extensions/ms-python.debugpy-2025.10.0-linux-x64/bundled/libs/debugpy/adapter/../../debugpy/launcher 40835 -- -m torch.distributed.run --nproc_per_node=4 /fsx/arthur/test_dequantize.py 

*****************************************
Setting OMP_NUM_THREADS environment variable for each process to be 1 in default, to avoid your system being overloaded, please further tune the variable for optimal performance in your application as needed. 
*****************************************
Loading checkpoint shards: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 9/9 [00:05<00:00,  1.64it/s]
Loading checkpoint shards: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 9/9 [00:05<00:00,  1.53it/s]
['Once upon a time in a kingdom faraway, there was a beautiful prince named Rohan. He had a magical garden']
Loading checkpoint shards: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 9/9 [00:06<00:00,  1.50it/s]
Loading checkpoint shards: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 9/9 [00:05<00:00,  1.58it/s]
['Once upon a time, in a kingdom far away\n\n**Title: "The Last King"**\n\n**Title**  \n']
['Once upon a time in the bustling city of Neo-Tokyo, a city that was the epitome where high-tech']
['Once upon a time, a kind and helpful friend named Yoonhee became "Sangha," the friend of all']
```

Changed files:
filename: src/transformers/integrations/mxfp4.py
patch: @@ -284,7 +284,7 @@ def topk(vals, k):
 def mlp_forward(self, hidden_states):
     import torch.distributed as dist
 
-    if dist.is_available() and dist.is_initialized():
+    if dist.is_available() and dist.is_initialized() and hasattr(self, "_is_hooked"):
         routing = routing_torch_dist
     else:
         routing = triton_kernels_hub.routing.routing
Repository: ollama/ollama
Pull request: truncate file size on resume

when resuming a download of a model truncate the file size to match the expected trunk size, hopefully this mitigates #170

Changed files:
filename: server/images.go
patch: @@ -939,6 +939,7 @@ func downloadBlob(mp ModelPath, digest string, regOpts *RegistryOptions, fn func
 	}
 
 	var size int64
+	chunkSize := 1024 * 1024 // 1 MiB in bytes
 
 	fi, err := os.Stat(fp + "-partial")
 	switch {
@@ -948,6 +949,13 @@ func downloadBlob(mp ModelPath, digest string, regOpts *RegistryOptions, fn func
 		return fmt.Errorf("stat: %w", err)
 	default:
 		size = fi.Size()
+		// Ensure the size is divisible by the chunk size by removing excess bytes
+		size -= size % int64(chunkSize)
+
+		err := os.Truncate(fp+"-partial", size)
+		if err != nil {
+			return fmt.Errorf("truncate: %w", err)
+		}
 	}
 
 	url := fmt.Sprintf("%s/v2/%s/blobs/%s", mp.Registry, mp.GetNamespaceRepository(), digest)
@@ -1008,7 +1016,7 @@ func downloadBlob(mp ModelPath, digest string, regOpts *RegistryOptions, fn func
 			break
 		}
 
-		n, err := io.CopyN(out, resp.Body, 8192)
+		n, err := io.CopyN(out, resp.Body, int64(chunkSize))
 		if err != nil && !errors.Is(err, io.EOF) {
 			return err
 		}
Repository: electron/electron
Pull request: build: make it clearer when cookie auth runs

Backport of #46406

See that PR for details.


Notes: none


Changed files:
filename: .github/actions/set-chromium-cookie/action.yml
patch: @@ -4,9 +4,14 @@ runs:
   using: "composite"
   steps:
   - name: Set the git cookie from chromium.googlesource.com (Unix)
-    if: ${{ runner.os != 'Windows' && env.CHROMIUM_GIT_COOKIE }}
+    if: ${{ runner.os != 'Windows' }}
     shell: bash
     run: |
+      if [[ -z "${{ env.CHROMIUM_GIT_COOKIE }}" ]]; then
+        echo "CHROMIUM_GIT_COOKIE is not set - cannot authenticate."
+        exit 0
+      fi
+
       eval 'set +o history' 2>/dev/null || setopt HIST_IGNORE_SPACE 2>/dev/null
       touch ~/.gitcookies
       chmod 0600 ~/.gitcookies
@@ -28,9 +33,14 @@ runs:
         echo $RESPONSE
       fi
   - name: Set the git cookie from chromium.googlesource.com (Windows)
-    if: ${{ runner.os == 'Windows' && env.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }}
+    if: ${{ runner.os == 'Windows' }}
     shell: cmd
     run: |
+      if "%CHROMIUM_GIT_COOKIE_WINDOWS_STRING%"=="" (
+        echo CHROMIUM_GIT_COOKIE_WINDOWS_STRING is not set - cannot authenticate.
+        exit /b 0
+      )
+
       git config --global http.cookiefile "%USERPROFILE%\.gitcookies"
       powershell -noprofile -nologo -command Write-Output "${{ env.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }}" >>"%USERPROFILE%\.gitcookies"
 

filename: .github/workflows/linux-publish.yml
patch: @@ -27,6 +27,7 @@ jobs:
         - /mnt/cross-instance-cache:/mnt/cross-instance-cache
         - /var/run/sas:/var/run/sas
     env:
+      CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
       GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
     steps:
     - name: Checkout Electron

filename: .github/workflows/macos-publish.yml
patch: @@ -28,6 +28,7 @@ jobs:
         - /mnt/cross-instance-cache:/mnt/cross-instance-cache
         - /var/run/sas:/var/run/sas
     env:
+      CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
       GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
     steps:
     - name: Checkout Electron

filename: .github/workflows/windows-publish.yml
patch: @@ -28,6 +28,7 @@ jobs:
         - /mnt/win-cache:/mnt/win-cache
         - /var/run/sas:/var/run/sas
     env:
+      CHROMIUM_GIT_COOKIE_WINDOWS_STRING: ${{ secrets.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }}
       GCLIENT_EXTRA_ARGS: '--custom-var=checkout_win=True'
       TARGET_OS: 'win'
       ELECTRON_DEPOT_TOOLS_WIN_TOOLCHAIN: '1'
Repository: nodejs/node
Pull request: doc: clarify x509.checkIssued only checks metadata

To avoid confusion thinking that relying solely on x509.checkIssued to verify the trust chain of certificates is enough.

<details>
<summary>See rendered change</summary>

<img width="1230" alt="image" src="https://github.com/user-attachments/assets/a8a1b38b-5621-4b33-8600-8f79dedba53a" />

</details>

Changed files:
filename: doc/api/crypto.md
patch: @@ -2651,7 +2651,23 @@ added: v15.6.0
 * `otherCert` {X509Certificate}
 * Returns: {boolean}
 
-Checks whether this certificate was issued by the given `otherCert`.
+Checks whether this certificate was potentially issued by the given `otherCert`
+by comparing the certificate metadata.
+
+This is useful for pruning a list of possible issuer certificates which have been
+selected using a more rudimentary filtering routine, i.e. just based on subject
+and issuer names.
+
+Finally, to verify that this certificate's signature was produced by a private key
+corresponding to `otherCert`'s public key use [`x509.verify(publicKey)`][]
+with `otherCert`'s public key represented as a [`KeyObject`][]
+like so
+
+```js
+if (!x509.verify(otherCert.publicKey)) {
+  throw new Error('otherCert did not issue x509');
+}
+```
 
 ### `x509.checkPrivateKey(privateKey)`
 
@@ -6205,6 +6221,7 @@ See the [list of SSL OP Flags][] for details.
 [`verify.update()`]: #verifyupdatedata-inputencoding
 [`verify.verify()`]: #verifyverifyobject-signature-signatureencoding
 [`x509.fingerprint256`]: #x509fingerprint256
+[`x509.verify(publicKey)`]: #x509verifypublickey
 [caveats when using strings as inputs to cryptographic APIs]: #using-strings-as-inputs-to-cryptographic-apis
 [certificate object]: tls.md#certificate-object
 [encoding]: buffer.md#buffers-and-character-encodings
Repository: ollama/ollama
Pull request: fix nil pointer dereference


Changed files:
filename: server/images.go
patch: @@ -1300,7 +1300,7 @@ func makeRequestWithRetry(ctx context.Context, method string, requestURL *url.UR
 }
 
 func makeRequest(ctx context.Context, method string, requestURL *url.URL, headers http.Header, body io.Reader, regOpts *RegistryOptions) (*http.Response, error) {
-	if requestURL.Scheme != "http" && regOpts.Insecure {
+	if requestURL.Scheme != "http" && regOpts != nil && regOpts.Insecure {
 		requestURL.Scheme = "http"
 	}
Repository: denoland/deno
Pull request: fix(node_resolver): incorrect resolution of `require("..")`

Fixes https://github.com/denoland/deno/issues/30505

Changed files:
filename: libs/node_resolver/resolution.rs
patch: @@ -553,10 +553,9 @@ impl<
     // }
 
     let p_str = path.to_str().unwrap();
-    let path = if p_str.ends_with('/') {
-      PathBuf::from(&p_str[p_str.len() - 1..])
-    } else {
-      path
+    let path = match p_str.strip_suffix('/') {
+      Some(s) => Cow::Borrowed(Path::new(s)),
+      None => Cow::Owned(path),
     };
 
     let maybe_file_type = self.sys.get_file_type(&path);
@@ -570,7 +569,7 @@ impl<
             .find(|e| self.sys.is_file(&path.join(e)));
           Err(
             UnsupportedDirImportError {
-              dir_url: UrlOrPath::Path(path),
+              dir_url: UrlOrPath::Path(path.into_owned()),
               maybe_referrer: maybe_referrer.map(|r| r.display()),
               suggested_file_name,
             }
@@ -607,7 +606,7 @@ impl<
         Ok(
           maybe_url
             .map(UrlOrPath::Url)
-            .unwrap_or(UrlOrPath::Path(path)),
+            .unwrap_or(UrlOrPath::Path(path.into_owned())),
         )
       }
       _ => {
@@ -626,7 +625,7 @@ impl<
           ModuleNotFoundError {
             suggested_ext: self
               .module_not_found_ext_suggestion(&path, resolved_method),
-            specifier: UrlOrPath::Path(path),
+            specifier: UrlOrPath::Path(path.into_owned()),
             maybe_referrer: maybe_referrer.map(|r| r.display()),
           }
           .into(),

filename: tests/specs/bundle/require_dotdot/__test__.jsonc
patch: @@ -0,0 +1,13 @@
+{
+  "tempDir": true,
+  "steps": [
+    {
+      "args": "bundle -o out.js ./repro/foo.cjs",
+      "output": "[WILDCARD]"
+    },
+    {
+      "args": "run -A out.js",
+      "output": "hello from index\n"
+    }
+  ]
+}

filename: tests/specs/bundle/require_dotdot/index.js
patch: @@ -0,0 +1 @@
+module.exports = "hello from index";

filename: tests/specs/bundle/require_dotdot/package.json
patch: @@ -0,0 +1 @@
+{}

filename: tests/specs/bundle/require_dotdot/repro/foo.cjs
patch: @@ -0,0 +1,2 @@
+const index = require("..");
+console.log(index);
Repository: ggml-org/llama.cpp
Pull request: Prevent premature submission on IME input

Close #16163

Adds checking for `KeyboardEvent.isComposing` to prevent sending request when confirming IME word selection.

Changed files:
filename: tools/server/webui/src/lib/components/app/chat/ChatForm/ChatForm.svelte
patch: @@ -26,6 +26,7 @@
 		MimeTypeImage,
 		MimeTypeText
 	} from '$lib/enums/files';
+	import { isIMEComposing } from '$lib/utils/is-ime-composing';
 
 	interface Props {
 		class?: string;
@@ -97,7 +98,7 @@
 	}
 
 	async function handleKeydown(event: KeyboardEvent) {
-		if (event.key === 'Enter' && !event.shiftKey) {
+		if (event.key === 'Enter' && !event.shiftKey && !isIMEComposing(event)) {
 			event.preventDefault();
 
 			if ((!message.trim() && uploadedFiles.length === 0) || disabled || isLoading) return;

filename: tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessage.svelte
patch: @@ -1,6 +1,7 @@
 <script lang="ts">
 	import { getDeletionInfo } from '$lib/stores/chat.svelte';
 	import { copyToClipboard } from '$lib/utils/copy';
+	import { isIMEComposing } from '$lib/utils/is-ime-composing';
 	import ChatMessageAssistant from './ChatMessageAssistant.svelte';
 	import ChatMessageUser from './ChatMessageUser.svelte';
 
@@ -93,7 +94,9 @@
 	}
 
 	function handleEditKeydown(event: KeyboardEvent) {
-		if (event.key === 'Enter' && !event.shiftKey) {
+		// Check for IME composition using isComposing property and keyCode 229 (specifically for IME composition on Safari)
+		// This prevents saving edit when confirming IME word selection (e.g., Japanese/Chinese input)
+		if (event.key === 'Enter' && !event.shiftKey && !isIMEComposing(event)) {
 			event.preventDefault();
 			handleSaveEdit();
 		} else if (event.key === 'Escape') {

filename: tools/server/webui/src/lib/utils/is-ime-composing.ts
patch: @@ -0,0 +1,5 @@
+export function isIMEComposing(event: KeyboardEvent) {
+	// Check for IME composition using isComposing property and keyCode 229 (specifically for IME composition on Safari, which is notorious for not supporting KeyboardEvent.isComposing)
+	// This prevents form submission when confirming IME word selection (e.g., Japanese/Chinese input)
+	return event.isComposing || event.keyCode === 229;
+}