turnkit 0.2.10 → 0.4.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/README.md +89 -9
- data/UPGRADE.md +37 -299
- data/lib/turnkit/adapters/ruby_llm.rb +87 -0
- data/lib/turnkit/agent.rb +22 -33
- data/lib/turnkit/budget.rb +24 -5
- data/lib/turnkit/client.rb +4 -0
- data/lib/turnkit/compaction.rb +1 -0
- data/lib/turnkit/error.rb +1 -0
- data/lib/turnkit/generators/turnkit/install/templates/create_turnkit_tables.rb +0 -1
- data/lib/turnkit/image_result.rb +51 -0
- data/lib/turnkit/image_tool.rb +30 -0
- data/lib/turnkit/load_skill_tool.rb +29 -0
- data/lib/turnkit/memory_store.rb +11 -0
- data/lib/turnkit/message.rb +19 -8
- data/lib/turnkit/message_projection.rb +28 -2
- data/lib/turnkit/output_policy.rb +15 -0
- data/lib/turnkit/result.rb +41 -4
- data/lib/turnkit/run.rb +4 -5
- data/lib/turnkit/schema_check.rb +68 -0
- data/lib/turnkit/skill.rb +16 -2
- data/lib/turnkit/store.rb +6 -0
- data/lib/turnkit/stores/active_record_store.rb +10 -2
- data/lib/turnkit/sub_agent_tool.rb +2 -1
- data/lib/turnkit/system_prompt.rb +1 -1
- data/lib/turnkit/tool.rb +2 -21
- data/lib/turnkit/tool_call.rb +3 -3
- data/lib/turnkit/tool_runner.rb +41 -16
- data/lib/turnkit/turn.rb +161 -23
- data/lib/turnkit/version.rb +1 -1
- data/lib/turnkit/workflow.rb +20 -94
- data/lib/turnkit.rb +12 -10
- metadata +6 -2
data/lib/turnkit/workflow.rb
CHANGED
|
@@ -4,13 +4,7 @@ require_relative "agent"
|
|
|
4
4
|
|
|
5
5
|
module TurnKit
|
|
6
6
|
class Workflow
|
|
7
|
-
|
|
8
|
-
attr_reader :model, :client, :store, :prompt_mode, :thinking, :compaction, :output_schema
|
|
9
|
-
attr_reader :on_event
|
|
10
|
-
attr_reader :max_iterations, :timeout, :cost_limit, :max_depth, :max_tool_executions, :max_tool_executions_by_name
|
|
11
|
-
attr_reader :output_audit, :output_audit_mode, :output_policy, :output_policy_mode, :output_policy_model, :output_policy_thinking
|
|
12
|
-
|
|
13
|
-
DEFAULT_INSTRUCTIONS = <<~TEXT.strip
|
|
7
|
+
ORCHESTRATOR_PREAMBLE = <<~TEXT.strip
|
|
14
8
|
You are an autonomous task orchestrator. Navigate from the application
|
|
15
9
|
request to a final output without asking the user follow-up questions.
|
|
16
10
|
|
|
@@ -29,104 +23,36 @@ module TurnKit
|
|
|
29
23
|
limits.
|
|
30
24
|
TEXT
|
|
31
25
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
output_schema: nil, max_iterations: nil, timeout: nil, max_spend: nil,
|
|
36
|
-
cost_limit: nil, max_depth: nil, max_tool_executions: nil, max_tool_executions_by_name: nil,
|
|
37
|
-
output_audit: nil, output_audit_mode: nil, output_policy: nil, output_policy_mode: nil, output_policy_model: nil, output_policy_thinking: nil)
|
|
26
|
+
DEFAULT_INSTRUCTIONS = ORCHESTRATOR_PREAMBLE
|
|
27
|
+
|
|
28
|
+
attr_reader :name, :options
|
|
38
29
|
|
|
30
|
+
def initialize(name: "workflow", instructions: nil, preamble: true, **options)
|
|
39
31
|
@name = name.to_s
|
|
40
|
-
@description = description.to_s
|
|
41
|
-
@instructions = instructions || DEFAULT_INSTRUCTIONS
|
|
42
|
-
@tools = Array(tools)
|
|
43
|
-
@skills = Array(skills)
|
|
44
|
-
@available_skills = Array(available_skills)
|
|
45
|
-
@model = model
|
|
46
|
-
@client = client
|
|
47
|
-
@store = store
|
|
48
|
-
@prompt_mode = prompt_mode
|
|
49
|
-
@thinking = thinking
|
|
50
|
-
@compaction = compaction
|
|
51
|
-
@on_event = on_event
|
|
52
|
-
@output_schema = output_schema
|
|
53
|
-
@max_iterations = max_iterations
|
|
54
|
-
@timeout = timeout
|
|
55
|
-
@cost_limit = cost_limit || max_spend
|
|
56
|
-
@max_depth = max_depth
|
|
57
|
-
@max_tool_executions = max_tool_executions
|
|
58
|
-
@max_tool_executions_by_name = max_tool_executions_by_name
|
|
59
|
-
@output_audit = output_audit
|
|
60
|
-
@output_audit_mode = output_audit_mode
|
|
61
|
-
@output_policy = output_policy
|
|
62
|
-
@output_policy_mode = output_policy_mode
|
|
63
|
-
@output_policy_model = output_policy_model
|
|
64
|
-
@output_policy_thinking = output_policy_thinking
|
|
65
32
|
raise ArgumentError, "name is required" if @name.empty?
|
|
66
|
-
@agent = build_agent
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def run(prompt = nil, task: nil, input: nil, async: false, subject: nil, metadata: {},
|
|
70
|
-
max_spend: nil, cost_limit: nil, **options)
|
|
71
|
-
|
|
72
|
-
task = task || prompt
|
|
73
|
-
raise ArgumentError, "task is required" if task.to_s.empty?
|
|
74
|
-
|
|
75
|
-
runtime_agent = if options.empty? && cost_limit.nil? && max_spend.nil?
|
|
76
|
-
@agent
|
|
77
|
-
else
|
|
78
|
-
build_agent(cost_limit: cost_limit || max_spend, **options)
|
|
79
|
-
end
|
|
80
33
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
)
|
|
34
|
+
@options = options.merge(
|
|
35
|
+
name: @name,
|
|
36
|
+
prompt_mode: options.fetch(:prompt_mode, :task),
|
|
37
|
+
instructions: compose_instructions(instructions, preamble: preamble)
|
|
38
|
+
).freeze
|
|
39
|
+
@agent = Agent.new(**@options)
|
|
88
40
|
end
|
|
89
41
|
|
|
90
|
-
def
|
|
91
|
-
|
|
42
|
+
def run(prompt = nil, task: nil, input: nil, async: false, subject: nil, metadata: {}, **overrides)
|
|
43
|
+
agent(**overrides).run(task || prompt, input: input, async: async, subject: subject, metadata: metadata)
|
|
92
44
|
end
|
|
93
45
|
|
|
94
|
-
def
|
|
95
|
-
|
|
46
|
+
def agent(**overrides)
|
|
47
|
+
overrides.empty? ? @agent : Agent.new(**@options.merge(overrides.compact))
|
|
96
48
|
end
|
|
97
49
|
|
|
98
50
|
private
|
|
99
|
-
def
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
tools: tools,
|
|
105
|
-
skills: skills,
|
|
106
|
-
available_skills: available_skills,
|
|
107
|
-
model: model,
|
|
108
|
-
client: client,
|
|
109
|
-
store: store,
|
|
110
|
-
prompt_mode: prompt_mode,
|
|
111
|
-
thinking: thinking,
|
|
112
|
-
compaction: compaction,
|
|
113
|
-
on_event: on_event,
|
|
114
|
-
output_schema: output_schema,
|
|
115
|
-
max_iterations: max_iterations,
|
|
116
|
-
timeout: timeout,
|
|
117
|
-
cost_limit: cost_limit,
|
|
118
|
-
max_depth: max_depth,
|
|
119
|
-
max_tool_executions: max_tool_executions,
|
|
120
|
-
max_tool_executions_by_name: max_tool_executions_by_name,
|
|
121
|
-
output_audit: output_audit,
|
|
122
|
-
output_audit_mode: output_audit_mode,
|
|
123
|
-
output_policy: output_policy,
|
|
124
|
-
output_policy_mode: output_policy_mode,
|
|
125
|
-
output_policy_model: output_policy_model,
|
|
126
|
-
output_policy_thinking: output_policy_thinking
|
|
127
|
-
}
|
|
128
|
-
attrs.merge!(overrides.compact)
|
|
129
|
-
Agent.new(**attrs)
|
|
51
|
+
def compose_instructions(instructions, preamble:)
|
|
52
|
+
parts = []
|
|
53
|
+
parts << ORCHESTRATOR_PREAMBLE if preamble
|
|
54
|
+
parts << instructions.to_s.strip unless instructions.to_s.strip.empty?
|
|
55
|
+
parts.join("\n\n")
|
|
130
56
|
end
|
|
131
57
|
end
|
|
132
58
|
end
|
data/lib/turnkit.rb
CHANGED
|
@@ -15,12 +15,14 @@ require_relative "turnkit/cost"
|
|
|
15
15
|
require_relative "turnkit/budget"
|
|
16
16
|
require_relative "turnkit/event"
|
|
17
17
|
require_relative "turnkit/model_request"
|
|
18
|
+
require_relative "turnkit/schema_check"
|
|
18
19
|
require_relative "turnkit/agent"
|
|
19
20
|
require_relative "turnkit/workflow"
|
|
20
21
|
require_relative "turnkit/client"
|
|
21
22
|
require_relative "turnkit/conversation"
|
|
22
23
|
require_relative "turnkit/message"
|
|
23
24
|
require_relative "turnkit/record"
|
|
25
|
+
require_relative "turnkit/image_result"
|
|
24
26
|
require_relative "turnkit/result"
|
|
25
27
|
require_relative "turnkit/skill"
|
|
26
28
|
require_relative "turnkit/output_audit"
|
|
@@ -33,9 +35,11 @@ require_relative "turnkit/store"
|
|
|
33
35
|
require_relative "turnkit/memory_store"
|
|
34
36
|
require_relative "turnkit/compaction"
|
|
35
37
|
require_relative "turnkit/tool"
|
|
38
|
+
require_relative "turnkit/image_tool"
|
|
36
39
|
require_relative "turnkit/tool_call"
|
|
37
40
|
require_relative "turnkit/tool_execution"
|
|
38
41
|
require_relative "turnkit/sub_agent_tool"
|
|
42
|
+
require_relative "turnkit/load_skill_tool"
|
|
39
43
|
require_relative "turnkit/message_projection"
|
|
40
44
|
require_relative "turnkit/tool_runner"
|
|
41
45
|
require_relative "turnkit/turn"
|
|
@@ -52,7 +56,7 @@ module TurnKit
|
|
|
52
56
|
attr_accessor :default_model, :client, :store, :logger
|
|
53
57
|
attr_accessor :max_iterations, :timeout, :max_depth, :max_tool_executions
|
|
54
58
|
attr_accessor :max_tool_executions_by_name
|
|
55
|
-
attr_accessor :
|
|
59
|
+
attr_accessor :max_spend, :prompt_cache
|
|
56
60
|
attr_accessor :compaction
|
|
57
61
|
attr_accessor :output_policy_model, :output_policy_thinking
|
|
58
62
|
attr_accessor :cost_rates, :cost_calculator
|
|
@@ -72,6 +76,7 @@ module TurnKit
|
|
|
72
76
|
self.max_depth = 3
|
|
73
77
|
self.max_tool_executions = 100
|
|
74
78
|
self.max_tool_executions_by_name = {}
|
|
79
|
+
self.max_spend = nil
|
|
75
80
|
self.prompt_cache = :auto
|
|
76
81
|
self.compaction = true
|
|
77
82
|
self.cost_rates = {}
|
|
@@ -97,21 +102,18 @@ module TurnKit
|
|
|
97
102
|
self.default_model = value
|
|
98
103
|
end
|
|
99
104
|
|
|
100
|
-
def self.max_spend
|
|
101
|
-
cost_limit
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def self.max_spend=(value)
|
|
105
|
-
self.cost_limit = value
|
|
106
|
-
end
|
|
107
|
-
|
|
108
105
|
def self.reconcile_stale!(before: Clock.now - (timeout || 300))
|
|
109
106
|
store.find_stale_turns(before: before).each do |turn|
|
|
110
107
|
store.update_turn(turn.fetch("id"), "status" => "stale", "completed_at" => Clock.now)
|
|
111
108
|
end
|
|
112
109
|
end
|
|
113
110
|
|
|
114
|
-
def self.
|
|
111
|
+
def self.check_output_policy(output, constraints: [], context: {})
|
|
115
112
|
OutputAudit.check(output, constraints: constraints, context: context)
|
|
116
113
|
end
|
|
114
|
+
|
|
115
|
+
def self.paint(prompt, model:, provider: nil, size: nil, assume_model_exists: nil, input_images: nil, mask: nil, params: {}, metadata: {}, client: nil)
|
|
116
|
+
image_client = client || self.client
|
|
117
|
+
image_client.paint(prompt: prompt, model: model, provider: provider, size: size, assume_model_exists: assume_model_exists, input_images: input_images, mask: mask, params: params, metadata: metadata).images.first
|
|
118
|
+
end
|
|
117
119
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: turnkit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sam Couch
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-06-
|
|
11
|
+
date: 2026-06-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: ruby_llm
|
|
@@ -57,6 +57,9 @@ files:
|
|
|
57
57
|
- lib/turnkit/generators/turnkit/install/templates/turn.rb
|
|
58
58
|
- lib/turnkit/generators/turnkit/install_generator.rb
|
|
59
59
|
- lib/turnkit/id.rb
|
|
60
|
+
- lib/turnkit/image_result.rb
|
|
61
|
+
- lib/turnkit/image_tool.rb
|
|
62
|
+
- lib/turnkit/load_skill_tool.rb
|
|
60
63
|
- lib/turnkit/memory_store.rb
|
|
61
64
|
- lib/turnkit/message.rb
|
|
62
65
|
- lib/turnkit/message_projection.rb
|
|
@@ -70,6 +73,7 @@ files:
|
|
|
70
73
|
- lib/turnkit/record.rb
|
|
71
74
|
- lib/turnkit/result.rb
|
|
72
75
|
- lib/turnkit/run.rb
|
|
76
|
+
- lib/turnkit/schema_check.rb
|
|
73
77
|
- lib/turnkit/skill.rb
|
|
74
78
|
- lib/turnkit/store.rb
|
|
75
79
|
- lib/turnkit/stores/active_record_store.rb
|