Tool results and evidence can end on a lone surrogate half when clipped
Los mantenedores suelen responder en 3 días
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 78/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- node.js, typescript
Línea de trabajo
Start by reading clipCalendarText in apps/server/src/engine/conversation.ts and sanitizeFileName in files.ts, which the issue identifies as existing guards. Then inspect the listed clipping sites in conversation.ts, model.ts, service.ts, browser.ts and jev/service.ts; check how each handles a cut through a surrogate pair. Done means the same limits are preserved without returning a lone surrogate, with the described reproduction case covered.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
What happened?
Mail and page text reaches tool results, recorded evidence and notifications through String.prototype.slice(0, limit) on the UTF-16 code units (for example the mail snippet at apps/server/src/engine/conversation.ts (snippet: body.slice(0, 240), read_mail_thread's body.slice(0, 12000)), the search/web/page clips in apps/server/src/engine/model.ts and the monitor/evidence clips in apps/server/src/engine/service.ts, plus browser.ts and jev/service.ts). When the cut index lands between the two halves of a surrogate pair (an astral character such as an emoji), the clipped value ends on a lone high surrogate:
- it is not a character: UI renderers show U+FFFD in its place, and
- consumers that encode the value to UTF-8 (for example any Python service that reads the same data) raise
UnicodeEncodeErroron the lone half.
Two places in the codebase already guard against exactly this: clipCalendarText in conversation.ts (added with the calendar tool) and sanitizeFileName in files.ts ("Slice code points, not UTF-16 units, so a surrogate pair is never split in half"), and #183 fixed the related case of a surrogate numeric character reference failing the mail list. The mail and page clips are the same class but do not use the guard.
Steps to reproduce
- Give a mail body or watched page an astral character (for example 👍, U+1F44D, the pair D83D DC4D) straddling index 240 (or 12000/30000/500 for the other surfaces) — or in code:
"a".repeat(239) + "\u{1F44D}".repeat(3). const snippet = body.slice(0, 240)→ the result ends with the lone half\uD83D:/[\uD800-\uDBFF]$/.test(snippet)istrue.- The same value passed through
JSON.stringifykeeps a\ud83descape, and encoding it to UTF-8 outside JS replaces or rejects the lone half.
Expected: clip at the same limit, but drop the high half with its low half when the cut would split a pair, the way clipCalendarText already does for calendar text.
Commit or release
main @ a4944f4.
Platform
Any (server-side string handling).
Environment and safe logs
Pure string handling; no provider or platform dependency. Reproduced with Node: ("a".repeat(239) + "\u{1F44D}").slice(0, 240).charCodeAt(239).toString(16) → d83d.
- Lenguaje dominante
- TypeScript
- Estrellas
- 5.6k
- Forks
- 797
- Merge medio
- 4 d 8 h
- PR fusionados (30 d)
- 67
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de CopilotKit/openmuse
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 66/100
CopilotKit/openmuse#215 ·
Los mantenedores suelen responder en 3 días
-
[Feature] Add LLMTR as a model providerPosiblemente ocupada @knowhycodata la tomó hace 2 días. Abierto
Dificultad 4/5 3-5 días Aptitud para principiantes 25/100
CopilotKit/openmuse#212 ·
Los mantenedores suelen responder en 3 días
-
[Feature] Dark modeAbierto
Dificultad 4/5 3-5 días Aptitud para principiantes 24/100
CopilotKit/openmuse#181 ·
Los mantenedores suelen responder en 3 días
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 25/100
CopilotKit/openmuse#179 ·
Los mantenedores suelen responder en 3 días
-
Dependency DashboardAbierto
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
CopilotKit/openmuse#153 ·
Los mantenedores suelen responder en 3 días
Todos los issues de CopilotKit/openmuse
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
Northeastern-Electric-Racing/FinishLine#4660 ·
Los mantenedores suelen responder en 2 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 86/100
excaliburjs/Excalibur#3895 ·
Los mantenedores suelen responder en 3 días
-
infer_audio_type only recognises one MPEG Layer III frame header, so most MP3 files are rejectedPosiblemente ocupada @Steve-20-ai la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
Earn report crashes with "RangeError: Invalid time value" when a report row has an unparsable timestampPosiblemente ocupada @Gurkaran18 la tomó hoy. Abiertobug
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
joinmarket-webui/jam#1588 ·
Los mantenedores suelen responder en 3 días
-
BeOS .json missingAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
mihaip/infinite-mac#475 ·