@bluefly/openstandardagents 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +58 -218
  3. package/dist/cli/commands/diff.command.d.ts +7 -0
  4. package/dist/cli/commands/diff.command.d.ts.map +1 -0
  5. package/dist/cli/commands/diff.command.js +181 -0
  6. package/dist/cli/commands/diff.command.js.map +1 -0
  7. package/dist/cli/commands/docs.command.d.ts +7 -0
  8. package/dist/cli/commands/docs.command.d.ts.map +1 -0
  9. package/dist/cli/commands/docs.command.js +274 -0
  10. package/dist/cli/commands/docs.command.js.map +1 -0
  11. package/dist/cli/commands/lint.command.d.ts +7 -0
  12. package/dist/cli/commands/lint.command.d.ts.map +1 -0
  13. package/dist/cli/commands/lint.command.js +342 -0
  14. package/dist/cli/commands/lint.command.js.map +1 -0
  15. package/dist/cli/commands/serve.command.d.ts +7 -0
  16. package/dist/cli/commands/serve.command.d.ts.map +1 -0
  17. package/dist/cli/commands/serve.command.js +232 -0
  18. package/dist/cli/commands/serve.command.js.map +1 -0
  19. package/dist/cli/index.js +4 -0
  20. package/dist/cli/index.js.map +1 -1
  21. package/dist/di-container.d.ts.map +1 -1
  22. package/dist/di-container.js +3 -0
  23. package/dist/di-container.js.map +1 -1
  24. package/dist/services/git.service.d.ts +40 -0
  25. package/dist/services/git.service.d.ts.map +1 -0
  26. package/dist/services/git.service.js +122 -0
  27. package/dist/services/git.service.js.map +1 -0
  28. package/dist/spec/v0.3.1/UNIFIED-SCHEMA.md +120 -0
  29. package/dist/spec/v0.3.1/adapters/drupal.md +541 -0
  30. package/dist/spec/v0.3.1/adapters/symfony.md +659 -0
  31. package/dist/spec/v0.3.1/agent-test.schema.json +75 -0
  32. package/dist/spec/v0.3.1/examples/drupal-content-writer.ossa.yaml +110 -0
  33. package/dist/spec/v0.3.1/examples/drupal-moderation-assistant.ossa.yaml +96 -0
  34. package/dist/spec/v0.3.1/examples/quick-wins/complete-agent-with-quick-wins.ossa.yaml +144 -0
  35. package/dist/spec/v0.3.1/extensions/drupal.md +417 -0
  36. package/dist/spec/v0.3.1/ossa-0.3.0.schema.json +2787 -0
  37. package/dist/spec/v0.3.1/ossa-0.3.1.schema.json +2806 -0
  38. package/dist/spec/v0.3.1/protocols/sse.md +494 -0
  39. package/dist/spec/v0.3.1/protocols/webrtc.md +600 -0
  40. package/dist/spec/v0.3.1/protocols/websocket.md +362 -0
  41. package/dist/spec/v0.3.1/schemas/agent-unified.yaml +165 -0
  42. package/dist/spec/v0.3.1/schemas/capabilities.yaml +102 -0
  43. package/dist/spec/v0.3.1/schemas/functions.yaml +75 -0
  44. package/dist/spec/v0.3.1/schemas/messaging/channel.schema.json +245 -0
  45. package/dist/spec/v0.3.1/schemas/messaging/delivery-receipt.schema.json +192 -0
  46. package/dist/spec/v0.3.1/schemas/messaging/message.schema.json +205 -0
  47. package/dist/spec/v0.3.1/schemas/messaging/subscription.schema.json +214 -0
  48. package/dist/spec/v0.3.1/schemas/runtime.yaml +102 -0
  49. package/dist/spec/v0.3.1/schemas/taxonomy.yaml +533 -0
  50. package/dist/spec/v0.3.1/schemas/unified-llm.yaml +91 -0
  51. package/dist/spec/v0.3.1/taxonomy.yaml +256 -0
  52. package/dist/testing/fixtures.d.ts.map +1 -1
  53. package/dist/testing/fixtures.js +3 -2
  54. package/dist/testing/fixtures.js.map +1 -1
  55. package/package.json +3 -31
  56. package/spec/v0.3.1/UNIFIED-SCHEMA.md +120 -0
  57. package/spec/v0.3.1/adapters/drupal.md +541 -0
  58. package/spec/v0.3.1/adapters/symfony.md +659 -0
  59. package/spec/v0.3.1/agent-test.schema.json +75 -0
  60. package/spec/v0.3.1/examples/drupal-content-writer.ossa.yaml +110 -0
  61. package/spec/v0.3.1/examples/drupal-moderation-assistant.ossa.yaml +96 -0
  62. package/spec/v0.3.1/examples/quick-wins/complete-agent-with-quick-wins.ossa.yaml +144 -0
  63. package/spec/v0.3.1/extensions/drupal.md +417 -0
  64. package/spec/v0.3.1/ossa-0.3.0.schema.json +2787 -0
  65. package/spec/v0.3.1/ossa-0.3.1.schema.json +2806 -0
  66. package/spec/v0.3.1/protocols/sse.md +494 -0
  67. package/spec/v0.3.1/protocols/webrtc.md +600 -0
  68. package/spec/v0.3.1/protocols/websocket.md +362 -0
  69. package/spec/v0.3.1/schemas/agent-unified.yaml +165 -0
  70. package/spec/v0.3.1/schemas/capabilities.yaml +102 -0
  71. package/spec/v0.3.1/schemas/functions.yaml +75 -0
  72. package/spec/v0.3.1/schemas/messaging/channel.schema.json +245 -0
  73. package/spec/v0.3.1/schemas/messaging/delivery-receipt.schema.json +192 -0
  74. package/spec/v0.3.1/schemas/messaging/message.schema.json +205 -0
  75. package/spec/v0.3.1/schemas/messaging/subscription.schema.json +214 -0
  76. package/spec/v0.3.1/schemas/runtime.yaml +102 -0
  77. package/spec/v0.3.1/schemas/taxonomy.yaml +533 -0
  78. package/spec/v0.3.1/schemas/unified-llm.yaml +91 -0
  79. package/spec/v0.3.1/taxonomy.yaml +256 -0
  80. package/dist/types/generated/ossa-0.3.0.types.d.ts +0 -316
  81. package/dist/types/generated/ossa-0.3.0.types.d.ts.map +0 -1
  82. package/dist/types/generated/ossa-0.3.0.types.js +0 -8
  83. package/dist/types/generated/ossa-0.3.0.types.js.map +0 -1
  84. package/dist/types/generated/ossa-0.3.0.zod.d.ts +0 -17
  85. package/dist/types/generated/ossa-0.3.0.zod.d.ts.map +0 -1
  86. package/dist/types/generated/ossa-0.3.0.zod.js +0 -3
  87. package/dist/types/generated/ossa-0.3.0.zod.js.map +0 -1
