ad-agent_architecture 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ddf07e6fca1337e7800b3c85b1c48f44524aa14660827eb81ffe541bce122c49
4
- data.tar.gz: be8299cec2e18b52eebeb1af83fc243b172685b490cd581241d1d471b7de68ee
3
+ metadata.gz: 48e72bffc8e25721cc39304860dac54bdde2cbe3828fd9bf39ea5a93d2ae40d8
4
+ data.tar.gz: 6579e5af918b96e8eb9960ea2e672cf1b2315fad054f794ca5789cec1779624c
5
5
  SHA512:
6
- metadata.gz: 92afeb1cb3bc9315da02dc33dbe280fa6ab1c43404886852c5e4b542345e00f8f0b48b504a5f45dce205dde146e6dc3f7cebc35b8d2cee777aee6f81ed7a6c9f
7
- data.tar.gz: 0167d391cb38acb70bd39dd0e454c21570531b86bb411b9b473869437f70a33374992f266c7cd10daa8f9ffd17697ffbd5784bb46056ffb4c71d3e34966926a2
6
+ metadata.gz: a3ac5432296309961a50273fbb71cdf0fd681ab5d1a40cf7054a9b1a044001d1262d0eefc91f08f579a887294104dc3e22e2fbe3717e3c32b98fe0eae7ff54de
7
+ data.tar.gz: 93c048683f119fa32427bf57422bf1217bb689870162cb733a3eda10bdba6d92c0f8b7606e3550630b747ad2000a7bd48ec7c83beaa4ab2c67593a67c7b5b5ef
data/.rubocop.yml CHANGED
@@ -14,6 +14,7 @@ AllCops:
14
14
  Exclude:
15
15
  - ".builders/**/*"
16
16
  - "spec/samples/**/*"
17
+ - "lib/ad/agent_architecture/db/*"
17
18
 
18
19
  Metrics/BlockLength:
