MCPcopy
hub / github.com/IBM/AssetOpsBench / run

Method run

src/agent/plan_execute/runner.py:110–185  ·  view source on GitHub ↗

Run the full plan-execute loop for a question. Steps: 1. Discover available servers from registered MCP servers. 2. Use the LLM to decompose the question into an execution plan. 3. Execute each plan step by routing tool calls to MCP servers. 4. Summar

(self, question: str)

Source from the content-addressed store, hash-verified

108 self._executor = Executor(self._meter, server_paths)
109
110 async def run(self, question: str) -> OrchestratorResult:
111 """Run the full plan-execute loop for a question.
112
113 Steps:
114 1. Discover available servers from registered MCP servers.
115 2. Use the LLM to decompose the question into an execution plan.
116 3. Execute each plan step by routing tool calls to MCP servers.
117 4. Summarise the step results into a final answer.
118
119 Args:
120 question: The user question to answer.
121
122 Returns:
123 OrchestratorResult with the final answer, the generated plan, and
124 the per-step execution trajectory.
125 """
126 with agent_run_span(
127 "plan-execute", model=self._llm.model_id, question=question
128 ) as span:
129 run_started = time.perf_counter()
130 self._meter.reset()
131
132 # 1. Discover
133 _log.info("Discovering server capabilities...")
134 server_descriptions = await self._executor.get_server_descriptions()
135
136 # 2. Plan
137 _log.info("Planning...")
138 planning_started = time.perf_counter()
139 plan = self._planner.generate_plan(question, server_descriptions)
140 planning_ms = (time.perf_counter() - planning_started) * 1000
141 _log.info("Plan has %d step(s).", len(plan.steps))
142
143 # 3. Execute
144 trajectory = await self._executor.execute_plan(plan, question)
145
146 # 4. Summarise
147 _log.info("Summarising...")
148 results_text = "\n\n".join(
149 f"Step {r.step_number} — {r.task} (server: {r.server}):\n"
150 + (r.response if r.success else f"ERROR: {r.error}")
151 for r in trajectory
152 )
153 summarization_started = time.perf_counter()
154 answer = self._meter.generate(
155 _SUMMARIZE_PROMPT.format(question=question, results=results_text)
156 )
157 summarization_ms = (time.perf_counter() - summarization_started) * 1000
158 duration_ms = (time.perf_counter() - run_started) * 1000
159
160 result = OrchestratorResult(
161 question=question,
162 answer=answer,
163 plan=plan,
164 trajectory=trajectory,
165 )
166 span.set_attribute("agent.plan.steps", len(plan.steps))
167 span.set_attribute("agent.answer.length", len(answer or ""))

Calls 8

agent_run_spanFunction · 0.90
persist_trajectoryFunction · 0.90
OrchestratorResultClass · 0.85
resetMethod · 0.80
generate_planMethod · 0.80
execute_planMethod · 0.80
generateMethod · 0.45