Muse Spark 1.1·续1
Here's a small, strict version. It fixes the original bug where `item[key] === undefined` silently created a `"undefined"` bucket.
### Generic implementation
**Chosen behavior for missing keys:** If `item[key]` is `null` or `undefined`, the item is **skipped** and not included in any group. Rationale: avoids polluting the result with a coerced `"undefined"` key. If you need to keep them, normalize before calling.
```ts
// groupBy.ts
type PropertyKey = string | number | symbol;
// Only allow keys whose value can be a property key (or optional version)
type GroupableKeys<T> = {
[K in keyof T]: T[K] extends PropertyKey | null | undefined ? K : never
}[keyof T];
export function groupBy<T, K extends GroupableKeys<T>>(
items: readonly T[],
key: K
): Record<string, T[]> {
const out: Record<string, T[]> = {};
for (const item of items) {
const raw = item[key];
if (raw == null) continue; // <-- explicit missing-key policy
const groupKey = String(raw as PropertyKey);
(out[groupKey] ??= []).push(item);
}
return out;
}
```
> Typed to `Record<string, T[]>` intentionally. If you want literal key inference you can change the return to `Record<Extract<T[K], PropertyKey> & {}, T[]>` but for a library this is more ergonomic and doesn't lie about runtime `String()` coercion.
### Tests that document behavior
```ts
// groupBy.test.ts
import { describe, it, expect } from 'vitest';
import { groupBy } from './groupBy';
type Item = { cat?: string; id: number };
describe('groupBy', () => {
it('empty input -> empty object', () => {
expect(groupBy([] as Item[], 'cat')).toEqual({});
});
it('missing key value -> item skipped', () => {
const items: Item[] = [
{ cat: 'a', id: 1 },
{ id: 2 }, // cat is missing
{ cat: undefined, id: 3 }, // cat is explicitly undefined
];
const result = groupBy(items, 'cat');
// only 'a' group exists, no "undefined" bucket
expect(result).toEqual({
a: [{ cat: 'a', id: 1 }],
});
expect(Object.keys(result)).not.toContain('undefined');
});
it('two items sharing a key -> grouped together', () => {
const items: Item[] = [
{ cat: 'x', id: 1 },
{ cat: 'x', id: 2 },
{ cat: 'y', id: 3 },
];
const result = groupBy(items, 'cat');
expect(result).toEqual({
x: [
{ cat: 'x', id: 1 },
{ cat: 'x', id: 2 },
],
y: [{ cat: 'y', id: 3 }],
});
});
});
```
{
"id": "resp_6ac7b0009eadac3fd3fd4b77",
"object": "response",
"created_at": 1791471616,
"model": "muse-spark-1.1",
"output": [
{
"type": "reasoning",
"id": "rs_6ac7b0009eadac3fd3fd4b77:rs_70691cf1-3099-4eaf-8a65-6c9811ee8913",
"summary": [],
"status": "completed"
},
{
"type": "message",
"id": "msg_20968e1e-1419-4226-89cb-2c6497d11b9e",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "Here's a small, strict version. It fixes the original bug where `item[key] === undefined` silently created a `\"undefined\"` bucket.\n\n### Generic implementation\n\n**Chosen behavior for missing keys:** If `item[key]` is `null` or `undefined`, the item is **skipped** and not included in any group. Rationale: avoids polluting the result with a coerced `\"undefined\"` key. If you need to keep them, normalize before calling.\n\n```ts\n// groupBy.ts\ntype PropertyKey = string | number | symbol;\n\n// Only allow keys whose value can be a property key (or optional version)\ntype GroupableKeys<T> = {\n [K in keyof T]: T[K] extends PropertyKey | null | undefined ? K : never\n}[keyof T];\n\nexport function groupBy<T, K extends GroupableKeys<T>>(\n items: readonly T[],\n key: K\n): Record<string, T[]> {\n const out: Record<string, T[]> = {};\n\n for (const item of items) {\n const raw = item[key];\n if (raw == null) continue; // <-- explicit missing-key policy\n\n const groupKey = String(raw as PropertyKey);\n (out[groupKey] ??= []).push(item);\n }\n\n return out;\n}\n```\n\n> Typed to `Record<string, T[]>` intentionally. If you want literal key inference you can change the return to `Record<Extract<T[K], PropertyKey> & {}, T[]>` but for a library this is more ergonomic and doesn't lie about runtime `String()` coercion.\n\n### Tests that document behavior\n\n```ts\n// groupBy.test.ts\nimport { describe, it, expect } from 'vitest';\nimport { groupBy } from './groupBy';\n\ntype Item = { cat?: string; id: number };\n\ndescribe('groupBy', () => {\n it('empty input -> empty object', () => {\n expect(groupBy([] as Item[], 'cat')).toEqual({});\n });\n\n it('missing key value -> item skipped', () => {\n const items: Item[] = [\n { cat: 'a', id: 1 },\n { id: 2 }, // cat is missing\n { cat: undefined, id: 3 }, // cat is explicitly undefined\n ];\n\n const result = groupBy(items, 'cat');\n\n // only 'a' group exists, no \"undefined\" bucket\n expect(result).toEqual({\n a: [{ cat: 'a', id: 1 }],\n });\n expect(Object.keys(result)).not.toContain('undefined');\n });\n\n it('two items sharing a key -> grouped together', () => {\n const items: Item[] = [\n { cat: 'x', id: 1 },\n { cat: 'x', id: 2 },\n { cat: 'y', id: 3 },\n ];\n\n const result = groupBy(items, 'cat');\n\n expect(result).toEqual({\n x: [\n { cat: 'x', id: 1 },\n { cat: 'x', id: 2 },\n ],\n y: [{ cat: 'y', id: 3 }],\n });\n });\n});\n```",
"annotations": [],
"logprobs": []
}
],
"status": "completed"
}
],
"status": "completed",
"usage": {
"input_tokens": 127,
"output_tokens": 3158,
"total_tokens": 3285,
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens_details": {
"reasoning_tokens": 2479
}
},
"top_logprobs": 0,
"temperature": 1,
"top_p": 1,
"service_tier": "auto",
"reasoning": {
"effort": "high"
},
"background": false,
"tools": [],
"tool_choice": "auto",
"truncation": "disabled",
"completed_at": 1791471616,
"error": null,
"incomplete_details": null,
"instructions": null,
"parallel_tool_calls": true,
"store": true,
"max_output_tokens": 4096
}
</details>
<details>
<summary>Production Incident Triage — Triage a production incident from sparse symptoms and produce an ordered investigation plan.</summary>
const response = await env.AI.run(
'meta/muse-spark-1.1',
{
messages: [
{
role: 'system',
content:
'You are an incident commander. Separate facts from hypotheses, prioritize customer impact, and give reversible next steps before risky remediation.',
},
{
role: 'user',
content:
'At 14:05 UTC, API p95 latency rose from 180 ms to 2.4 s for one region. Error rate is 0.8%, database CPU is 45%, cache hit rate fell from 92% to 61%, and deploys have been quiet for six hours. A single endpoint is responsible for 70% of the extra latency. Write an incident update, list the three highest-value checks in order, and propose a safe mitigation.',
},
],
max_completion_tokens: 4096,
},
)
console.log(response)
curl https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/ai/run \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"model": "meta/muse-spark-1.1",
"input": {
"messages": [
{
"role": "system",
"content": "You are an incident commander. Separate facts from hypotheses, prioritize customer impact, and give reversible next steps before risky remediation."
},
{
"role": "user",
"content": "At 14:05 UTC, API p95 latency rose from 180 ms to 2.4 s for one region. Error rate is 0.8%, database CPU is 45%, cache hit rate fell from 92% to 61%, and deploys have been quiet for six hours. A single endpoint is responsible for 70% of the extra latency. Write an incident update, list the three highest-value checks in order, and propose a safe mitigation."
}
],
"max_completion_tokens": 4096
}
}'
### INCIDENT UPDATE #1 - 14:20 UTC - API Latency Elevation [Single Region]
**Status:** Investigating - SEV2
**Impact:** Customers served from `us-east-1 [example]` experiencing API p95 of 2.4s vs normal 180ms since 14:05 UTC. p50 stable. Error rate still low at 0.8% but we are seeing timeouts. Other regions healthy.
**Scope:** ~70% of added latency is isolated to a single endpoint: `GET /v1/<hot-endpoint>`
**FACTS:**
* 14:05 UTC start, sustained. Single region only.
* p95: 180ms -> 2.4s. Error rate: 0.8%
* Cache hit rate: 92% -> 61% in that region at same time.
* DB CPU 45% [normal], no saturation.
* No deploys for 6 hours to API or infra.
* One endpoint accounts for 70% of the latency increase.
**WORKING HYPOTHESES [Unconfirmed - Do not act on alone]:**
* Cache tier degradation / node loss in that region causing miss storm -> origin overload for that endpoint.
* Data / traffic shape change for that endpoint causing key cardinality blow-up / cache stampede.
* Regional capacity issue - client pool saturation, instance brownout, network partition to cache.
**NOT doing right now:** Cache flush, DB failover/restart, new deploy/rollback. All are high-risk and destructive to evidence.
---
### Top 3 Checks - In Priority Order
**1. Cache Tier Health in Affected Region - Highest signal**
Owner: Cache / SRE. Timebox: 5 min.
* Are all cache nodes members? Any node down/evicted at 14:05?
* Memory pressure, evictions/sec, OOMs, CPU, client connections, network errors.
* Client-side errors from API to cache, not just server-side.
**2. Hot Endpoint Traffic Analysis**
Owner: Backend. Timebox: 5 min.
* Traces for `/v1/<hot-endpoint>`: QPS change at 14:05? Tenant / customer spike?
* Cache key pattern: Hit rate per key, new keys per second, payload size. Is there a single hot key or key explosion?
* Origin latency without cache - is the DB / downstream for this endpoint spiking?
**3. Regional Serving Health**
Owner: SRE
* Pod/instance count, crash loops, autoscaler events, CPU throttling/GC for API fleet in that region at 14:05.
* Service mesh / load balancer latency between API and cache tier.
* Breakdown of that 0.8% errors: 504 vs 500 vs 429?
### Safe, Reversible Mitigation Proposed
Goal: Protect customers while preserving evidence.
**Proposal: Traffic shed + regional shift:**
1. Put a **temporal rate limit / load shed** on `GET /v1/<hot-endpoint>` in affected region only - e.g., 50% of normal limit, return 429 with Retry-After. Protects other endpoints.
2. **Shift 50% of API traffic out of affected region** to healthy regions via Global LB weight change. 1-click reversible.
3. Enable request coalescing + stale-while-revalidate for that endpoint if feature-flag exists.
**Why safe:** No data loss, no restarts, instantly reversible via config/LB. Directly addresses symptom - cache miss storm - without touching DB/cache.
**Rollback:** Revert LB weight + remove rate limit.
Next update in 20 minutes or upon completion of check #1.
Please attach cache and endpoint dashboards in thread.
{
"id": "resp_6ac7b01785cd56aad50246a5",
"object": "response",
"created_at": 1791471639,
"model": "muse-spark-1.1",
"output": [
{
"type": "reasoning",
"id": "rs_6ac7b01785cd56aad50246a5:rs_322771d5-5cdd-4e2d-a99d-9f26fb95b8a9",
"summary": [],
"status": "completed"
},
{
"type": "message",
"id": "msg_f39c4926-6745-4033-90d7-961b45acd92b",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "### INCIDENT UPDATE #1 - 14:20 UTC - API Latency Elevation [Single Region]\n\n**Status:** Investigating - SEV2\n**Impact:** Customers served from `us-east-1 [example]` experiencing API p95 of 2.4s vs normal 180ms since 14:05 UTC. p50 stable. Error rate still low at 0.8% but we are seeing timeouts. Other regions healthy.\n**Scope:** ~70% of added latency is isolated to a single endpoint: `GET /v1/<hot-endpoint>`\n\n**FACTS:**\n* 14:05 UTC start, sustained. Single region only.\n* p95: 180ms -> 2.4s. Error rate: 0.8%\n* Cache hit rate: 92% -> 61% in that region at same time.\n* DB CPU 45% [normal], no saturation.\n* No deploys for 6 hours to API or infra.\n* One endpoint accounts for 70% of the latency increase.\n\n**WORKING HYPOTHESES [Unconfirmed - Do not act on alone]:**\n* Cache tier degradation / node loss in that region causing miss storm -> origin overload for that endpoint.\n* Data / traffic shape change for that endpoint causing key cardinality blow-up / cache stampede.\n* Regional capacity issue - client pool saturation, instance brownout, network partition to cache.\n\n**NOT doing right now:** Cache flush, DB failover/restart, new deploy/rollback. All are high-risk and destructive to evidence.\n\n---\n### Top 3 Checks - In Priority Order\n\n**1. Cache Tier Health in Affected Region - Highest signal**\nOwner: Cache / SRE. Timebox: 5 min.\n* Are all cache nodes members? Any node down/evicted at 14:05?\n* Memory pressure, evictions/sec, OOMs, CPU, client connections, network errors.\n* Client-side errors from API to cache, not just server-side.\n\n**2. Hot Endpoint Traffic Analysis**\nOwner: Backend. Timebox: 5 min.\n* Traces for `/v1/<hot-endpoint>`: QPS change at 14:05? Tenant / customer spike?\n* Cache key pattern: Hit rate per key, new keys per second, payload size. Is there a single hot key or key explosion?\n* Origin latency without cache - is the DB / downstream for this endpoint spiking?\n\n**3. Regional Serving Health**\nOwner: SRE\n* Pod/instance count, crash loops, autoscaler events, CPU throttling/GC for API fleet in that region at 14:05.\n* Service mesh / load balancer latency between API and cache tier.\n* Breakdown of that 0.8% errors: 504 vs 500 vs 429?\n\n### Safe, Reversible Mitigation Proposed\n\nGoal: Protect customers while preserving evidence.\n\n**Proposal: Traffic shed + regional shift:**\n1. Put a **temporal rate limit / load shed** on `GET /v1/<hot-endpoint>` in affected region only - e.g., 50% of normal limit, return 429 with Retry-After. Protects other endpoints.\n2. **Shift 50% of API traffic out of affected region** to healthy regions via Global LB weight change. 1-click reversible.\n3. Enable request coalescing + stale-while-revalidate for that endpoint if feature-flag exists.\n\n**Why safe:** No data loss, no restarts, instantly reversible via config/LB. Directly addresses symptom - cache miss storm - without touching DB/cache.\n\n**Rollback:** Revert LB weight + remove rate limit.\n\nNext update in 20 minutes or upon completion of check #1.\n\nPlease attach cache and endpoint dashboards in thread.",
"annotations": [],
"logprobs": []
}
],
"status": "completed"
}
],
"status": "completed",
"usage": {
"input_tokens": 146,
"output_tokens": 2500,
"total_tokens": 2646,
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens_details": {
"reasoning_tokens": 1714
}
},
"top_logprobs": 0,
"temperature": 1,
"top_p": 1,
"service_tier": "auto",
"reasoning": {
"effort": "high"
},
"background": false,
"tools": [],
"tool_choice": "auto",
"truncation": "disabled",
"completed_at": 1791471639,
"error": null,
"incomplete_details": null,
"instructions": null,
"parallel_tool_calls": true,
"store": true,
"max_output_tokens": 4096
}
