Module: Workflow

Included in:
AgentWorkflow
Defined in:
lib/scout/llm/mcp.rb,
lib/scout/llm/agent/workflow.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.require_workflow(name) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
# File 'lib/scout/llm/agent/workflow.rb', line 149

def self.require_workflow(name, ...)
  begin
    require_workflow_old(name, ...)
  rescue => e
    begin
      LLM.load_agent(name).workflow
    rescue
      raise e
    end
  end
end

.require_workflow_oldObject



146
# File 'lib/scout/llm/agent/workflow.rb', line 146

alias require_workflow_old require_workflow

Instance Method Details

#chat_task(task_name, &block) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/scout/llm/agent/workflow.rb', line 115

def chat_task(task_name, &block)
  input :chat, :text, 'Chat in Scout-AI chat-file format'
  task task_name => :chat do |chat|
    begin
      # No eager mkdir: directories appear lazily when the save machinery
      # (or any other writer) actually produces a file under files_dir.
      Chat.allow_path files_dir
      response = self.instance_exec(&block)

      result = if LLM::Agent === response
        agent = response
        if agent.current_chat.last[:role].to_s != 'assistant'
          agent.chat(return_messages: true)
        else
          agent.current_chat - agent.start_chat
        end.tap { log_agent(agent) }
      elsif Hash === response
        [response]
      else
        response
      end

      Chat.project(self.short_path, result)
    rescue ScoutException
      error = { role: :assistant, content: { exception: $!, job: self.short_path }.to_json }
      Chat.project(self.short_path, [error])
    end
  end
end

#mcp(*tasks) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/scout/llm/mcp.rb', line 4

def mcp(*tasks)
  tasks = tasks.flatten.compact
  tasks = self.tasks.keys if tasks.empty?

  tools = tasks.collect do |task,inputs=nil|
    tool_definition = LLM.task_tool_definition(self, task, inputs)
    description = tool_definition[:description]
    input_schema = tool_definition[:parameters].slice(:properties, :required)
    annotations = tool_definition.slice(:title)
    annotations[:read_only_hint] = true
    annotations[:destructive_hint] = false
    annotations[:idempotent_hint] = true
    annotations[:open_world_hint] = false
    MCP::Tool.define(name:task, description: description, input_schema: input_schema, annotations:annotations) do |parameters,context|
      self.job(name, parameters).run
    end
  end

  version = "1.0.0"
  MCP::Server.new(
    name: self.name,
    version: version,
    tools: tools
  )
end

#mcp_stdio(*tasks) ⇒ Object



30
31
32
33
34
35
# File 'lib/scout/llm/mcp.rb', line 30

def mcp_stdio(*tasks)
  server = mcp(*tasks)
  transport = MCP::Server::Transports::StdioTransport.new(server)
  server.transport = transport
  transport.open
end