CedarCopilot / CedarCopilot/cedar-OS
Enhance streaming logic to handle partial JSON objects properly
- Dominant language
- TypeScript
- Stars
- 172
- Forks
- 19
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
Currently, when streaming partial JSON objects in chunks, they are incorrectly processed as plain text instead of being accumulated and parsed as complete JSON objects. This causes the intended `object` type handler to not be called for valid JSON objects that are split across multiple streaming chunks.
## Problem Description
**Location**: `/packages/cedar-os/src/store/agentConnection/agentUtils.ts` lines 77-149 in the `processDataContent` function
**Current Behavior**:
- When a JSON object is streamed in parts (e.g., first chunk: `{`, second chunk: `"type": "action"`, third chunk: `}`), each chunk is individually parsed with `JSON.parse()`
- Since partial JSON chunks are invalid JSON, they fall through to the plain text handler
- The complete object is never reconstructed and handled as an `object` type
**Expected Behavior**:
- When encountering a `{` character, the system should buffer subsequent chunks until a complete, valid JSON object is formed
- Once valid JSON is detected, call the `object` type handler instead of treating it as text chunks
- This should work similar to how complete objects are currently handled when streamed as single chunks
## Code References
In `/packages/cedar-os/src/store/agentConnection/agentUtils.ts`:
```typescript
// Lines 84-149: Current logic immediately tries JSON.parse on each chunk
try {
const parsed = JSON.parse(data);
// ... handle parsed object
} catch {
// Falls back to treating as plain text - this is the problem
if (data.trim() && data \!== '[DONE]' && data \!== 'done') {
const processedContent = processContentChunk(data);
currentTextMessage += processedContent;
handler({ type: 'chunk', content: processedContent });
}
}
```
## Proposed Solution
1. **Add JSON Buffer System**: Implement a buffer to accumulate potential JSON chunks
2. **Bracket Detection**: When encountering `{`, start buffering mode
3. **Validation Loop**: On each new chunk in buffer mode, attempt to parse the accumulated content
4. **Handler Dispatch**: Once valid JSON is formed, call `handler({ type: 'object', object: parsed })`
5. **Fallback Mechanism**: If buffer grows too large or contains invalid patterns, flush as text
## Implementation Considerations
- Track brace nesting level to handle nested objects
- Set reasonable buffer size limits to prevent memory issues
- Maintain compatibility with existing single-chunk object streaming
- Ensure text chunks that aren't part of JSON objects continue to work normally
## Acceptance Criteria
- [ ] Partial JSON objects streamed across multiple chunks are properly reconstructed
- [ ] Complete JSON objects trigger the `object` type handler instead of `chunk` handlers
- [ ] Existing functionality for single-chunk objects remains unchanged
- [ ] Text-only streaming continues to work as expected
- [ ] Memory usage remains bounded even with malformed JSON streams
🤖 Generated with [Claude Code](https://claude.ai/code)
Contributor guide
Assessment
This issue has not been assessed yet.