#20622: feat: add configurable typingTtlSeconds to config schema
size: XS
Cluster:
Messaging Platform Improvements
## Summary
Adds `typingTtlSeconds` to both agent-level and session-level config schemas, and passes it through to `createTypingController()` in `get-reply.ts`.
## Problem
The typing indicator has a hardcoded 2-minute TTL (`typingTtlMs = 2 * 60_000`). For extended thinking models (e.g. Claude Opus 4.6 with `effort:max`), tool-heavy workflows, or complex multi-step replies, processing regularly exceeds 2 minutes — causing the typing indicator to disappear while the model is still actively working. This confuses users into thinking the bot has stalled.
`typingIntervalSeconds` is already configurable in the schema, but there is no config path for the TTL.
## Change
**5 files, 11 insertions:**
| File | Change |
|---|---|
| `src/config/types.agent-defaults.ts` | Add `typingTtlSeconds?: number` |
| `src/config/types.base.ts` | Add `typingTtlSeconds?: number` |
| `src/config/zod-schema.agent-defaults.ts` | Add `typingTtlSeconds: z.number().int().nonnegative().optional()` |
| `src/config/zod-schema.session.ts` | Add `typingTtlSeconds: z.number().int().nonnegative().optional()` |
| `src/auto-reply/reply/get-reply.ts` | Read from config, pass to `createTypingController()` |
## Behavior
| `typingTtlSeconds` | Behavior |
|---|---|
| not set / undefined | Default 2-minute TTL (backward compatible) |
| `0` | Disabled — typing stays active until run completes |
| `> 0` | Custom TTL in seconds |
The `0` case works because `createTypingController()` already has the guard:
```ts
if (typingTtlMs <= 0) return; // skip TTL timer entirely
```
## Config Example
```yaml
# Disable TTL (typing stays active for full processing duration)
agents:
defaults:
typingTtlSeconds: 0
# Extend to 5 minutes
agents:
defaults:
typingTtlSeconds: 300
```
## Design Decisions
- **`.nonnegative()` not `.positive()`** — because `0` is a valid value meaning "disabled"
- **Seconds not milliseconds** — matches existing `typingIntervalSeconds` convention
- **Spread with undefined check** — only passes `typingTtlMs` when explicitly configured, preserving the existing default for unset values
- **Agent cascades to session** — `agentCfg?.typingTtlSeconds ?? sessionCfg?.typingTtlSeconds` follows the same pattern as `typingIntervalSeconds`
Closes #13673
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds configurable `typingTtlSeconds` to agent and session config schemas, allowing users to control how long the typing indicator stays active. The implementation follows the existing `typingIntervalSeconds` pattern and correctly:
- Adds schema validation with `.nonnegative()` (allowing `0` to disable TTL)
- Cascades from agent to session config
- Converts seconds to milliseconds before passing to `createTypingController()`
- Only passes the parameter when explicitly set (preserving the 2-minute default)
- Supports `0` value to disable TTL entirely (typing stays active until processing completes)
The change solves a real problem for extended thinking models and tool-heavy workflows where processing exceeds the hardcoded 2-minute TTL.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- The implementation is straightforward, follows established patterns in the codebase (mirrors `typingIntervalSeconds`), and makes only additive changes. The type checking, schema validation, and conditional spreading ensure backward compatibility. The existing `createTypingController()` logic already handles all edge cases including `0` and negative values.
- No files require special attention
<sub>Last reviewed commit: 0514a1b</sub>
<!-- greptile_other_comments_section -->
<sub>(5/5) You can turn off certain types of comments like style [here](https://app.greptile.com/review/github)!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#6778: feat(typing): add configurable typingTtlSeconds option
by rahultappetla · 2026-02-02
85.0%
#10746: feat: add 'deferred' typing mode to suppress typing indicator for N...
by r00k · 2026-02-06
78.6%
#6546: Reply: avoid typing before text in message mode
by aldoeliacim · 2026-02-01
74.5%
#14640: feat(agents): support per-agent temperature and maxTokens in agents...
by lailoo · 2026-02-12
73.3%
#21558: config: support agents.list[].thinkingDefault
by Uarmagan · 2026-02-20
72.7%
#19816: feat(slack): add typingReaction config for DM typing indicator fall...
by dalefrieswthat · 2026-02-18
72.6%
#22140: feat(config): add usageDefault to agent defaults for persistent /us...
by Mellowambience · 2026-02-20
71.8%
#16403: feat: add readable timestamp to inbound_meta.v1 payload
by mcinteerj · 2026-02-14
71.7%
#20798: fix(process): Add delayMs parameter to send-keys for TUI compatibility
by Q00 · 2026-02-19
71.5%
#16899: feat(config): per-agent and per-model thinking defaults
by jh280722 · 2026-02-15
71.1%