@@ -0,0 +1,494 @@
1
+ # Server-Sent Events (SSE) Transport Protocol
2
+
3
+ ## Overview
4
+
5
+ Server-Sent Events (SSE) provides unidirectional server-to-client streaming over HTTP. This specification defines how OSSA agents use SSE for real-time event delivery, status updates, and streaming responses.
6
+
7
+ ## Connection Model
8
+
9
+ SSE is a **one-way protocol**: server sends events to client. For bidirectional communication, combine SSE (server→client) with HTTP POST (client→server).
10
+
11
+ ```
12
+ Client ─────POST───────> Server (Commands/Requests)
13
+ <────SSE Events── Server (Events/Responses)
14
+ ```
15
+
16
+ ## Connection Establishment
17
+
18
+ ### Client Connection
19
+
20
+ ```typescript
21
+ const eventSource = new EventSource('https://agent.example.com/events', {
22
+ withCredentials: true
23
+ });
24
+
25
+ eventSource.addEventListener('message', (event) => {
26
+ const data = JSON.parse(event.data);
27
+ console.log('Received:', data);
28
+ });
29
+
30
+ eventSource.addEventListener('error', (error) => {
31
+ console.error('Connection error:', error);
32
+ });
33
+ ```
34
+
35
+ ### Server Response Format
36
+
37
+ ```http
38
+ HTTP/1.1 200 OK
39
+ Content-Type: text/event-stream
40
+ Cache-Control: no-cache, no-store, must-revalidate
41
+ Connection: keep-alive
42
+ X-Accel-Buffering: no
43
+
44
+ data: {"type":"connected","timestamp":"2025-12-18T14:00:00Z"}
45
+
46
+ ```
47
+
48
+ ## Event Format
49
+
50
+ ### SSE Message Structure
51
+
52
+ ```
53
+ event: <event-type>
54
+ id: <message-id>
55
+ retry: <reconnect-time-ms>
56
+ data: <json-payload>
57
+
58
+ ```
59
+
60
+ ### OSSA Event Schema
61
+
62
+ ```typescript
63
+ interface SSEEvent {
64
+ type: 'message' | 'status' | 'capability_response' | 'error';
65
+ id: string; // Unique event ID
66
+ timestamp: string; // ISO 8601 timestamp
67
+ payload: unknown; // Event-specific data
68
+ metadata: {
69
+ agentId: string; // Source agent URI
70
+ streamId?: string; // For multi-stream scenarios
71
+ correlationId?: string; // Links to originating request
72
+ sequence?: number; // Event sequence number
73
+ final?: boolean; // Indicates last event in sequence
74
+ };
75
+ }
76
+ ```
77
+
78
+ ## Event Types
79
+
80
+ ### 1. Message Event
81
+
82
+ Standard event delivery:
83
+
84
+ ```
85
+ event: message
86
+ id: msg-123e4567-e89b-12d3-a456-426614174000
87
+ data: {
88
+ data: "type": "message",
89
+ data: "timestamp": "2025-12-18T14:00:00Z",
90
+ data: "payload": {
91
+ data: "channel": "content.published",
92
+ data: "data": {"contentId": "node-123", "status": "published"}
93
+ data: },
94
+ data: "metadata": {
95
+ data: "agentId": "agent://example.com/publisher",
96
+ data: "sequence": 42
97
+ data: }
98
+ data: }
99
+
100
+ ```
101
+
102
+ ### 2. Status Update
103
+
104
+ Agent health and status streams:
105
+
106
+ ```
107
+ event: status
108
+ id: status-456e7890-a12b-34c5-d678-901234567890
109
+ data: {
110
+ data: "type": "status",
111
+ data: "timestamp": "2025-12-18T14:00:00Z",
112
+ data: "payload": {
113
+ data: "status": "healthy",
114
+ data: "load": 0.45,
115
+ data: "uptime": 86400
116
+ data: },
117
+ data: "metadata": {
118
+ data: "agentId": "agent://example.com/worker-1"
119
+ data: }
120
+ data: }
121
+
122
+ ```
123
+
124
+ ### 3. Capability Response
125
+
126
+ Streaming response to capability invocation:
127
+
128
+ ```
129
+ event: capability_response
130
+ id: resp-789a0123-b45c-67d8-e901-234567890123
131
+ data: {
132
+ data: "type": "capability_response",
133
+ data: "timestamp": "2025-12-18T14:00:00Z",
134
+ data: "payload": {
135
+ data: "capability": "analyze_content",
136
+ data: "result": {"sentiment": "positive", "score": 0.85}
137
+ data: },
138
+ data: "metadata": {
139
+ data: "agentId": "agent://example.com/analyzer",
140
+ data: "correlationId": "req-789",
141
+ data: "final": true
142
+ data: }
143
+ data: }
144
+
145
+ ```
146
+
147
+ ### 4. Error Event
148
+
149
+ Error notifications:
150
+
151
+ ```
152
+ event: error
153
+ id: err-234f5678-g90h-12i3-j456-789012345678
154
+ data: {
155
+ data: "type": "error",
156
+ data: "timestamp": "2025-12-18T14:00:00Z",
157
+ data: "payload": {
158
+ data: "code": "PROCESSING_ERROR",
159
+ data: "message": "Failed to process request",
160
+ data: "retryable": true
161
+ data: },
162
+ data: "metadata": {
163
+ data: "agentId": "agent://example.com/agent",
164
+ data: "correlationId": "req-789"
165
+ data: }
166
+ data: }
167
+
168
+ ```
169
+
170
+ ## Authentication
171
+
172
+ ### Bearer Token
173
+
174
+ ```typescript
175
+ // Modern browsers
176
+ const eventSource = new EventSource('https://agent.example.com/events', {
177
+ withCredentials: true
178
+ });
179
+
180
+ // Server sets cookie or client sends Authorization header
181
+ // Note: EventSource doesn't support custom headers in browsers
182
+ // Use cookie-based auth or proxy
183
+ ```
184
+
185
+ ### Query Parameter Authentication
186
+
187
+ For environments without cookie support:
188
+
189
+ ```typescript
190
+ const token = await getAuthToken();
191
+ const eventSource = new EventSource(
192
+ `https://agent.example.com/events?token=${token}`
193
+ );
194
+ ```
195
+
196
+ ## Reconnection and Reliability
197
+
198
+ ### Automatic Reconnection
199
+
200
+ EventSource automatically reconnects with:
201
+
202
+ - Default retry: 3 seconds
203
+ - Server can customize via `retry` field
204
+
205
+ ```
206
+ retry: 5000
207
+ data: {"type":"message","payload":{...}}
208
+
209
+ ```
210
+
211
+ ### Last-Event-ID
212
+
213
+ Client sends last received event ID on reconnect:
214
+
215
+ ```http
216
+ GET /events HTTP/1.1
217
+ Host: agent.example.com
218
+ Last-Event-ID: msg-123e4567-e89b-12d3-a456-426614174000
219
+ ```
220
+
221
+ Server resumes from that event:
222
+
223
+ ```typescript
224
+ app.get('/events', (req, res) => {
225
+ const lastEventId = req.headers['last-event-id'];
226
+
227
+ // Replay events after lastEventId
228
+ if (lastEventId) {
229
+ const missedEvents = getEventsSince(lastEventId);
230
+ missedEvents.forEach(event => sendSSE(res, event));
231
+ }
232
+
233
+ // Continue with live events
234
+ streamLiveEvents(res);
235
+ });
236
+ ```
237
+
238
+ ## Streaming Patterns
239
+
240
+ ### 1. Event Stream
241
+
242
+ Continuous event delivery:
243
+
244
+ ```typescript
245
+ // Server
246
+ app.get('/events', (req, res) => {
247
+ res.setHeader('Content-Type', 'text/event-stream');
248
+ res.setHeader('Cache-Control', 'no-cache');
249
+ res.setHeader('Connection', 'keep-alive');
250
+
251
+ const sendEvent = (event: SSEEvent) => {
252
+ res.write(`event: ${event.type}\n`);
253
+ res.write(`id: ${event.id}\n`);
254
+ res.write(`data: ${JSON.stringify(event)}\n\n`);
255
+ };
256
+
257
+ // Subscribe to events
258
+ const subscription = eventBus.subscribe((event) => {
259
+ sendEvent(event);
260
+ });
261
+
262
+ req.on('close', () => {
263
+ subscription.unsubscribe();
264
+ });
265
+ });
266
+ ```
267
+
268
+ ### 2. Request-Response Streaming
269
+
270
+ Long-running capability execution:
271
+
272
+ ```typescript
273
+ // Client initiates capability call via POST
274
+ const response = await fetch('/capabilities/analyze', {
275
+ method: 'POST',
276
+ body: JSON.stringify({ contentId: 'node-123' })
277
+ });
278
+
279
+ const { streamId } = await response.json();
280
+
281
+ // Subscribe to result stream
282
+ const eventSource = new EventSource(`/events?stream=${streamId}`);
283
+
284
+ eventSource.addEventListener('capability_response', (event) => {
285
+ const data = JSON.parse(event.data);
286
+
287
+ if (data.metadata.final) {
288
+ eventSource.close();
289
+ console.log('Final result:', data.payload.result);
290
+ } else {
291
+ console.log('Progress:', data.payload);
292
+ }
293
+ });
294
+ ```
295
+
296
+ ### 3. Multiplexed Streams
297
+
298
+ Multiple logical streams over one SSE connection:
299
+
300
+ ```typescript
301
+ // Client subscribes to multiple channels
302
+ const eventSource = new EventSource(
303
+ '/events?channels=content.published,user.login,agent.status'
304
+ );
305
+
306
+ eventSource.addEventListener('message', (event) => {
307
+ const data = JSON.parse(event.data);
308
+
309
+ switch (data.payload.channel) {
310
+ case 'content.published':
311
+ handleContentPublished(data);
312
+ break;
313
+ case 'user.login':
314
+ handleUserLogin(data);
315
+ break;
316
+ case 'agent.status':
317
+ handleAgentStatus(data);
318
+ break;
319
+ }
320
+ });
321
+ ```
322
+
323
+ ## Heartbeat and Keepalive
324
+
325
+ Server SHOULD send periodic comments to prevent connection timeout:
326
+
327
+ ```
328
+ : heartbeat - 2025-12-18T14:00:00Z
329
+
330
+ data: {"type":"message","payload":{...}}
331
+
332
+ : heartbeat - 2025-12-18T14:01:00Z
333
+
334
+ ```
335
+
336
+ Recommended heartbeat interval: 30 seconds
337
+
338
+ ## Error Handling
339
+
340
+ ### Connection Errors
341
+
342
+ ```typescript
343
+ eventSource.addEventListener('error', (error) => {
344
+ if (eventSource.readyState === EventSource.CLOSED) {
345
+ console.log('Connection closed permanently');
346
+ // Implement custom reconnection logic if needed
347
+ } else {
348
+ console.log('Connection error, auto-reconnecting...');
349
+ }
350
+ });
351
+ ```
352
+
353
+ ### Event Processing Errors
354
+
355
+ ```typescript
356
+ eventSource.addEventListener('message', (event) => {
357
+ try {
358
+ const data = JSON.parse(event.data);
359
+ processEvent(data);
360
+ } catch (error) {
361
+ console.error('Failed to process event:', error);
362
+ // Log but don't close connection
363
+ }
364
+ });
365
+ ```
366
+
367
+ ## Performance Considerations
368
+
369
+ ### Buffering
370
+
371
+ Disable buffering for real-time delivery:
372
+
373
+ ```http
374
+ X-Accel-Buffering: no
375
+ ```
376
+
377
+ Nginx:
378
+
379
+ ```nginx
380
+ location /events {
381
+ proxy_pass http://backend;
382
+ proxy_buffering off;
383
+ proxy_cache off;
384
+ }
385
+ ```
386
+
387
+ ### Connection Limits
388
+
389
+ - Browser limit: 6 connections per domain
390
+ - Use single SSE connection per domain
391
+ - Multiplex channels over one connection
392
+
393
+ ### Memory Management
394
+
395
+ Server SHOULD:
396
+
397
+ 1. Limit event buffer size (e.g., last 100 events)
398
+ 2. Implement event expiry (e.g., 5 minutes)
399
+ 3. Track active connections and enforce limits
400
+
401
+ ## Security Considerations
402
+
403
+ 1. **HTTPS Required** - Always use HTTPS in production
404
+ 2. **CORS** - Configure proper CORS headers
405
+ 3. **Authentication** - Use cookie-based or query param auth
406
+ 4. **Rate Limiting** - Limit events per connection
407
+ 5. **Event Filtering** - Only send events user has permission to see
408
+
409
+ ```http
410
+ Access-Control-Allow-Origin: https://trusted-domain.com
411
+ Access-Control-Allow-Credentials: true
412
+ ```
413
+
414
+ ## Bidirectional Communication
415
+
416
+ Combine SSE with HTTP POST for bidirectional flow:
417
+
418
+ ```typescript
419
+ // Client sends command
420
+ const response = await fetch('/capabilities/process', {
421
+ method: 'POST',
422
+ body: JSON.stringify({ data: 'input' })
423
+ });
424
+
425
+ const { taskId } = await response.json();
426
+
427
+ // Server streams progress via SSE
428
+ const eventSource = new EventSource(`/events?task=${taskId}`);
429
+
430
+ eventSource.addEventListener('capability_response', (event) => {
431
+ const data = JSON.parse(event.data);
432
+ updateProgress(data.payload);
433
+
434
+ if (data.metadata.final) {
435
+ eventSource.close();
436
+ }
437
+ });
438
+ ```
439
+
440
+ ## Examples
441
+
442
+ ### Real-time Status Dashboard
443
+
444
+ ```typescript
445
+ // Server
446
+ app.get('/agent-status', (req, res) => {
447
+ res.setHeader('Content-Type', 'text/event-stream');
448
+ res.setHeader('Cache-Control', 'no-cache');
449
+ res.setHeader('Connection', 'keep-alive');
450
+
451
+ const interval = setInterval(() => {
452
+ const status = {
453
+ type: 'status',
454
+ id: uuid(),
455
+ timestamp: new Date().toISOString(),
456
+ payload: {
457
+ activeAgents: getActiveAgentCount(),
458
+ queueDepth: getQueueDepth(),
459
+ throughput: getThroughput()
460
+ },
461
+ metadata: {
462
+ agentId: 'agent://example.com/monitor'
463
+ }
464
+ };
465
+
466
+ res.write(`event: status\n`);
467
+ res.write(`id: ${status.id}\n`);
468
+ res.write(`data: ${JSON.stringify(status)}\n\n`);
469
+ }, 5000);
470
+
471
+ req.on('close', () => clearInterval(interval));
472
+ });
473
+
474
+ // Client
475
+ const eventSource = new EventSource('/agent-status');
476
+ eventSource.addEventListener('status', (event) => {
477
+ const status = JSON.parse(event.data);
478
+ updateDashboard(status.payload);
479
+ });
480
+ ```
481
+
482
+ ## Compatibility
483
+
484
+ - Protocol: SSE (HTML5 EventSource API)
485
+ - Content-Type: `text/event-stream`
486
+ - Character encoding: UTF-8
487
+ - Browser support: All modern browsers
488
+ - Fallback: Long-polling for older browsers
489
+
490
+ ## References
491
+
492
+ - [HTML5 Server-Sent Events](https://html.spec.whatwg.org/multipage/server-sent-events.html)
493
+ - [MDN EventSource API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)
494
+ - [OSSA Message Envelope Specification](../messaging.md)