19
20
  Exclude:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [0.0.4](https://github.com/appydave/ad-agent_architecture/compare/v0.0.3...v0.0.4) (2024-06-26)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * update schema ([dd2d6fb](https://github.com/appydave/ad-agent_architecture/commit/dd2d6fbd1eb477da5e44f3d5417aa05ec291fb25))
7
+
1
8
  ## [0.0.3](https://github.com/appydave/ad-agent_architecture/compare/v0.0.2...v0.0.3) (2024-06-26)
2
9
 
3
10
 
Binary file
data/docs/requirements.md CHANGED
@@ -7,7 +7,16 @@
7
7
 
8
8
  ### Static Workflow Definition
9
9
 
10
+ Static workflow definition defines the structure of a workflow, including its sections, steps, attributes, and their relationships.
11
+
12
+ ![Static Workflow Definition](./images/sample-workflow.png)
13
+
14
+ ### Static Workflow Entities
15
+
10
16
  #### Table: workflows
17
+
18
+ This table stores the basic information about each workflow, including its unique identifier, name, and description.
19
+
11
20
  | Field | Type | Description |
12
21
  |-------------|--------|-------------------------------------|
13
22
  | id | string | Unique identifier for the workflow |
@@ -15,40 +24,60 @@
15
24
  | description | string | A brief description of the workflow |
16
25
 
17
26
  #### Table: sections
27
+ This table stores the sections that belong to a workflow. Each section has an order within its workflow.
28
+
18
29
  | Field | Type | Description |
19
30
  |-------------|---------|----------------------------------------|
20
31
  | id | string | Unique identifier for the section |
32
+ | workflow_id | string | Foreign key referencing workflows |
21
33
  | name | string | The name of the section |
22
34
  | description | string | A brief description of the section |
23
35
  | order | integer | The order of the section in the workflow|
24
- | workflow_id | string | Foreign key referencing workflows |
25
36
 
26
37
  #### Table: steps
38
+
39
+ This table stores the steps that belong to a section. Each step has an order within its section and an associated prompt.
40
+
41
+ Example workflows include "YouTube Video Script", "YouTube Title Creator" and "YouTube Transcription to Medium Article".
42
+
27
43
  | Field | Type | Description |
28
44
  |-------------|---------|-------------------------------------|
29
45
  | id | string | Unique identifier for the step |
46
+ | section_id | string | Foreign key referencing sections |
30
47
  | name | string | The name of the step |
48
+ | action | string | The action to be performed by the step, default ('gpt') |
31
49
  | description | string | A brief description of the step |
32
50
  | order | integer | The order of the step in the section|
33
- | section_id | string | Foreign key referencing sections |
34
51
  | prompt | string | The template string for the prompt |
35
52
 
36
53
  #### Table: attributes
54
+
55
+ This table stores the attributes associated with a workflow. Each attribute can be a simple value or an array.
56
+
57
+ Example attributes include "simple_title", "basic_factsheet" and "working_title".
58
+
37
59
  | Field | Type | Description |
38
60
  |-------------|---------|---------------------------------------------|
39
61
  | id | string | Unique identifier for the attribute |
62
+ | workflow_id | string | Foreign key referencing workflows |
40
63
  | name | string | The name of the attribute |
41
64
  | type | string | The type of the attribute (e.g., string) |
42
65
  | is_array | boolean | Indicates whether the attribute is an array |
43
- | workflow_id | string | Foreign key referencing workflows |
44
66
 
45
67
  #### Table: input_attributes
68
+
69
+ This table maps input attributes to steps. This becomes the input parameters for the AI agent.
70
+
46
71
  | Field | Type | Description |
47
72
  |-------------|---------|------------------------------------|
48
73
  | step_id | string | Foreign key referencing steps |
49
74
  | attribute_id| string | Foreign key referencing attributes |
75
+ | required | boolean | Indicates whether the attribute is required |
50
76
 
51
77
  #### Table: output_attributes
78
+
79
+ This table maps output attributes to steps. This becomes a result of the AI agent.
80
+
52
81
  | Field | Type | Description |
53
82
  |-------------|---------|------------------------------------|
54
83
  | step_id | string | Foreign key referencing steps |
@@ -56,20 +85,31 @@
56
85
 
57
86
  ### Dynamic Workflow Execution
58
87
 
88
+ Dynamic workflow execution captures the actual execution of a workflow, including the workflow runs, section runs, step runs, and attribute values.
89
+
90
+ ### Dynamic Workflow Entities
91
+
59
92
  #### Table: workflow_runs
93
+
94
+ This table stores instances of workflow executions.
95
+
60
96
  | Field | Type | Description |
61
97
  |-------------|--------|---------------------------------------|
62
98
  | id | string | Unique identifier for the workflow run|
63
99
  | workflow_id | string | Foreign key referencing workflows |
64
100
 
65
101
  #### Table: section_runs
102
+ This table stores instances of section executions within a workflow run.
103
+
66
104
  | Field | Type | Description |
67
105
  |-----------------|--------|----------------------------------------|
68
106
  | id | string | Unique identifier for the section run |
69
- | workflow_run_id | string | Foreign key referencing workflow_runs |
70
107
  | section_id | string | Foreign key referencing sections |
108
+ | workflow_run_id | string | Foreign key referencing workflow_runs |
71
109
 
72
110
  #### Table: step_runs
111
+ This table stores instances of step executions within a section run. Each step run can have multiple branches.
112
+
73
113
  | Field | Type | Description |
74
114
  |------------------|---------|---------------------------------------------------------------------|
75
115
  | id | string | Unique identifier for the step run |
@@ -78,9 +118,526 @@
78
118
  | branch_number | integer | Branch number to distinguish different instances (branches) of the same step |
79
119
 
80
120
  #### Table: attribute_values
121
+ This table stores the values of attributes during step executions.
122
+
81
123
  | Field | Type | Description |
82
124
  |---------------|--------|-----------------------------------------|
83
125
  | id | string | Unique identifier for the attribute value|
84
126
  | attribute_id | string | Foreign key referencing attributes |
85
127
  | step_run_id | string | Foreign key referencing step_runs |
86
128
  | value | text | The actual value of the attribute during the step execution |
129
+
130
+ ## Gemfile
131
+
132
+ ```ruby
133
+
134
+ # Gemfile
135
+
136
+ source 'https://rubygems.org'
137
+
138
+ gem 'sequel'
139
+ gem 'sqlite3'
140
+ ```
141
+
142
+ ## Database Setup
143
+
144
+
145
+ ```ruby
146
+ # db_setup.rb
147
+
148
+ require 'sequel'
149
+
150
+ DB = Sequel.sqlite('workflow.db') # Creates an SQLite database called workflow.db
151
+
152
+ # Create the tables for static workflow definition
153
+ DB.create_table :workflows do
154
+ primary_key :id
155
+ String :name, null: false
156
+ String :description
157
+ end
158
+
159
+ DB.create_table :sections do
160
+ primary_key :id
161
+ String :name, null: false
162
+ String :description
163
+ Integer :order
164
+ foreign_key :workflow_id, :workflows
165
+ end
166
+
167
+ DB.create_table :steps do
168
+ primary_key :id
169
+ String :name, null: false
170
+ String :description
171
+ Integer :order
172
+ foreign_key :section_id, :sections
173
+ String :prompt
174
+ end
175
+
176
+ DB.create_table :attributes do
177
+ primary_key :id
178
+ String :name, null: false
179
+ String :type
180
+ Boolean :is_array
181
+ foreign_key :workflow_id, :workflows
182
+ end
183
+
184
+ DB.create_table :input_attributes do
185
+ foreign_key :step_id, :steps
186
+ foreign_key :attribute_id, :attributes
187
+ end
188
+
189
+ DB.create_table :output_attributes do
190
+ foreign_key :step_id, :steps
191
+ foreign_key :attribute_id, :attributes
192
+ end
193
+
194
+ # Create the tables for dynamic workflow execution
195
+ DB.create_table :workflow_runs do
196
+ primary_key :id
197
+ foreign_key :workflow_id, :workflows
198
+ end
199
+
200
+ DB.create_table :section_runs do
201
+ primary_key :id
202
+ foreign_key :workflow_run_id, :workflow_runs
203
+ foreign_key :section_id, :sections
204
+ end
205
+
206
+ DB.create_table :step_runs do
207
+ primary_key :id
208
+ foreign_key :section_run_id, :section_runs
209
+ foreign_key :step_id, :steps
210
+ Integer :branch_number
211
+ end
212
+
213
+ DB.create_table :attribute_values do
214
+ primary_key :id
215
+ foreign_key :attribute_id, :attributes
216
+ foreign_key :step_run_id, :step_runs
217
+ String :value
218
+ end
219
+ ```
220
+
221
+ ## Models
222
+
223
+ ```ruby
224
+ # models.rb
225
+
226
+ require 'sequel'
227
+
228
+ DB = Sequel.sqlite('workflow.db') # Connect to the SQLite database
229
+
230
+ # Static Workflow Definition
231
+
232
+ class Workflow < Sequel::Model
233
+ one_to_many :sections
234
+ one_to_many :attributes
235
+ one_to_many :workflow_runs
236
+ end
237
+
238
+ class Section < Sequel::Model
239
+ many_to_one :workflow
240
+ one_to_many :steps
241
+ one_to_many :section_runs
242
+ end
243
+
244
+ class Step < Sequel::Model
245
+ many_to_one :section
246
+ one_to_many :input_attributes, class: :StepInputAttribute
247
+ one_to_many :output_attributes, class: :StepOutputAttribute
248
+ one_to_many :step_runs
249
+ end
250
+
251
+ class Attribute < Sequel::Model
252
+ many_to_one :workflow
253
+ one_to_many :input_attributes, class: :StepInputAttribute
254
+ one_to_many :output_attributes, class: :StepOutputAttribute
255
+ end
256
+
257
+ class StepInputAttribute < Sequel::Model
258
+ many_to_one :step
259
+ many_to_one :attribute
260
+ end
261
+
262
+ class StepOutputAttribute < Sequel::Model
263
+ many_to_one :step
264
+ many_to_one :attribute
265
+ end
266
+
267
+ # Dynamic Workflow Execution
268
+
269
+ class WorkflowRun < Sequel::Model
270
+ many_to_one :workflow
271
+ one_to_many :section_runs
272
+ end
273
+
274
+ class SectionRun < Sequel::Model
275
+ many_to_one :workflow_run
276
+ many_to_one :section
277
+ one_to_many :step_runs
278
+ end
279
+
280
+ class StepRun < Sequel::Model
281
+ many_to_one :section_run
282
+ many_to_one :step
283
+ one_to_many :attribute_values
284
+ end
285
+
286
+ class AttributeValue < Sequel::Model
287
+ many_to_one :attribute
288
+ many_to_one :step_run
289
+ end
290
+
291
+ ```
292
+
293
+ ## Usage via Models
294
+
295
+ ```ruby
296
+ # example_usage.rb
297
+
298
+ require_relative 'models'
299
+
300
+ # Create a new workflow
301
+ workflow = Workflow.create(name: "YouTube Video Script", description: "Workflow for creating a YouTube video script")
302
+
303
+ # Create sections for the workflow
304
+ section1 = Section.create(name: "Research", description: "Research phase", order: 1, workflow: workflow)
305
+ section2 = Section.create(name: "Script Writing", description: "Script writing phase", order: 2, workflow: workflow)
306
+
307
+ # Create steps for the sections
308
+ step1 = Step.create(name: "01-1-basic-meta", description: "Basic metadata for Fotor AI tool", order: 1, section: section1, prompt: "Generate 5 titles to get started")
309
+ step2 = Step.create(name: "01-2-basic-factsheet", description: "Detailed factsheet about Fotor AI Tool", order: 2, section: section1, prompt: "Generate detailed factsheet")
310
+
311
+ # Create attributes
312
+ attribute1 = Attribute.create(name: "simple_title", type: "string", is_array: false, workflow: workflow)
313
+ attribute2 = Attribute.create(name: "basic_factsheet", type: "string", is_array: false, workflow: workflow)
314
+
315
+ # Associate input and output attributes with steps
316
+ StepInputAttribute.create(step: step1, attribute: attribute1)
317
+ StepOutputAttribute.create(step: step1, attribute: attribute2)
318
+
319
+ # Create a workflow run
320
+ workflow_run = WorkflowRun.create(workflow: workflow)
321
+
322
+ # Create section runs
323
+ section_run1 = SectionRun.create(workflow_run: workflow_run, section: section1)
324
+ section_run2 = SectionRun.create(workflow_run: workflow_run, section: section2)
325
+
326
+ # Create step runs
327
+ step_run1 = StepRun.create(section_run: section_run1, step: step1, branch_number: 1)
328
+ step_run2 = StepRun.create(section_run: section_run1, step: step2, branch_number: 1)
329
+
330
+ # Add attribute values to step runs
331
+ AttributeValue.create(attribute: attribute1, step_run: step_run1, value: "Fotor AI tool")
332
+ AttributeValue.create(attribute: attribute2, step_run: step_run2, value: "Detailed factsheet about Fotor AI Tool")
333
+ ```
334
+
335
+ ## Exporting to JSON
336
+
337
+ ```ruby
338
+ # export_to_json.rb
339
+
340
+ require 'json'
341
+ require_relative 'models'
342
+
343
+ # Export all workflows to JSON files
344
+ Workflow.all.each do |workflow|
345
+ workflow_data = {
346
+ id: workflow.id,
347
+ name: workflow.name,
348
+ description: workflow.description,
349
+ sections: workflow.sections.map do |section|
350
+ {
351
+ id: section.id,
352
+ name: section.name,
353
+ description: section.description,
354
+ order: section.order,
355
+ steps: section.steps.map do |step|
356
+ {
357
+ id: step.id,
358
+ name: step.name,
359
+ description: step.description,
360
+ order: step.order,
361
+ prompt: step.prompt,
362
+ input_attributes: step.input_attributes.map { |ia| { id: ia.attribute.id, name: ia.attribute.name } },
363
+ output_attributes: step.output_attributes.map { |oa| { id: oa.attribute.id, name: oa.attribute.name } }
364
+ }
365
+ end
366
+ }
367
+ end,
368
+ attributes: workflow.attributes.map { |attr| { id: attr.id, name: attr.name, type: attr.type, is_array: attr.is_array } }
369
+ }
370
+
371
+ File.write("workflow_#{workflow.id}.json", JSON.pretty_generate(workflow_data))
372
+ end
373
+
374
+ # Export all workflow runs to JSON files
375
+ WorkflowRun.all.each do |workflow_run|
376
+ workflow_run_data = {
377
+ id: workflow_run.id,
378
+ workflow_id: workflow_run.workflow_id,
379
+ section_runs: workflow_run.section_runs.map do |section_run|
380
+ {
381
+ id: section_run.id,
382
+ section_id: section_run.section_id,
383
+ step_runs: section_run.step_runs.map do |step_run|
384
+ {
385
+ id: step_run.id,
386
+ step_id: step_run.step_id,
387
+ branch_number: step_run.branch_number,
388
+ attribute_values: step_run.attribute_values.map { |av| { id: av.attribute.id, name: av.attribute.name, value: av.value } }
389
+ }
390
+ end
391
+ }
392
+ end
393
+ }
394
+
395
+ File.write("workflow_run_#{workflow_run.id}.json", JSON.pretty_generate(workflow_run_data))
396
+ end
397
+ ```
398
+
399
+ ## Importing from JSON
400
+
401
+ ```ruby
402
+ # import_from_json.rb
403
+
404
+ require 'json'
405
+ require_relative 'models'
406
+
407
+ # Helper function to find or create an attribute
408
+ def find_or_create_attribute(attr_data, workflow)
409
+ Attribute.find_or_create(name: attr_data['name'], workflow: workflow) do |attribute|
410
+ attribute.type = attr_data['type']
411
+ attribute.is_array = attr_data['is_array']
412
+ end
413
+ end
414
+
415
+ # Restore workflows from JSON files
416
+ Dir.glob('workflow_*.json').each do |file|
417
+ data = JSON.parse(File.read(file))
418
+
419
+ workflow = Workflow.find_or_create(id: data['id']) do |w|
420
+ w.name = data['name']
421
+ w.description = data['description']
422
+ end
423
+
424
+ data['sections'].each do |section_data|
425
+ section = Section.find_or_create(id: section_data['id'], workflow: workflow) do |s|
426
+ s.name = section_data['name']
427
+ s.description = section_data['description']
428
+ s.order = section_data['order']
429
+ end
430
+
431
+ section_data['steps'].each do |step_data|
432
+ step = Step.find_or_create(id: step_data['id'], section: section) do |s|
433
+ s.name = step_data['name']
434
+ s.description = step_data['description']
435
+ s.order = step_data['order']
436
+ s.prompt = step_data['prompt']
437
+ end
438
+
439
+ step_data['input_attributes'].each do |attr_data|
440
+ attribute = find_or_create_attribute(attr_data, workflow)
441
+ StepInputAttribute.find_or_create(step: step, attribute: attribute)
442
+ end
443
+
444
+ step_data['output_attributes'].each do |attr_data|
445
+ attribute = find_or_create_attribute(attr_data, workflow)
446
+ StepOutputAttribute.find_or_create(step: step, attribute: attribute)
447
+ end
448
+ end
449
+ end
450
+
451
+ data['attributes'].each do |attr_data|
452
+ find_or_create_attribute(attr_data, workflow)
453
+ end
454
+ end
455
+
456
+ # Restore workflow runs from JSON files
457
+ Dir.glob('workflow_run_*.json').each do |file|
458
+ data = JSON.parse(File.read(file))
459
+
460
+ workflow_run = WorkflowRun.find_or_create(id: data['id'], workflow_id: data['workflow_id'])
461
+
462
+ data['section_runs'].each do |section_run_data|
463
+ section_run = SectionRun.find_or_create(id: section_run_data['id'], workflow_run: workflow_run, section_id: section_run_data['section_id'])
464
+
465
+ section_run_data['step_runs'].each do |step_run_data|
466
+ step_run = StepRun.find_or_create(id: step_run_data['id'], section_run: section_run, step_id: step_run_data['step_id'], branch_number: step_run_data['branch_number'])
467
+
468
+ step_run_data['attribute_values'].each do |attr_value_data|
469
+ attribute = Attribute.find(id: attr_value_data['id'])
470
+ AttributeValue.find_or_create(attribute: attribute, step_run: step_run) do |av|
471
+ av.value = attr_value_data['value']
472
+ end
473
+ end
474
+ end
475
+ end
476
+ end
477
+ ```
478
+
479
+ ## Sample Implementation of Workflow Builder (DSL)
480
+
481
+ ```ruby
482
+ require 'yaml'
483
+ require 'sequel'
484
+
485
+ # Assuming the database and models are already set up
486
+ DB = Sequel.sqlite('workflow.db')
487
+
488
+ # Models
489
+ class Workflow < Sequel::Model
490
+ one_to_many :sections
491
+ one_to_many :attributes
492
+ one_to_many :workflow_runs
493
+ end
494
+
495
+ class Section < Sequel::Model
496
+ many_to_one :workflow
497
+ one_to_many :steps
498
+ one_to_many :section_runs
499
+ end
500
+
501
+ class Step < Sequel::Model
502
+ many_to_one :section
503
+ one_to_many :input_attributes, class: :StepInputAttribute
504
+ one_to_many :output_attributes, class: :StepOutputAttribute
505
+ one_to_many :step_runs
506
+ end
507
+
508
+ class Attribute < Sequel::Model
509
+ many_to_one :workflow
510
+ one_to_many :input_attributes, class: :StepInputAttribute
511
+ one_to_many :output_attributes, class: :StepOutputAttribute
512
+ end
513
+
514
+ class StepInputAttribute < Sequel::Model
515
+ many_to_one :step
516
+ many_to_one :attribute
517
+ end
518
+
519
+ class StepOutputAttribute < Sequel::Model
520
+ many_to_one :step
521
+ many_to_one :attribute
522
+ end
523
+
524
+ # WorkflowBuilder
525
+ class WorkflowBuilder
526
+ def initialize(name:, description: nil)
527
+ @workflow = Workflow.new(name: name, description: description)
528
+ @current_section_order = 1
529
+ end
530
+
531
+ def description(desc)
532
+ @workflow.description = desc
533
+ end
534
+
535
+ def section(name:, &block)
536
+ @current_step_order = 1
537
+ @current_section = Section.new(name: name, order: @current_section_order)
538
+ @current_section_order += 1
539
+ instance_eval(&block) if block_given?
540
+ @workflow.add_section(@current_section)
541
+ end
542
+
543
+ def step(name:, &block)
544
+ step = Step.new(name: name, order: @current_step_order)
545
+ @current_step_order += 1
546
+ instance_eval(&block) if block_given?
547
+ @current_section.add_step(step)
548
+ end
549
+
550
+ def prompt(prompt)
551
+ @current_section.steps.last.prompt = prompt
552
+ end
553
+
554
+ def save
555
+ @workflow.save
556
+ end
557
+
558
+ def to_yaml
559
+ workflow_data = {
560
+ id: @workflow.id,
561
+ name: @workflow.name,
562
+ description: @workflow.description,
563
+ sections: @workflow.sections.map do |section|
564
+ {
565
+ id: section.id,
566
+ name: section.name,
567
+ description: section.description,
568
+ order: section.order,
569
+ steps: section.steps.map do |step|
570
+ {
571
+ id: step.id,
572
+ name: step.name,
573
+ description: step.description,
574
+ order: step.order,
575
+ prompt: step.prompt
576
+ }
577
+ end
578
+ }
579
+ end
580
+ }
581
+ workflow_data.to_yaml
582
+ end
583
+ end
584
+
585
+ ```
586
+
587
+ ## Usage via DSL
588
+
589
+ ```ruby
590
+ builder = WorkflowBuilder.new(name: 'YouTube Video Script')
591
+
592
+ builder.section(name: 'Research') do
593
+ step(name: '01-1-basic-meta') do
594
+ prompt 'Generate 5 titles to get started'
595
+ end
596
+
597
+ step(name: '01-2-basic-factsheet') do
598
+ prompt 'Generate detailed factsheet'
599
+ end
600
+ end
601
+
602
+ builder.section(name: 'Script Writing') do
603
+ step(name: '02-1-create-script') do
604
+ prompt 'Generate basic script'
605
+ end
606
+ end
607
+
608
+ puts builder.to_yaml
609
+
610
+ # Save to the database
611
+ builder.save
612
+
613
+
614
+ builder = WorkflowBuilder.new(name: 'YouTube Title Creator')
615
+
616
+ builder.section(name: 'Research') do
617
+ step(name: '01-1-working-title') do
618
+ prompt 'Come up with a simple working title for the YouTube video.'
619
+ end
620
+
621
+ step(name: '01-2-keyword-research') do
622
+ prompt 'Perform basic keyword research to identify relevant keywords.'
623
+ end
624
+
625
+ step(name: '01-3-topic-research') do
626
+ prompt 'Conduct basic topic research to gather information on the subject.'
627
+ end
628
+
629
+ step(name: '01-4-powerful-titles') do
630
+ prompt 'Ask GPT for 10 powerful titles based on the research.'
631
+ end
632
+
633
+ step(name: '01-5-title-rules') do
634
+ prompt 'Follow specific rules for title creation to ensure effectiveness.'
635
+ end
636
+ end
637
+
638
+ puts builder.to_yaml
639
+
640
+ # Save to the database
641
+ builder.save
642
+
643
+ ```
@@ -0,0 +1,177 @@
1
+ workflows:
2
+ - id: 1
3
+ name: "YouTube Video Script"
4
+ description: "Workflow for creating a YouTube video script"
5
+
6
+ sections:
7
+ - id: 1
8
+ name: "Research"
9
+ description: "Research phase of the workflow"
10
+ order: 1
11
+ workflow_id: 1
12
+ - id: 2
13
+ name: "Script Writing"
14
+ description: "Script writing phase of the workflow"
15
+ order: 2
16
+ workflow_id: 1
17
+
18
+ steps:
19
+ - id: 1
20
+ name: "01-1-basic-meta"
21
+ description: "Basic metadata for Fotor AI tool"
22
+ order: 1
23
+ section_id: 1
24
+ prompt: "Generate 5 titles to get started"
25
+ - id: 2
26
+ name: "01-2-basic-factsheet"
27
+ description: "Detailed factsheet about Fotor AI Tool"
28
+ order: 2
29
+ section_id: 1
30
+ prompt: "Generate detailed factsheet"
31
+ - id: 3
32
+ name: "01-3-video-type"
33
+ description: "Identify video types"
34
+ order: 3
35
+ section_id: 1
36
+ prompt: "Identify video types based on basic factsheet"
37
+ - id: 4
38
+ name: "01-4-expanded-factsheet"
39
+ description: "Expanded factsheet about Fotor AI Tool"
40
+ order: 4
41
+ section_id: 1
42
+ prompt: "Generate expanded factsheet"
43
+ - id: 5
44
+ name: "01-5-expanded-meta"
45
+ description: "Expanded metadata for Fotor AI Tool"
46
+ order: 5
47
+ section_id: 1
48
+ prompt: "Generate engaging titles, keywords, and topics"
49
+ - id: 6
50
+ name: "02-1-create-script"
51
+ description: "Create basic script"
52
+ order: 1
53
+ section_id: 2
54
+ prompt: "Generate basic script"
55
+ - id: 7
56
+ name: "02-2-clean-transcript"
57
+ description: "Clean and revise transcript"
58
+ order: 2
59
+ section_id: 2
60
+ prompt: "Generate basic transcript"
61
+ - id: 8
62
+ name: "02-3-transcript-factchecked"
63
+ description: "Fact-check and revise transcript"
64
+ order: 3
65
+ section_id: 2
66
+ prompt: "Generate fact-checked transcript"
67
+
68
+ attributes:
69
+ - id: 1
70
+ name: "simple_title"
71
+ type: "string"
72
+ is_array: false
73
+ workflow_id: 1
74
+ - id: 2
75
+ name: "basic_factsheet"
76
+ type: "string"
77
+ is_array: false
78
+ workflow_id: 1
79
+ - id: 3
80
+ name: "focus_video_type"
81
+ type: "string"
82
+ is_array: false
83
+ workflow_id: 1
84
+ - id: 4
85
+ name: "expanded_factsheet"
86
+ type: "string"
87
+ is_array: false
88
+ workflow_id: 1
89
+ - id: 5
90
+ name: "video_types"
91
+ type: "string"
92
+ is_array: true
93
+ workflow_id: 1
94
+ - id: 6
95
+ name: "engaging_titles"
96
+ type: "string"
97
+ is_array: true
98
+ workflow_id: 1
99
+ - id: 7
100
+ name: "keywords"
101
+ type: "string"
102
+ is_array: true
103
+ workflow_id: 1
104
+ - id: 8
105
+ name: "topics"
106
+ type: "string"
107
+ is_array: true
108
+ workflow_id: 1
109
+ - id: 9
110
+ name: "basic_script"
111
+ type: "string"
112
+ is_array: false
113
+ workflow_id: 1
114
+ - id: 10
115
+ name: "basic_transcript"
116
+ type: "string"
117
+ is_array: false
118
+ workflow_id: 1
119
+ - id: 11
120
+ name: "transcript_qa"
121
+ type: "string"
122
+ is_array: false
123
+ workflow_id: 1
124
+
125
+ input_attributes:
126
+ - step_id: 1
127
+ attribute_id: 1
128
+ - step_id: 2
129
+ attribute_id: 1
130
+ - step_id: 3
131
+ attribute_id: 1
132
+ - step_id: 3
133
+ attribute_id: 2
134
+ - step_id: 4
135
+ attribute_id: 1
136
+ - step_id: 4
137
+ attribute_id: 2
138
+ - step_id: 4
139
+ attribute_id: 3
140
+ - step_id: 5
141
+ attribute_id: 1
142
+ - step_id: 5
143
+ attribute_id: 3
144
+ - step_id: 5
145
+ attribute_id: 4
146
+ - step_id: 6
147
+ attribute_id: 1
148
+ - step_id: 6
149
+ attribute_id: 3
150
+ - step_id: 6
151
+ attribute_id: 4
152
+ - step_id: 7
153
+ attribute_id: 9
154
+ - step_id: 8
155
+ attribute_id: 10
156
+
157
+ output_attributes:
158
+ - step_id: 1
159
+ attribute_id: 6
160
+ - step_id: 2
161
+ attribute_id: 2
162
+ - step_id: 3
163
+ attribute_id: 5
164
+ - step_id: 4
165
+ attribute_id: 4
166
+ - step_id: 5
167
+ attribute_id: 6
168
+ - step_id: 5
169
+ attribute_id: 7
170
+ - step_id: 5
171
+ attribute_id: 8
172
+ - step_id: 6
173
+ attribute_id: 9
174
+ - step_id: 7
175
+ attribute_id: 10
176
+ - step_id: 8
177
+ attribute_id: 11
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Usage
4
+ # DB = Sequel.sqlite # In-memory database
5
+
6
+ # schema_creator = Ad::AgentArchitecture::Database::CreateSchema.new(DB)
7
+ # schema_creator.execute
8
+ module Ad
9
+ module AgentArchitecture
10
+ module Database
11
+ # Create the database schema
12
+ class CreateSchema
13
+ attr_reader :db
14
+
15
+ def initialize(db)
16
+ @db = db
17
+ end
18
+
19
+ def execute
20
+ create_tables
21
+ define_models
22
+ end
23
+
24
+ private
25
+
26
+ def create_tables
27
+ db.create_table :workflows do
28
+ primary_key :id
29
+ String :name, null: false
30
+ String :description
31
+ end
32
+
33
+ db.create_table :sections do
34
+ primary_key :id
35
+ foreign_key :workflow_id, :workflows
36
+ String :name, null: false
37
+ String :description
38
+ Integer :order
39
+ end
40
+
41
+ db.create_table :steps do
42
+ primary_key :id
43
+ foreign_key :section_id, :sections
44
+ String :name, null: false
45
+ String :action, default: 'gpt'
46
+ String :description
47
+ Integer :order
48
+ String :prompt
49
+ end
50
+
51
+ db.create_table :attributes do
52
+ primary_key :id
53
+ foreign_key :workflow_id, :workflows
54
+ String :name, null: false
55
+ String :type
56
+ Boolean :is_array
57
+ end
58
+
59
+ db.create_table :input_attributes do
60
+ primary_key :id
61
+ foreign_key :step_id, :steps
62
+ foreign_key :attribute_id, :attributes
63
+ Boolean :required
64
+ end
65
+
66
+ db.create_table :output_attributes do
67
+ primary_key :id
68
+ foreign_key :step_id, :steps
69
+ foreign_key :attribute_id, :attributes
70
+ end
71
+
72
+ db.create_table :workflow_runs do
73
+ primary_key :id
74
+ foreign_key :workflow_id, :workflows
75
+ end
76
+
77
+ db.create_table :section_runs do
78
+ primary_key :id
79
+ foreign_key :workflow_run_id, :workflow_runs
80
+ foreign_key :section_id, :sections
81
+ end
82
+
83
+ db.create_table :step_runs do
84
+ primary_key :id
85
+ foreign_key :section_run_id, :section_runs
86
+ foreign_key :step_id, :steps
87
+ Integer :branch_number
88
+ end
89
+
90
+ db.create_table :attribute_values do
91
+ primary_key :id
92
+ foreign_key :attribute_id, :attributes
93
+ foreign_key :step_run_id, :step_runs
94
+ String :value
95
+ end
96
+ end
97
+
98
+ def define_models
99
+ Class.new(Sequel::Model(:workflows)) do
100
+ one_to_many :sections
101
+ one_to_many :attributes
102
+ one_to_many :workflow_runs
103
+ end
104
+
105
+ Class.new(Sequel::Model(:sections)) do
106
+ many_to_one :workflow
107
+ one_to_many :steps
108
+ one_to_many :section_runs
109
+ end
110
+
111
+ Class.new(Sequel::Model(:steps)) do
112
+ many_to_one :section
113
+ one_to_many :input_attributes, class: :InputAttribute
114
+ one_to_many :output_attributes, class: :OutputAttribute
115
+ one_to_many :step_runs
116
+ end
117
+
118
+ Class.new(Sequel::Model(:attributes)) do
119
+ many_to_one :workflow
120
+ one_to_many :input_attributes, class: :InputAttribute
121
+ one_to_many :output_attributes, class: :OutputAttribute
122
+ end
123
+
124
+ Class.new(Sequel::Model(:input_attributes)) do
125
+ many_to_one :step
126
+ many_to_one :attribute
127
+ end
128
+
129
+ Class.new(Sequel::Model(:output_attributes)) do
130
+ many_to_one :step
131
+ many_to_one :attribute
132
+ end
133
+
134
+ Class.new(Sequel::Model(:workflow_runs)) do
135
+ many_to_one :workflow
136
+ one_to_many :section_runs
137
+ end
138
+
139
+ Class.new(Sequel::Model(:section_runs)) do
140
+ many_to_one :workflow_run
141
+ many_to_one :section
142
+ one_to_many :step_runs
143
+ end
144
+
145
+ Class.new(Sequel::Model(:step_runs)) do
146
+ many_to_one :section_run
147
+ many_to_one :step
148
+ one_to_many :attribute_values
149
+ end
150
+
151
+ Class.new(Sequel::Model(:attribute_values)) do
152
+ many_to_one :attribute
153
+ many_to_one :step_run
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sequel'
4
+
5
+ module Ad
6
+ module AgentArchitecture
7
+ module Database
8
+ # Workflow model represents a workflow entity in the database.
9
+ class Workflow < Sequel::Model
10
+ one_to_many :sections, class: 'Ad::AgentArchitecture::Database::Section'
11
+ one_to_many :attributes, class: 'Ad::AgentArchitecture::Database::Attribute'
12
+ one_to_many :workflow_runs, class: 'Ad::AgentArchitecture::Database::WorkflowRun'
13
+ end
14
+
15
+ # Section model represents a section entity in the database.
16
+ class Section < Sequel::Model
17
+ many_to_one :workflow, class: 'Ad::AgentArchitecture::Database::Workflow'
18
+ one_to_many :steps, class: 'Ad::AgentArchitecture::Database::Step'
19
+ one_to_many :section_runs, class: 'Ad::AgentArchitecture::Database::SectionRun'
20
+ end
21
+
22
+ # Step model represents a step entity in the database.
23
+ class Step < Sequel::Model
24
+ many_to_one :section, class: 'Ad::AgentArchitecture::Database::Section'
25
+ one_to_many :input_attributes, class: 'Ad::AgentArchitecture::Database::InputAttribute'
26
+ one_to_many :output_attributes, class: 'Ad::AgentArchitecture::Database::OutputAttribute'
27
+ one_to_many :step_runs, class: 'Ad::AgentArchitecture::Database::StepRun'
28
+ end
29
+
30
+ # Attribute model represents an attribute entity in the database.
31
+ class Attribute < Sequel::Model
32
+ many_to_one :workflow, class: 'Ad::AgentArchitecture::Database::Workflow'
33
+ one_to_many :input_attributes, class: 'Ad::AgentArchitecture::Database::InputAttribute'
34
+ one_to_many :output_attributes, class: 'Ad::AgentArchitecture::Database::OutputAttribute'
35
+ end
36
+
37
+ # InputAttribute model represents an input attribute entity in the database.
38
+ class InputAttribute < Sequel::Model
39
+ many_to_one :step, class: 'Ad::AgentArchitecture::Database::Step'
40
+ many_to_one :attribute, class: 'Ad::AgentArchitecture::Database::Attribute'
41
+ end
42
+
43
+ # OutputAttribute model represents an output attribute entity in the database.
44
+ class OutputAttribute < Sequel::Model
45
+ many_to_one :step, class: 'Ad::AgentArchitecture::Database::Step'
46
+ many_to_one :attribute, class: 'Ad::AgentArchitecture::Database::Attribute'
47
+ end
48
+
49
+ # WorkflowRun model represents a workflow run entity in the database.
50
+ class WorkflowRun < Sequel::Model
51
+ many_to_one :workflow, class: 'Ad::AgentArchitecture::Database::Workflow'
52
+ one_to_many :section_runs, class: 'Ad::AgentArchitecture::Database::SectionRun'
53
+ end
54
+
55
+ # SectionRun model represents a section run entity in the database.
56
+ class SectionRun < Sequel::Model
57
+ many_to_one :workflow_run, class: 'Ad::AgentArchitecture::Database::WorkflowRun'
58
+ many_to_one :section, class: 'Ad::AgentArchitecture::Database::Section'
59
+ one_to_many :step_runs, class: 'Ad::AgentArchitecture::Database::StepRun'
60
+ end
61
+
62
+ # StepRun model represents a step run entity in the database.
63
+ class StepRun < Sequel::Model
64
+ many_to_one :section_run, class: 'Ad::AgentArchitecture::Database::SectionRun'
65
+ many_to_one :step, class: 'Ad::AgentArchitecture::Database::Step'
66
+ one_to_many :attribute_values, class: 'Ad::AgentArchitecture::Database::AttributeValue'
67
+ end
68
+
69
+ # AttributeValue model represents an attribute value entity in the database.
70
+ class AttributeValue < Sequel::Model
71
+ many_to_one :attribute, class: 'Ad::AgentArchitecture::Database::Attribute'
72
+ many_to_one :step_run, class: 'Ad::AgentArchitecture::Database::StepRun'
73
+ end
74
+ end
75
+ end
76
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ad
4
4
  module AgentArchitecture
5
- VERSION = '0.0.4'
5
+ VERSION = '0.0.5'
6
6
  end
7
7
  end
@@ -1,6 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'sequel'
4
+ require 'sqlite3'
5
+
3
6
  require 'ad/agent_architecture/version'
7
+ require 'ad/agent_architecture/db/create_schema'
8
+
9
+ DB = Sequel.sqlite
10
+
11
+ Ad::AgentArchitecture::Database::CreateSchema.new(DB).execute
12
+
13
+ require 'ad/agent_architecture/db/models'
4
14
 
5
15
  module Ad
6
16
  module AgentArchitecture
data/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "ad-agent_architecture",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "ad-agent_architecture",
9
- "version": "0.0.4",
9
+ "version": "0.0.5",
10
10
  "devDependencies": {
11
11
  "@klueless-js/semantic-release-rubygem": "github:klueless-js/semantic-release-rubygem",
12
12
  "@semantic-release/changelog": "^6.0.3",
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ad-agent_architecture",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Architecture/Schema for AI Agents",
5
5
  "scripts": {
6
6
  "release": "semantic-release"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ad-agent_architecture
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cruwys
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-06-26 00:00:00.000000000 Z
11
+ date: 2024-06-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: k_log
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sequel
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sqlite3
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2'
27
55
  description: " Architecture/Schema for AI Agents\n"
28
56
  email:
29
57
  - david@ideasmen.com.au
@@ -48,8 +76,12 @@ files:
48
76
  - bin/console
49
77
  - bin/setup
50
78
  - docs/erd.svg
79
+ - docs/images/sample-workflow.png
51
80
  - docs/requirements.md
81
+ - docs/structure-youtube-script.yaml
52
82
  - lib/ad/agent_architecture.rb
83
+ - lib/ad/agent_architecture/db/create_schema.rb
84
+ - lib/ad/agent_architecture/db/models.rb
53
85
  - lib/ad/agent_architecture/version.rb
54
86
  - package-lock.json
55
87
  - package.json