-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathsse_streaming_example.php
More file actions
121 lines (104 loc) · 3.32 KB
/
Copy pathsse_streaming_example.php
File metadata and controls
121 lines (104 loc) · 3.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<?php
declare(strict_types=1);
require_once __DIR__ . '/load-env.php';
use ClaudeAgents\Agents\CodeGenerationAgent;
use ClaudeAgents\Validation\ValidationCoordinator;
use ClaudeAgents\Validation\Validators\PHPSyntaxValidator;
use ClaudeAgents\Streaming\SSEStreamAdapter;
use ClaudeAgents\Streaming\SSEServer;
use ClaudePhp\ClaudePhp;
/**
* Example: Server-Sent Events (SSE) streaming for code generation.
*
* This demonstrates real-time streaming of code generation progress
* to web clients using SSE.
*
* Usage:
* 1. Run this script: php examples/sse_streaming_example.php
* 2. Open your browser and use the EventSource API:
*
* ```javascript
* const eventSource = new EventSource('http://localhost:8000/sse_streaming_example.php');
*
* eventSource.addEventListener('code.generating', (e) => {
* console.log('Generating...', JSON.parse(e.data));
* });
*
* eventSource.addEventListener('code.generated', (e) => {
* const data = JSON.parse(e.data);
* console.log(`Generated ${data.line_count} lines`);
* });
*
* eventSource.addEventListener('validation.passed', (e) => {
* console.log('Validation passed!');
* });
*
* eventSource.addEventListener('component.completed', (e) => {
* console.log('Complete!', JSON.parse(e.data));
* eventSource.close();
* });
* ```
*/
$apiKey = getenv('ANTHROPIC_API_KEY');
if (! $apiKey) {
header('Content-Type: text/plain');
echo "Error: ANTHROPIC_API_KEY environment variable not set\n";
exit(1);
}
// Setup SSE headers
SSEServer::setupHeaders();
// Send initial comment
SSEServer::sendComment('Code Generation SSE Stream Starting...');
try {
$client = new ClaudePhp(apiKey: $apiKey);
// Setup validation
$validator = new ValidationCoordinator();
$validator->addValidator(new PHPSyntaxValidator());
// Create agent
$agent = new CodeGenerationAgent($client, [
'max_validation_retries' => 2,
'validation_coordinator' => $validator,
]);
// Create SSE adapter
$sseAdapter = new SSEStreamAdapter([
'auto_flush' => true,
'include_comments' => true,
]);
// Attach SSE callback to agent
$agent->onUpdate($sseAdapter->createCodeGenerationCallback());
// Send start event
SSEServer::sendEvent('stream.started', [
'timestamp' => date('c'),
'max_retries' => 2,
]);
// Generate component
$description = <<<DESC
Create a Logger class with:
- Namespace: App\Services
- Methods: debug(), info(), warning(), error()
- Each method accepts a message and optional context array
- Include PSR-3 compliant interface
DESC;
$result = $agent->generateComponent($description);
// Send completion event
if ($result->isValid()) {
SSEServer::sendEvent('stream.completed', [
'success' => true,
'code_length' => strlen($result->getCode()),
'attempts' => $result->getMetadata()['attempts'],
'summary' => $result->getSummary(),
]);
} else {
SSEServer::sendEvent('stream.failed', [
'success' => false,
'errors' => $result->getValidation()->getErrors(),
]);
}
} catch (\Throwable $e) {
SSEServer::sendEvent('stream.error', [
'error' => $e->getMessage(),
'type' => get_class($e),
]);
}
// Send final comment
SSEServer::sendComment('Stream complete');