Skip to content

Narratives prompts - #449

Open
ddebasmita-lab wants to merge 3 commits into
datacommonsorg:mainfrom
ddebasmita-lab:narratives-prompts
Open

Narratives prompts#449
ddebasmita-lab wants to merge 3 commits into
datacommonsorg:mainfrom
ddebasmita-lab:narratives-prompts

Conversation

@ddebasmita-lab

Copy link
Copy Markdown
Contributor

Prompt loading and a reusable, instance-agnostic prompt set

  • Prompts now load from the instance's config bucket. The bootstrap fetches prompts/.md alongside agent-config.json and merges the bodies into the config the workflows already read. An inline prompts entry still takes precedence, and a slot that's absent is skipped with a warning, so startup is never blocked by a partial upload.
  • The four prompts are generic and reusable. They cover how the agent should search, cite and format, without naming a country, agency, dataset or currency — so the same set is a sound starting point for any instance.
  • Customisation is per-instance, no rebuild. Each instance loads its own copy from its bucket, so operators tailor the prompts there exactly as they tailor branding.json. {{CURRENT_DATETIME}} is rendered at request time.
  • Compact by design. The shipped tool-loop prompt is 6.5 KB and the full set 16 KB, keeping per-iteration token cost low while leaving room for operators to add their own dataset details.
  • Robust config fetching. The bucket fetch pins UTF-8, so currency symbols, arrows and em-dashes arrive intact in prompts, agent-config.json and branding.json alike. HTML comments are stripped, letting the .md files carry authoring notes that never reach the model.
  • Schema completeness and key hygiene. The follow_up slot is now declared alongside mcp, kb and synthesis, and the schema describes only fields the agent reads. agent/config.json and deploy.env are git-ignored, keeping local development credentials out of the repo.
  • Verified on a live Cloud Run deployment. All four prompts loaded from the bucket at startup, and a real query drove the intended search_indicators → get_observations sequence, returning bold figures, a numbered citation built from real source provenance, and follow-up suggestions.

Two halves of the same gap: the agent never loaded its prompts, and the prompts
that existed were written for one specific instance.

**The prompts were never loaded.** The workflows read config["prompts"][slot],
but nothing populated it. _bootstrap_config_from_url() fetched only
agent-config.json, whose prompts object is empty, and no code path read the .md
files. The MCP tool loop, the KB phase and synthesis therefore ran with no
system instruction at all. follow_up was the only governed phase, because its
default lives in code.

_bootstrap_config_from_url() now fetches prompts/<slot>.md from the same bucket
path as agent-config.json and merges the bodies in. An inline prompts slot still
wins, as the schema documents. A slot that 404s is skipped with a warning rather
than failing startup, so a partial fetch degrades to the previous behaviour
instead of taking the agent down. HTML comments are stripped so the .md files
can carry authoring notes without those notes reaching the model.

The config-bucket fetch also pins UTF-8. Buckets serve .md as text/markdown with
no charset, so requests guessed the encoding from the bytes and corrupted
currency symbols, arrows and em-dashes. Every prompt was affected, silently.
This covers agent-config.json and branding.json too.

**The prompts are now instance-agnostic.** They carry no country, agency,
dataset or currency of their own — they describe how to search, cite and format,
and nothing else. The agent loads prompts/<slot>.md from the instance's own
config bucket, so customising them is a per-instance edit in that bucket, the
same as branding.json. Only {{CURRENT_DATETIME}} is substituted; everything else
is literal text.

That is deliberate rather than a limitation. A fixed set of substitution
variables would have to assume a shape — a country with states, a fiscal year —
and instances are not all shaped that way. One may be a single state whose
sub-units are districts, another may be thematic with no default place at all.
Prose an operator writes for their own instance fits every shape; a schema of
placeholders fits one.

Dropping the instance-specific catalogue also cut the tool-loop prompt by 81%
(33KB to 6.5KB), since the bulk of it was one instance's variable reference.
Across all four prompts, 46KB became 16KB. config/README.md explains what is
worth adding back locally — above all, the custom variable DCIDs, because the
ingest indexes descriptions rather than names.

follow_up.md is byte-identical to DEFAULT_FOLLOW_UP_PROMPT, so declaring that
slot changes nothing today but stops the two copies drifting. It needed the
schema's prompts object to admit it, which additionalProperties: false blocked.

Enabling these prompts is a behaviour change, not only a fix: instructions that
have never executed now go live on every request.
`agent/config.json` was not ignored. A deployed instance never uses it — it
fetches config from the instance bucket via CONFIG_URL and reads API keys from
Secret Manager — but the local development flow writes real Gemini keys into it,
so `git add -A` would have staged them into a public repo.

Also ignores `deploy.env`, which holds the API keys used to drive a deployment,
in both git and the Docker build context.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a mechanism to fetch and merge markdown system prompts (mcp, kb, synthesis, and follow_up) from a GCS config bucket into the agent's configuration at startup, while removing unused template variables. The review feedback recommends using urllib.parse to robustly handle URLs with query parameters when deriving prompt URLs, and explicitly specifying encoding="utf-8" when writing configuration files to prevent platform-dependent encoding issues.

Comment thread narratives/agent/src/config.py Outdated
Comment thread narratives/agent/src/config.py Outdated
Comment thread narratives/agent/src/config.py Outdated
Comment thread narratives/agent/src/config.py Outdated
…TF-8

Two review fixes in the config bootstrap.

Prompt URLs were derived by splitting the raw CONFIG_URL string, so a query
containing a slash (?prefix=a/b) split mid-query and produced a nonsense base.
Parse the URL and rewrite only its path. Query and fragment are dropped: they
address the config object, not the prompt objects, so carrying a generation or
a signed-URL signature across would 403. Private buckets are read with the
metadata token, which is unaffected.

Config reads and writes now name utf-8 explicitly instead of relying on the
platform default, which is not UTF-8 on Windows. Both sides are pinned, so the
currency symbols and em-dashes the prompts carry survive the round trip.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant