Summary
Cyrus posts an agentActivityCreate mutation to Linear for every thought, tool action, and acknowledgment — including empty body:"" thoughts and ephemeral status updates ("Compacting conversation history…"). There is no configuration to turn this down. In multi-repo deployments that share one Linear workspace token, this chatter is the primary driver of exhausting Linear's 5,000 requests/hour per-token limit, which then breaks in-flight sessions (see #1324).
Notably, Slack thread-following already has a toggle (CYRUS_SLACK_THREAD_FOLLOWING_DISABLED) — but Linear activity streaming has no equivalent.
Environment
cyrus-ai 0.2.65, self-hosted edge worker, 5 repos sharing one Linear workspace token.
Evidence
- The dominant rate-limited operation is
agentActivityCreate with content.type:"thought", frequently body:"" (a literal no-op post) and ephemeral:true.
- ~12 unconditional
post*Activity call-sites in EdgeWorker (cyrus-edge-worker): postThoughtActivity (several), postInstantAcknowledgment, postInstantPromptedAcknowledgment, postParentResumeAcknowledgment, postRoutingActivity, postSystemPromptSelectionThought, postModelNotificationThought, postAnalyzingThought.
- No concurrency / max-session knob exists either (checked
cyrus-core + cyrus-edge-worker config schemas), so request volume can't be bounded that way — it has to be reduced at the posting layer.
Proposed fix
- Add a config field for Linear activity-streaming verbosity — per-repo (
RepositoryConfig) and/or global (EdgeConfig) in cyrus-core, with a default that preserves current behavior:
linearActivityStreaming: "full" | "minimal" | "off", or granular booleans (streamThoughts, streamAcks, streamRouting).
"minimal" = keep meaningful action results + the final response + session lifecycle; skip thoughts and ephemeral acks.
- Gate the
post*Activity call-sites in EdgeWorker on the flag.
- Unconditionally skip empty-
body:"" thought posts (pure waste) in ActivityPoster.postThoughtActivity, regardless of the flag.
- Optional: debounce/coalesce rapid ephemeral thought updates (each is replaced by the next anyway).
Acceptance criteria
- With
minimal / thoughts-off, a typical session issues materially fewer agentActivityCreate calls (target ≳60% reduction) with no loss of the final response or session-lifecycle visibility in Linear.
- Empty-body thoughts are never posted.
- Default behavior is unchanged when the flag is unset.
Related
Graceful handling when the limit is still hit: #1324. Together they address both sides — fewer requests (this) + resilience under throttle (#1324).
Summary
Cyrus posts an
agentActivityCreatemutation to Linear for every thought, tool action, and acknowledgment — including emptybody:""thoughts and ephemeral status updates ("Compacting conversation history…"). There is no configuration to turn this down. In multi-repo deployments that share one Linear workspace token, this chatter is the primary driver of exhausting Linear's 5,000 requests/hour per-token limit, which then breaks in-flight sessions (see #1324).Notably, Slack thread-following already has a toggle (
CYRUS_SLACK_THREAD_FOLLOWING_DISABLED) — but Linear activity streaming has no equivalent.Environment
cyrus-ai 0.2.65, self-hosted edge worker, 5 repos sharing one Linear workspace token.
Evidence
agentActivityCreatewithcontent.type:"thought", frequentlybody:""(a literal no-op post) andephemeral:true.post*Activitycall-sites inEdgeWorker(cyrus-edge-worker):postThoughtActivity(several),postInstantAcknowledgment,postInstantPromptedAcknowledgment,postParentResumeAcknowledgment,postRoutingActivity,postSystemPromptSelectionThought,postModelNotificationThought,postAnalyzingThought.cyrus-core+cyrus-edge-workerconfig schemas), so request volume can't be bounded that way — it has to be reduced at the posting layer.Proposed fix
RepositoryConfig) and/or global (EdgeConfig) incyrus-core, with a default that preserves current behavior:linearActivityStreaming: "full" | "minimal" | "off", or granular booleans (streamThoughts,streamAcks,streamRouting)."minimal"= keep meaningful action results + the final response + session lifecycle; skip thoughts and ephemeral acks.post*Activitycall-sites inEdgeWorkeron the flag.body:""thought posts (pure waste) inActivityPoster.postThoughtActivity, regardless of the flag.Acceptance criteria
minimal/ thoughts-off, a typical session issues materially feweragentActivityCreatecalls (target ≳60% reduction) with no loss of the final response or session-lifecycle visibility in Linear.Related
Graceful handling when the limit is still hit: #1324. Together they address both sides — fewer requests (this) + resilience under throttle (#1324).