Skip to content

Commit 9ed9197

Browse files
committed
Add initial implementation of PHP Stream Protocol library
- Created .gitignore to exclude vendor and composer.lock files. - Added composer.json for package management with dependencies. - Introduced README.md with library description, features, installation instructions, and usage examples. - Implemented core classes for handling AI streaming protocols, including StreamProtocol, StreamHandler, MessageConverter, and message structures (ClientMessage, ClientAttachment, ToolInvocation). - Added example usage scripts to demonstrate library functionality. - Established a structure for tool registration and invocation during streaming.
0 parents  commit 9ed9197

File tree

10 files changed

+1531
-0
lines changed

10 files changed

+1531
-0
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Dependencies
2+
/vendor/
3+
4+
# Composer
5+
/composer.lock

README.md

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
# PHP Stream Protocol
2+
3+
A PHP library for handling AI streaming protocols, particularly the Vercel AI SDK Stream Protocol. This package provides an easy-to-use interface for creating streaming AI responses with support for tool calls, attachments, and various AI providers.
4+
5+
## Features
6+
7+
- 🚀 **Easy Integration**: Simple, fluent API for streaming responses
8+
- 🔧 **Tool Support**: Built-in tool calling and execution
9+
- 📎 **Attachments**: Handle file and image attachments
10+
- 🔄 **Multi-Provider**: Support for OpenAI, Anthropic Claude, and more
11+
- 📊 **Protocol Compliant**: Follows Vercel AI SDK Stream Protocol specifications
12+
-**Symfony Integration**: Built with Symfony components
13+
14+
## Installation
15+
16+
```bash
17+
composer require premieroctet/php-stream-protocol
18+
```
19+
20+
## Quick Start
21+
22+
### Basic Usage
23+
24+
```php
25+
use App\StreamProtocol\StreamProtocol;
26+
use OpenAI;
27+
28+
// Create a new StreamProtocol instance
29+
$protocol = StreamProtocol::create()
30+
->withSystemPrompt('You are a helpful assistant.');
31+
32+
// Register tools
33+
$protocol->registerTool('get_weather', [WeatherService::class, 'getCurrentWeather']);
34+
35+
// In your controller
36+
public function chat(Request $request): Response
37+
{
38+
// Parse incoming messages
39+
$messages = $protocol->parseMessages($request->getContent());
40+
41+
// Convert to OpenAI format and create request
42+
$openaiRequest = $protocol->buildOpenAIRequest($messages, 'gpt-4');
43+
44+
// Create OpenAI stream
45+
$client = OpenAI::client($apiKey);
46+
$stream = $client->chat()->createStreamed($openaiRequest);
47+
48+
// Return streaming response
49+
return $protocol->stream($stream);
50+
}
51+
```
52+
53+
### Advanced Usage with Custom Tools
54+
55+
```php
56+
use App\StreamProtocol\StreamProtocol;
57+
58+
class ChatController
59+
{
60+
public function chat(Request $request): Response
61+
{
62+
$protocol = StreamProtocol::create()
63+
->withSystemPrompt('You are a helpful assistant with access to various tools.')
64+
->registerTool('search_web', [$this, 'searchWeb'])
65+
->registerTool('get_weather', [$this, 'getWeather'])
66+
->registerTool('send_email', [$this, 'sendEmail']);
67+
68+
return $protocol->handleRequest(
69+
$request->getContent(),
70+
function($messages) use ($request) {
71+
$client = OpenAI::client(env('OPENAI_API_KEY'));
72+
return $client->chat()->createStreamed([
73+
'model' => 'gpt-4',
74+
'messages' => $messages,
75+
'stream' => true,
76+
'tools' => $protocol->getToolDefinitions(),
77+
]);
78+
}
79+
);
80+
}
81+
82+
private function searchWeb(string $query): array
83+
{
84+
// Your web search implementation
85+
return ['results' => "Search results for: {$query}"];
86+
}
87+
88+
private function getWeather(string $location): array
89+
{
90+
// Your weather service implementation
91+
return ['weather' => "Weather in {$location}: Sunny, 25°C"];
92+
}
93+
}
94+
```
95+
96+
### Message Conversion
97+
98+
```php
99+
// Convert messages to different AI provider formats
100+
$messages = $protocol->parseMessages($jsonData);
101+
102+
// For OpenAI
103+
$openaiMessages = $protocol->convertToOpenAI($messages);
104+
105+
// For Anthropic Claude
106+
$anthropicData = $protocol->convertToAnthropic($messages);
107+
```
108+
109+
### Simple Text Streaming (for testing)
110+
111+
```php
112+
public function demo(): Response
113+
{
114+
$protocol = StreamProtocol::create();
115+
116+
return $protocol->streamText(
117+
'This is a demo of streaming text word by word.',
118+
50 // delay in milliseconds
119+
);
120+
}
121+
```
122+
123+
## Message Format
124+
125+
The library handles messages in the Vercel AI SDK format, supporting:
126+
127+
- **Text messages**: Simple text content
128+
- **Tool calls**: Function calling with arguments and results
129+
- **Attachments**: File and image attachments
130+
- **Message parts**: Complex message structures
131+
132+
Example message structure:
133+
134+
```json
135+
{
136+
"messages": [
137+
{
138+
"role": "user",
139+
"content": "What's the weather like?",
140+
"experimental_attachments": [
141+
{
142+
"contentType": "image/jpeg",
143+
"url": "data:image/jpeg;base64,..."
144+
}
145+
]
146+
},
147+
{
148+
"role": "assistant",
149+
"content": "",
150+
"toolInvocations": [
151+
{
152+
"toolCallId": "call_123",
153+
"toolName": "get_weather",
154+
"args": { "location": "New York" },
155+
"result": { "temperature": "25°C", "condition": "sunny" }
156+
}
157+
]
158+
}
159+
]
160+
}
161+
```
162+
163+
## Stream Protocol
164+
165+
The library implements the Vercel AI SDK Stream Protocol with the following message types:
166+
167+
- `0:` - Text content
168+
- `9:` - Tool call
169+
- `a:` - Tool result
170+
- `b:` - Tool call streaming start
171+
- `c:` - Tool call delta
172+
- `d:` - Finish message
173+
- `e:` - Finish step
174+
- `f:` - Message start
175+
176+
## Tool Integration
177+
178+
Tools must follow this interface:
179+
180+
```php
181+
class WeatherTool
182+
{
183+
public static function getCurrentWeather(string $location): array
184+
{
185+
// Your implementation
186+
return [
187+
'location' => $location,
188+
'temperature' => '25°C',
189+
'condition' => 'sunny'
190+
];
191+
}
192+
193+
public static function getToolDefinition(): array
194+
{
195+
return [
196+
'type' => 'function',
197+
'function' => [
198+
'name' => 'get_current_weather',
199+
'description' => 'Get current weather for a location',
200+
'parameters' => [
201+
'type' => 'object',
202+
'properties' => [
203+
'location' => [
204+
'type' => 'string',
205+
'description' => 'The city and state, e.g. San Francisco, CA'
206+
]
207+
],
208+
'required' => ['location']
209+
]
210+
]
211+
];
212+
}
213+
}
214+
```
215+
216+
## Requirements
217+
218+
- PHP 8.1 or higher
219+
- Symfony HttpFoundation component
220+
221+
## License
222+
223+
MIT License - see LICENSE file for details.
224+
225+
## Contributing
226+
227+
1. Fork the repository
228+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
229+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
230+
4. Push to the branch (`git push origin feature/amazing-feature`)
231+
5. Open a Pull Request

