Small models fail to call tools in two patterns:
Explicit time/date queries ("what time is it?", "what day is it?") are unambiguous. Gemma's training data is frozen — it knows it can't answer correctly — which pushes it toward tool use. These queries are the reliable case.
Explicit queries ("where are you?", "what's my location?") should work.
Implicit queries ("what's a good restaurant nearby?", "what's the weather?") will
not reliably trigger get_location in a 2B model without very strong prompt guidance.
| Lever | Mechanism | Coverage |
|---|---|---|
| 1. System prompt rules | Explicit imperative rules in config/generator.yaml — same pattern that makes search_memory reliable |
Explicit queries; works for both tools |
| 2. Tool description wording | Imperative "Call this tool when…" language in the schema description field |
Reinforces lever 1; helps model selection when multiple tools are registered |
| 3. Context injection fallback | GeneratorAgent._build_messages() prepends [Current datetime: …] to every system message — Gemma sees fresh data without needing to call the tool |
Guarantees correct answers regardless of tool-calling reliability; costs ~10 tokens per turn |
get_datetime){
"type": "function",
"function": {
"name": "get_datetime",
"description": "Returns the current local date, time, day of week, and timezone. Call this tool whenever the user asks about the current time, date, day, or timezone. Do not answer time or date questions from training data — always call this tool.",
"parameters": {
"type": "object",
"properties": {},
"required": []
}
}
}
"Tuesday 2026-06-03 09:17:42 PDT (UTC-7)"
import time
from datetime import datetime
import zoneinfo # stdlib Python 3.9+
def _get_datetime() -> str:
now = datetime.now().astimezone()
tz_name = now.strftime("%Z") # e.g. "PDT"
utc_offset = now.strftime("%z") # e.g. "+0700" → format as UTC-7
offset_h = int(utc_offset[:3])
utc_str = f"UTC{offset_h:+d}"
return now.strftime(f"%A %Y-%m-%d %H:%M:%S ") + f"{tz_name} ({utc_str})"
No config file needed. Follows the existing tool pattern: publishes schema on
tool.schema at startup; responds to tool.request.get_datetime;
publishes result on tool.result.get_datetime.
get_location){
"type": "function",
"function": {
"name": "get_location",
"description": "Returns the user's current location (city, state, country, timezone, and optionally coordinates). Call this tool when the user asks where you are, where they are, or when answering a question that requires knowing the local area.",
"parameters": {
"type": "object",
"properties": {},
"required": []
}
}
}
"Cupertino, California, United States (America/Los_Angeles, 37.3230° N, 122.0322° W)"
config/location.yamlcity: "Cupertino"
state: "California"
country: "United States"
timezone: "America/Los_Angeles"
coordinates: "37.3230° N, 122.0322° W" # optional — omit to exclude from result
If config/location.yaml is missing or empty, the tool returns
"Location not configured — edit config/location.yaml" rather than failing.
Add to config/generator.yaml system_prompt:
- If the user asks about the current date, time, day of week, or timezone —
call get_datetime. Never answer time or date questions from training data.
- If the user asks where you are, what your location is, or asks a question
that requires knowing the local area — call get_location.
If Gemma proves unreliable at calling get_datetime even with the system prompt rule,
add a one-line prepend in GeneratorAgent._build_messages():
if self._inject_datetime: # config flag: inject_datetime: true
now_str = _format_datetime()
system_content = f"[Current datetime: {now_str}]\n\n" + system_content
This costs ~10 tokens per turn and makes correct date/time answers unconditional.
Add inject_datetime: false to config/generator.yaml so it can be toggled
without a code change.
| File | Purpose |
|---|---|
src/local/tools/datetime_tool.py | NEW — DateTimeTool |
src/local/tools/location_tool.py | NEW — LocationTool |
config/location.yaml | NEW — user location config |
| File | Change |
|---|---|
config/generator.yaml | Add get_datetime and get_location rules to system_prompt |
run_local.py | Start datetime_tool and location_tool alongside other tools |
web_search_tool.py and web_fetch_tool.py:
publish schema on tool.schema at startup, subscribe to tool.request.<name>,
publish result on tool.result.<name>. The ToolWindow in the UI will
spawn reactively when the schema arrives — no UI changes needed.
class DateTimeTool:
TOOL_NAME = "get_datetime"
def __init__(self) -> None:
self._pub, self._sub = make_participant_bus(
[TOOL_SCHEMA_REQUEST, f"tool.request.{self.TOOL_NAME}"]
)
def run(self) -> None:
self._announce_schema()
while True:
envelope = self._sub.receive()
if envelope.subject == TOOL_SCHEMA_REQUEST:
self._announce_schema()
elif envelope.subject == f"tool.request.{self.TOOL_NAME}":
self._handle_request(envelope)
def _announce_schema(self) -> None:
self._pub.publish(MessageEnvelope.create(
message_type="tool_schema",
subject=TOOL_SCHEMA,
sender_id=self.TOOL_NAME,
payload={"schema": SCHEMA},
))
def _handle_request(self, envelope: MessageEnvelope) -> None:
result = _get_datetime()
self._pub.publish(MessageEnvelope.create(
message_type="tool_result",
subject=f"tool.result.{self.TOOL_NAME}",
sender_id=self.TOOL_NAME,
payload={"result": result},
correlation_id=envelope.correlation_id,
))
# Tools start first; generator waits 0.5s after tools so schemas are registered
procs = [
("web_search", [...]),
("web_fetch", [...]),
("datetime", ["python", "-m", "local.tools.datetime_tool"]),
("location", ["python", "-m", "local.tools.location_tool"]),
("generator_a", [...]),
("generator_b", [...]), # if dual-respondent enabled
...
]
tests/test_datetime_tool.pytests/test_location_tool.py| Turn | Query | Assertion |
|---|---|---|
| 1 | "What day of the week is it?" | Answer contains the correct day name (verified at test time) |
| 2 | "What year is it?" | Answer contains "2026" |
| 3 | "Where are you located?" | Answer contains the city from config/location.yaml |
get_datetime and get_location system prompt rules to config/generator.yamlsrc/local/tools/datetime_tool.pysrc/local/tools/location_tool.py + config/location.yamlrun_local.py_build_messages| File | Change |
|---|---|
src/local/tools/datetime_tool.py | NEW |
src/local/tools/location_tool.py | NEW |
config/location.yaml | NEW |
config/generator.yaml | Add system prompt rules for get_datetime / get_location |
run_local.py | Start datetime_tool and location_tool |
tests/test_datetime_tool.py | NEW |
tests/test_location_tool.py | NEW |
tests/stories/s10_datetime_location.yaml | NEW |