HumanInputTool Inside a Skill — Meeting Notes Summarizer¶
This notebook shows that HITL is not only an agent-level concern — it can be embedded directly inside a reusable skill.
The meeting-notes-summarizer skill uses HumanInputTool with constrained
choices to ask the operator two questions before producing output:
- Format —
bullet-pointsorprose - Level of detail —
briefordetailed
Any agent that loads this skill gets the human-input behaviour automatically, without the caller knowing or configuring it.
Setting up the LLM¶
I recommend running these notebooks on Ollama Cloud. It serves much larger models than most laptops can run. The default cloud model is picked by benchmarking candidates on these notebooks, and an automated run checks every notebook against it each week. The notebook status page shows the current model and results.
- Create an API key at https://ollama.com/settings/keys.
- Export it before launching Jupyter:
export OLLAMA_API_KEY=<your key>. - That's all. When a notebook builds its LLM, it detects the key and uses Ollama Cloud.
Prefer to run locally? Install Ollama from https://ollama.com/download
and pull the model with ollama pull qwen3:14b. If no key is set, the
notebook starts the Ollama service for you, so there is no need to run
ollama serve. Local models are smaller, so your outputs will differ from
the recorded ones.
Prefer OpenAI or Anthropic?
- Install the extra:
uv sync --extra openaioruv sync --extra anthropic. - Export
OPENAI_API_KEYorANTHROPIC_API_KEYbefore launching Jupyter. If you forget, you will be prompted for it, which keeps the key out of the saved notebook. - Set
LLM_PROVIDER=openai(oranthropic), or passprovider="openai"tomake_llm(). A key on its own never switches providers, so one exported for unrelated work cannot reroute you.
The switch applies wherever a notebook builds its LLM with make_llm().
A notebook that constructs OllamaLLM directly stays on Ollama. Output on
gpt-5 or Claude will differ from the recorded outputs, and prompt-sensitive
examples (the ch09 evaluator pattern, ch08 supervised trajectories) may
behave noticeably differently.
# Uncomment the line below to install `llm-agents-from-scratch` from PyPI
# !pip install llm-agents-from-scratch
from llm_agents_from_scratch.notebook_utils import make_llm
import logging
from llm_agents_from_scratch import LLMAgent
from llm_agents_from_scratch.logger import enable_console_logging
from llm_agents_from_scratch.tools.default import HumanInputTool
enable_console_logging(logging.INFO)
human_input_tool = HumanInputTool()
llm = make_llm()
agent = LLMAgent(llm=llm, tools=[human_input_tool])
✓ Using Ollama Cloud (kimi-k2.7-code:cloud)
TRANSCRIPT = """\
Sprint 14 Planning — 2026-06-27
Attendees: Priya (PM), Marcus (Lead Eng), Leila (Backend),
Tom (Frontend), Ana (QA)
Priya opened by reviewing Sprint 13 velocity: 42 points delivered against a
target of 45. Two stories were rolled over — the pagination refactor (8 pts)
and the email digest feature (5 pts). Both are high priority for Sprint 14.
Marcus flagged a dependency risk: the pagination refactor depends on a database
migration scheduled for next Tuesday. If the migration slips, the refactor
cannot be merged. The team agreed to move the migration to Monday to de-risk.
Leila volunteered to pick up the email digest feature and estimated three days
of backend work. Tom said he'd need one day of frontend work once Leila's API
is ready. Ana will write the test plan today so it's ready for review by
Wednesday.
Sprint 14 commitments (44 points total):
- Pagination refactor: 8 pts — Marcus, Leila
- Email digest: 5 pts — Leila, Tom
- Auth token refresh: 3 pts — Leila
- Dashboard chart improvements: 13 pts — Tom
- Automated regression suite: 8 pts — Ana
- Performance monitoring alerts: 7 pts — Marcus
Priya reminded the team that the release is scheduled for July 11. All Sprint 14
work must be merged and QA-approved by July 9.
Meeting closed at 10:24.
"""
Running the Skill¶
When the agent activates the meeting-notes-summarizer skill, it will pause
twice to collect your preferences via HumanInputTool:
- Format —
bullet-pointsorprose - Detail level —
briefordetailed
The summary is then generated according to your choices.
result = await agent.run_with_skill(
"meeting-notes-summarizer",
prompt=f"Summarise the following meeting transcript:\n\n{TRANSCRIPT}",
)
print(result.content)
INFO (llm_agents_fs.LLMAgent) : 🚀 Starting task: This is a user-explicit skill activation. Call the from_scratch__use_skill tool with name='meeting-notes-summarizer'. Use exactly thi...[TRUNCATED] INFO (llm_agents_fs.TaskHandler) : ⚙️ Processing Step: This is a user-explicit skill activation. Call the from_scratch__use_skill tool with name='meeting-notes-summarizer'. Use exactly ...[TRUNCATED] INFO (llm_agents_fs.TaskHandler) : 🛠️ Executing Tool Call: from_scratch__use_skill INFO (llm_agents_fs.TaskHandler) : ✅ Successful Tool Call: <skill_content name="meeting-notes-summarizer"> # Meeting Notes Summarizer Produce a summary of a meeting transcript provided...[TRUNCATED] INFO (llm_agents_fs.TaskHandler) : ✅ Step Result: Following the skill's instructions, I need to ask you two quick questions before summarizing. First, what format would you like the su...[TRUNCATED] INFO (llm_agents_fs.TaskHandler) : 🧠 New Step: Call the from_scratch__human_input tool with prompt='What format would you like the summary in?' and choices=['bullet-points', 'prose']. R...[TRUNCATED] INFO (llm_agents_fs.TaskHandler) : ⚙️ Processing Step: Call the from_scratch__human_input tool with prompt='What format would you like the summary in?' and choices=['bullet-points', 'pr...[TRUNCATED] INFO (llm_agents_fs.TaskHandler) : 🛠️ Executing Tool Call: from_scratch__human_input
╭────────────────────────────────────────────────── Human Input ──────────────────────────────────────────────────╮ │ What format would you like the summary in? │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
> [bullet-points/prose]:
[scripted human] > bullet-points
INFO (llm_agents_fs.TaskHandler) : ✅ Successful Tool Call: bullet-points
INFO (llm_agents_fs.TaskHandler) : ✅ Step Result: I need to make the following tool-calls:
{
"id_": "d6e97002-d177-403d-b99d-e0d927329924",
"tool_name": "from_scratch__human_inp...[TRUNCATED]
INFO (llm_agents_fs.TaskHandler) : 🧠 New Step: Call the from_scratch__human_input tool with prompt='What level of detail?' and choices=['brief', 'detailed']. Record the response as deta...[TRUNCATED]
INFO (llm_agents_fs.TaskHandler) : ⚙️ Processing Step: Call the from_scratch__human_input tool with prompt='What level of detail?' and choices=['brief', 'detailed']. Record the response...[TRUNCATED]
INFO (llm_agents_fs.TaskHandler) : 🛠️ Executing Tool Call: from_scratch__human_input
╭────────────────────────────────────────────────── Human Input ──────────────────────────────────────────────────╮ │ What level of detail? │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
> [brief/detailed]:
[scripted human] > brief INFO (llm_agents_fs.TaskHandler) : ✅ Successful Tool Call: brief INFO (llm_agents_fs.TaskHandler) : ✅ Step Result: Got it — you chose **bullet-points** format and **brief** detail level. **Sprint 14 Planning — 2026-06-27** - **Sprint 13 recap**: 42...[TRUNCATED] INFO (llm_agents_fs.TaskHandler) : No new step required. INFO (llm_agents_fs.LLMAgent) : 🏁 Task completed: Got it — you chose **bullet-points** format and **brief** detail level. **Sprint 14 Planning — 2026-06-27** - **Sprint 13 recap**:...[TRUNCATED] Got it — you chose **bullet-points** format and **brief** detail level. **Sprint 14 Planning — 2026-06-27** - **Sprint 13 recap**: 42 of 45 points delivered; pagination refactor (8 pts) and email digest (5 pts) rolled into Sprint 14. - **Risk mitigated**: Database migration for the pagination refactor was moved from Tuesday to Monday to unblock Marcus and Leila. - **Sprint 14 commitments**: 44 points across six items, including dashboard improvements (13 pts), automated regression suite (8 pts), and performance monitoring alerts (7 pts). - **Key owners & timelines**: Leila owns email digest backend (3 days) and token refresh; Tom handles its frontend (1 day) plus dashboard charts; Ana writes the test plan today for Wednesday review; Marcus shares pagination and performance alerts. - **Deadline**: Release set for July 11; all work must be merged and QA-approved by July 9.