composer.json

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"name": "premieroctet/php-stream-protocol",
3+
"description": "A PHP library for handling AI streaming protocols, particularly the Vercel AI SDK Stream Protocol",
4+
"type": "library",
5+
"keywords": [
6+
"ai",
7+
"streaming",
8+
"openai",
9+
"anthropic",
10+
"vercel",
11+
"protocol"
12+
],
13+
"license": "MIT",
14+
"authors": [
15+
{
16+
"name": "Baptiste Adrien",
17+
"email": "[email protected]"
18+
}
19+
],
20+
"require": {
21+
"php": "^8.1",
22+
"symfony/http-foundation": "^6.0|^7.0"
23+
},
24+
"require-dev": {
25+
"phpunit/phpunit": "^10.0",
26+
"phpstan/phpstan": "^1.10"
27+
},
28+
"autoload": {
29+
"psr-4": {
30+
"PremierOctet\\StreamProtocol\\": "src/"
31+
}
32+
},
33+
"autoload-dev": {
34+
"psr-4": {
35+
"PremierOctet\\StreamProtocol\\Tests\\": "tests/"
36+
}
37+
},
38+
"minimum-stability": "stable",
39+
"prefer-stable": true,
40+
"config": {
41+
"sort-packages": true
42+
}
43+
}

0 commit comments

Comments
 (0)