CedarCopilot / CedarCopilot/cedar-OS

Enhance streaming logic to handle partial JSON objects properly

Open
#46 1 comment 0 reactions 0 assignees View on GitHub
enhancement
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.