poml 0.0.6 → 0.0.7

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/docs/tutorial/advanced/performance.md +695 -0
  3. data/docs/tutorial/advanced/tool-registration.md +776 -0
  4. data/docs/tutorial/basic-usage.md +351 -0
  5. data/docs/tutorial/components/chat-components.md +552 -0
  6. data/docs/tutorial/components/formatting.md +623 -0
  7. data/docs/tutorial/components/index.md +366 -0
  8. data/docs/tutorial/components/media-components.md +259 -0
  9. data/docs/tutorial/components/schema-components.md +668 -0
  10. data/docs/tutorial/index.md +184 -0
  11. data/docs/tutorial/output-formats.md +688 -0
  12. data/docs/tutorial/quickstart.md +30 -0
  13. data/docs/tutorial/template-engine.md +540 -0
  14. data/lib/poml/components/base.rb +146 -4
  15. data/lib/poml/components/content.rb +10 -3
  16. data/lib/poml/components/data.rb +539 -19
  17. data/lib/poml/components/examples.rb +235 -1
  18. data/lib/poml/components/formatting.rb +184 -18
  19. data/lib/poml/components/layout.rb +7 -2
  20. data/lib/poml/components/lists.rb +69 -35
  21. data/lib/poml/components/meta.rb +134 -5
  22. data/lib/poml/components/output_schema.rb +19 -1
  23. data/lib/poml/components/template.rb +72 -61
  24. data/lib/poml/components/text.rb +30 -1
  25. data/lib/poml/components/tool.rb +81 -0
  26. data/lib/poml/components/tool_definition.rb +339 -10
  27. data/lib/poml/components/tools.rb +14 -0
  28. data/lib/poml/components/utilities.rb +34 -18
  29. data/lib/poml/components.rb +19 -0
  30. data/lib/poml/context.rb +19 -4
  31. data/lib/poml/parser.rb +88 -63
  32. data/lib/poml/renderer.rb +191 -9
  33. data/lib/poml/template_engine.rb +138 -13
  34. data/lib/poml/version.rb +1 -1
  35. data/lib/poml.rb +16 -1
  36. data/readme.md +154 -27
  37. metadata +31 -4
  38. data/TUTORIAL.md +0 -987
@@ -0,0 +1,552 @@
1
+ # Chat Components
2
+
3
+ POML provides specialized components for creating structured AI conversations with proper role-based messaging.
4
+
5
+ ## Overview
6
+
7
+ Chat components (`<ai>`, `<human>`, `<system>`) are designed to create structured conversation flows that work seamlessly across different AI platforms and output formats.
8
+
9
+ ## System Component
10
+
11
+ The `<system>` component defines system-level instructions and context:
12
+
13
+ ```ruby
14
+ require 'poml'
15
+
16
+ markup = <<~POML
17
+ <poml>
18
+ <system>
19
+ You are a helpful assistant specializing in Ruby programming.
20
+ Provide clear, practical solutions with code examples.
21
+ Always explain your reasoning and suggest best practices.
22
+ </system>
23
+ </poml>
24
+ POML
25
+
26
+ result = Poml.process(markup: markup, format: 'openai_chat')
27
+ puts JSON.pretty_generate(result)
28
+ ```
29
+
30
+ Output:
31
+
32
+ ```json
33
+ [
34
+ {
35
+ "role": "system",
36
+ "content": "You are a helpful assistant specializing in Ruby programming..."
37
+ }
38
+ ]
39
+ ```
40
+
41
+ ## Human Component
42
+
43
+ The `<human>` component represents user messages and queries:
44
+
45
+ ```ruby
46
+ markup = <<~POML
47
+ <poml>
48
+ <system>You are a code review assistant.</system>
49
+
50
+ <human>
51
+ Please review this Ruby method for potential improvements:
52
+
53
+ <code>
54
+ def calculate_total(items)
55
+ total = 0
56
+ items.each do |item|
57
+ total += item.price * item.quantity
58
+ end
59
+ total
60
+ end
61
+ </code>
62
+ </human>
63
+ </poml>
64
+ POML
65
+
66
+ result = Poml.process(markup: markup, format: 'openai_chat')
67
+ ```
68
+
69
+ ## AI Component
70
+
71
+ The `<ai>` component represents assistant responses and can be used for few-shot examples:
72
+
73
+ ```ruby
74
+ markup = <<~POML
75
+ <poml>
76
+ <system>You are a Ruby expert providing code reviews.</system>
77
+
78
+ <human>How can I optimize this method?</human>
79
+
80
+ <ai>
81
+ Here's an optimized version using Ruby's built-in methods:
82
+
83
+ <code>
84
+ def calculate_total(items)
85
+ items.sum { |item| item.price * item.quantity }
86
+ end
87
+ </code>
88
+
89
+ This approach is more idiomatic and efficient.
90
+ </ai>
91
+
92
+ <human>Now please review this new code I've written:</human>
93
+ </poml>
94
+ POML
95
+
96
+ result = Poml.process(markup: markup, format: 'openai_chat')
97
+ ```
98
+
99
+ ## Multi-Turn Conversations
100
+
101
+ Create complex conversation flows with multiple exchanges:
102
+
103
+ ```ruby
104
+ markup = <<~POML
105
+ <poml>
106
+ <system>
107
+ You are a technical interviewer conducting a Ruby programming interview.
108
+ Ask progressive questions to assess the candidate's knowledge.
109
+ </system>
110
+
111
+ <human>I'm ready for the Ruby interview questions.</human>
112
+
113
+ <ai>
114
+ Great! Let's start with a basic question:
115
+
116
+ What's the difference between a class method and an instance method in Ruby?
117
+ Can you provide examples of each?
118
+ </ai>
119
+
120
+ <human>
121
+ A class method is called on the class itself, while an instance method
122
+ is called on an instance of the class.
123
+
124
+ Class method: `User.find_by_email(email)`
125
+ Instance method: `user.save`
126
+ </human>
127
+
128
+ <ai>
129
+ Excellent! Now let's dive deeper. Can you explain how Ruby's method
130
+ lookup chain works? What happens when you call a method on an object?
131
+ </ai>
132
+
133
+ <human>{{candidate_response}}</human>
134
+ </poml>
135
+ POML
136
+
137
+ context = {
138
+ 'candidate_response' => 'Please explain the method lookup process...'
139
+ }
140
+
141
+ result = Poml.process(markup: markup, context: context, format: 'openai_chat')
142
+ ```
143
+
144
+ ## Chat Components with Formatting
145
+
146
+ Chat components support nested formatting and structure:
147
+
148
+ ```ruby
149
+ markup = <<~POML
150
+ <poml>
151
+ <system>You are a code documentation assistant.</system>
152
+
153
+ <human>
154
+ Please document this API endpoint:
155
+
156
+ <list>
157
+ <item><b>Method:</b> POST</item>
158
+ <item><b>Path:</b> /api/users</item>
159
+ <item><b>Purpose:</b> Create new user account</item>
160
+ </list>
161
+ </human>
162
+
163
+ <ai>
164
+ I'll create comprehensive documentation for this endpoint:
165
+
166
+ <h2>POST /api/users</h2>
167
+
168
+ <p><b>Description:</b> Creates a new user account in the system.</p>
169
+
170
+ <p><b>Request Body:</b></p>
171
+ <code>
172
+ {
173
+ "name": "string (required)",
174
+ "email": "string (required, unique)",
175
+ "password": "string (required, min 8 chars)"
176
+ }
177
+ </code>
178
+
179
+ <p><b>Response Codes:</b></p>
180
+ <list>
181
+ <item><code>201</code> - User created successfully</item>
182
+ <item><code>400</code> - Validation errors</item>
183
+ <item><code>409</code> - Email already exists</item>
184
+ </list>
185
+ </ai>
186
+ </poml>
187
+ POML
188
+
189
+ result = Poml.process(markup: markup, format: 'raw')
190
+ ```
191
+
192
+ ## Template Variables in Chat
193
+
194
+ Use template variables within chat components:
195
+
196
+ ```ruby
197
+ markup = <<~POML
198
+ <poml>
199
+ <system>
200
+ You are a {{expertise_area}} expert helping with {{project_type}} projects.
201
+ Provide detailed, practical guidance based on industry best practices.
202
+ </system>
203
+
204
+ <human>
205
+ I'm working on a {{project_type}} and need help with {{specific_issue}}.
206
+
207
+ <p>Project Details:</p>
208
+ <list>
209
+ <item>Technology: {{technology_stack}}</item>
210
+ <item>Timeline: {{timeline}}</item>
211
+ <item>Team Size: {{team_size}}</item>
212
+ </list>
213
+ </human>
214
+ </poml>
215
+ POML
216
+
217
+ context = {
218
+ 'expertise_area' => 'DevOps',
219
+ 'project_type' => 'microservices deployment',
220
+ 'specific_issue' => 'container orchestration',
221
+ 'technology_stack' => 'Docker + Kubernetes',
222
+ 'timeline' => '3 months',
223
+ 'team_size' => '5 developers'
224
+ }
225
+
226
+ result = Poml.process(markup: markup, context: context, format: 'openai_chat')
227
+ ```
228
+
229
+ ## Conditional Chat Content
230
+
231
+ Use conditionals to create dynamic conversation flows:
232
+
233
+ ```ruby
234
+ markup = <<~POML
235
+ <poml>
236
+ <system>You are a debugging assistant.</system>
237
+
238
+ <human>I'm having an issue with my {{language}} code.</human>
239
+
240
+ <ai>
241
+ I'd be happy to help you debug your {{language}} code!
242
+
243
+ <if condition="{{language}} == 'Ruby'">
244
+ <p>For Ruby issues, I'll need to see:</p>
245
+ <list>
246
+ <item>The Ruby version you're using</item>
247
+ <item>Your Gemfile (if applicable)</item>
248
+ <item>The specific error message</item>
249
+ <item>The problematic code snippet</item>
250
+ </list>
251
+ </if>
252
+
253
+ <if condition="{{language}} == 'Python'">
254
+ <p>For Python issues, please provide:</p>
255
+ <list>
256
+ <item>Python version and virtual environment info</item>
257
+ <item>requirements.txt or pip freeze output</item>
258
+ <item>Full traceback of the error</item>
259
+ <item>Minimal code to reproduce the issue</item>
260
+ </list>
261
+ </if>
262
+
263
+ <p>Please share these details and I'll help you solve the problem.</p>
264
+ </ai>
265
+ </poml>
266
+ POML
267
+
268
+ context = { 'language' => 'Ruby' }
269
+ result = Poml.process(markup: markup, context: context, format: 'raw')
270
+ ```
271
+
272
+ ## Output Format Behavior
273
+
274
+ Chat components behave differently based on the output format:
275
+
276
+ ### OpenAI Chat Format
277
+
278
+ ```ruby
279
+ markup = <<~POML
280
+ <poml>
281
+ <system>You are a helpful assistant.</system>
282
+ <human>What is Ruby?</human>
283
+ </poml>
284
+ POML
285
+
286
+ result = Poml.process(markup: markup, format: 'openai_chat')
287
+ # Returns: [{"role": "system", "content": "..."}, {"role": "user", "content": "..."}]
288
+ ```
289
+
290
+ ### Raw Format
291
+
292
+ ```ruby
293
+ result = Poml.process(markup: markup, format: 'raw')
294
+ # Returns: Text with role boundaries like "===== system ====="
295
+ ```
296
+
297
+ ### LangChain Format
298
+
299
+ ```ruby
300
+ result = Poml.process(markup: markup, format: 'langchain')
301
+ # Returns: LangChain-compatible message structure
302
+ ```
303
+
304
+ ## Advanced Chat Patterns
305
+
306
+ ### Interview Flow
307
+
308
+ ```ruby
309
+ markup = <<~POML
310
+ <poml>
311
+ <system>
312
+ You are conducting a technical interview for a {{position}} role.
313
+ Ask progressive questions starting from basic concepts to advanced topics.
314
+ Provide feedback and follow-up questions based on responses.
315
+ </system>
316
+
317
+ <human>I'm ready to begin the {{position}} interview.</human>
318
+
319
+ <ai>
320
+ Welcome to the {{position}} interview! Let's start with some foundational questions.
321
+
322
+ <p><b>Question 1:</b> {{first_question}}</p>
323
+
324
+ <p>Take your time to explain your thought process.</p>
325
+ </ai>
326
+
327
+ <human>{{candidate_answer_1}}</human>
328
+
329
+ <ai>
330
+ <if condition="{{question_difficulty}} == 'basic'">
331
+ Good start! Now let's move to something more challenging.
332
+ </if>
333
+
334
+ <if condition="{{question_difficulty}} == 'advanced'">
335
+ Excellent answer! You clearly understand the concepts well.
336
+ </if>
337
+
338
+ <p><b>Follow-up:</b> {{follow_up_question}}</p>
339
+ </ai>
340
+ </poml>
341
+ POML
342
+ ```
343
+
344
+ ### Debugging Session
345
+
346
+ ```ruby
347
+ markup = <<~POML
348
+ <poml>
349
+ <system>
350
+ You are a senior developer helping debug a complex issue.
351
+ Guide the user through systematic debugging steps.
352
+ </system>
353
+
354
+ <human>
355
+ I'm getting this error in production:
356
+
357
+ <code>{{error_message}}</code>
358
+
359
+ It happens intermittently and I can't reproduce it locally.
360
+ </human>
361
+
362
+ <ai>
363
+ Intermittent production-only errors can be tricky! Let's debug this systematically.
364
+
365
+ <p><b>First, let's gather information:</b></p>
366
+ <list>
367
+ <item>What's the frequency of this error?</item>
368
+ <item>Are there any patterns in timing or user actions?</item>
369
+ <item>What are the differences between your local and production environments?</item>
370
+ <item>Do you have logging around the error location?</item>
371
+ </list>
372
+
373
+ <p>Based on the error message, here are some initial hypotheses:</p>
374
+
375
+ <if condition="{{error_type}} == 'timeout'">
376
+ <list>
377
+ <item>Database connection pooling issues</item>
378
+ <item>External API timeouts</item>
379
+ <item>Load-related performance degradation</item>
380
+ </list>
381
+ </if>
382
+
383
+ <if condition="{{error_type}} == 'memory'">
384
+ <list>
385
+ <item>Memory leaks in long-running processes</item>
386
+ <item>Large dataset processing without pagination</item>
387
+ <item>Inefficient caching strategies</item>
388
+ </list>
389
+ </if>
390
+ </ai>
391
+ </poml>
392
+ POML
393
+ ```
394
+
395
+ ### Code Review Conversation
396
+
397
+ ```ruby
398
+ markup = <<~POML
399
+ <poml>
400
+ <system>
401
+ You are a senior developer conducting a code review.
402
+ Provide constructive feedback focusing on maintainability, performance, and best practices.
403
+ </system>
404
+
405
+ <human>
406
+ Here's my implementation for the user authentication system:
407
+
408
+ <code>{{code_submission}}</code>
409
+
410
+ I'm particularly concerned about security and performance.
411
+ </human>
412
+
413
+ <ai>
414
+ Thanks for submitting this code! I'll review it focusing on security and performance as requested.
415
+
416
+ <p><b>Overall Assessment:</b> {{overall_assessment}}</p>
417
+
418
+ <p><b>Security Review:</b></p>
419
+ <list>
420
+ <for variable="security_issue" items="{{security_issues}}">
421
+ <item><b>{{security_issue.severity}}:</b> {{security_issue.description}}</item>
422
+ </for>
423
+ </list>
424
+
425
+ <p><b>Performance Considerations:</b></p>
426
+ <list>
427
+ <for variable="perf_issue" items="{{performance_issues}}">
428
+ <item>{{perf_issue.description}} - <i>{{perf_issue.solution}}</i></item>
429
+ </for>
430
+ </list>
431
+
432
+ <p><b>Recommended Changes:</b></p>
433
+ <code>{{suggested_improvements}}</code>
434
+
435
+ <p>Would you like me to explain any of these recommendations in more detail?</p>
436
+ </ai>
437
+ </poml>
438
+ POML
439
+ ```
440
+
441
+ ## Best Practices
442
+
443
+ ### 1. Clear Role Definition
444
+
445
+ ```ruby
446
+ # Good
447
+ <system>
448
+ You are a Ruby on Rails expert with 10+ years of experience.
449
+ Provide practical, production-ready solutions with security considerations.
450
+ </system>
451
+
452
+ # Better
453
+ <system>
454
+ You are a Senior Ruby on Rails Developer and Technical Lead specializing in:
455
+ - Performance optimization and scaling
456
+ - Security best practices and compliance
457
+ - Code architecture and maintainability
458
+
459
+ Always provide working code examples and explain trade-offs.
460
+ </system>
461
+ ```
462
+
463
+ ### 2. Structured Conversations
464
+
465
+ ```ruby
466
+ # Structure conversations logically
467
+ <system>Context and role definition</system>
468
+ <human>Initial request or question</human>
469
+ <ai>Example response (for few-shot learning)</ai>
470
+ <human>Actual user input</human>
471
+ ```
472
+
473
+ ### 3. Use Formatting for Clarity
474
+
475
+ ```ruby
476
+ <human>
477
+ <p>I need help with this problem:</p>
478
+
479
+ <p><b>Context:</b> {{context}}</p>
480
+ <p><b>Goal:</b> {{goal}}</p>
481
+ <p><b>Constraints:</b> {{constraints}}</p>
482
+
483
+ <p>Current code:</p>
484
+ <code>{{current_code}}</code>
485
+ </human>
486
+ ```
487
+
488
+ ### 4. Error Handling
489
+
490
+ ```ruby
491
+ def safe_chat_processing(markup, context = {})
492
+ begin
493
+ result = Poml.process(markup: markup, context: context, format: 'openai_chat')
494
+
495
+ # Validate chat structure
496
+ if result.is_a?(Array) && result.all? { |msg| msg.is_a?(Hash) && msg['role'] && msg['content'] }
497
+ { success: true, messages: result }
498
+ else
499
+ { success: false, error: 'Invalid chat structure' }
500
+ end
501
+ rescue => e
502
+ { success: false, error: e.message }
503
+ end
504
+ end
505
+ ```
506
+
507
+ ## Integration with AI Services
508
+
509
+ ### OpenAI API
510
+
511
+ ```ruby
512
+ require 'net/http'
513
+ require 'json'
514
+
515
+ def send_to_openai(poml_markup, context = {})
516
+ messages = Poml.process(
517
+ markup: poml_markup,
518
+ context: context,
519
+ format: 'openai_chat'
520
+ )
521
+
522
+ payload = {
523
+ model: 'gpt-4',
524
+ messages: messages,
525
+ max_tokens: 1000,
526
+ temperature: 0.7
527
+ }
528
+
529
+ # Send to OpenAI API...
530
+ end
531
+ ```
532
+
533
+ ### Claude API
534
+
535
+ ```ruby
536
+ def send_to_claude(poml_markup, context = {})
537
+ # Convert to raw format for Claude
538
+ prompt = Poml.process(
539
+ markup: poml_markup,
540
+ context: context,
541
+ format: 'raw'
542
+ )
543
+
544
+ # Send to Claude API...
545
+ end
546
+ ```
547
+
548
+ ## Next Steps
549
+
550
+ - Learn about [Output Formats](../output-formats.md) for different AI services
551
+ - Explore [Schema Components](schema-components.md) for structured responses
552
+ - Check [Integration Examples](../integration/rails.md) for real-world usage