# Loomi Hackathon Content Generator

Context-orchestrated Bloomreach Engagement solution generator.

This project builds a **manual solution-pack generator** for Bloomreach Engagement projects. The target architecture is deliberately small: Claude Code/Codex + Loomi MCP + local context.

- Loomi MCP provides project truth: scenarios, segmentations, customer filters, schemas, consent, frequency policies, predictions, analytics.
- Local context provides business rules, industry packs, platform rules, and reusable project notes.
- This generator provides orchestration: project brief, segmentation strategy, scenario blueprint, contentgen API payloads, measurement, and risk review.
- The output is copy/paste-ready guidance. It does not create Bloomreach assets directly.

For email scenarios, the Bloomreach scenario creates email structure and content at runtime through the contentgen API webhook. The webhook returns `webhook.available` and `webhook.cache_key`; the scenario stores the cache key in `customer.customer_variant`; the email template renders `catalogs.content.item_by_id(customer.customer_variant).json | from_json`.

## MVP Shape

Public tools:

- `build_project_brief`
- `recommend_segmentations`
- `refine_segmentations`
- `generate_scenario_from_segments`
- `generate_node_content`
- `generate_solution_pack`
- `refine_solution_pack`
- `validate_solution_pack`

Main context layers:

- [docs/agent-context/router.md](docs/agent-context/router.md)
- [contexts/team.md](contexts/team.md)
- [contexts/industries/ecommerce.md](contexts/industries/ecommerce.md)
- [contexts/industries/sportsbook.md](contexts/industries/sportsbook.md)
- [contexts/platforms/bloomreach.md](contexts/platforms/bloomreach.md)
- [prompts/router.md](prompts/router.md)
- [prompts/advisors](prompts/advisors)
- [schemas/solution-pack.schema.json](schemas/solution-pack.schema.json)
- [docs/strategy-loop.md](docs/strategy-loop.md)
- [docs/context-orchestration.md](docs/context-orchestration.md)

Default context lives in `contexts/` and supplied `projectContextJson`. If a Bloomreach CLI workspace export is available, use it as optional richer project evidence with the card-first fallback described in [docs/context-orchestration.md](docs/context-orchestration.md).

Project-local Codex skills:

- [loomi-crm-strategy-loop](skills/loomi-crm-strategy-loop/SKILL.md)
- [loomi-project-discovery-brief](skills/loomi-project-discovery-brief/SKILL.md)
- [loomi-segmentation-strategy](skills/loomi-segmentation-strategy/SKILL.md)
- [loomi-scenario-blueprint](skills/loomi-scenario-blueprint/SKILL.md)
- [loomi-node-content-generation](skills/loomi-node-content-generation/SKILL.md)

## Install

```bash
npm install
npm test
```

## CLI

Generate a draft from local context:

```bash
node ./bin/loomi-content-generator.js generate \
  --request "Generate an abandoned cart email scenario" \
  --industry ecommerce \
  --team contexts/team.md
```

Validate a saved pack:

```bash
node ./bin/loomi-content-generator.js validate --pack pack.json
```

## MCP

Run the stdio MCP server:

```bash
npm run mcp
```

The MCP server exposes:

- `build_project_brief`
- `recommend_segmentations`
- `refine_segmentations`
- `generate_scenario_from_segments`
- `generate_node_content`
- `generate_solution_pack`
- `refine_solution_pack`
- `validate_solution_pack`

## Contentgen Backend

Run the webhook backend locally:

```bash
npm run serve
```

Default URL:

```text
POST http://127.0.0.1:8787/contentgen/api/v1/generate
```

The service computes `cache_key` / `item_id` as the MD5 hash of:

```text
customer_segment_id + city + country + campaign_strategy_variant + category
```

On cache hit it returns `available: true`. On cache miss it returns `available: false`, queues background generation, and writes the completed JSON into the configured catalog client.

By default the service uses an in-memory catalog client for local development and tests. To write to Bloomreach through the sibling Bloomreach CLI, set:

```bash
CONTENTGEN_CATALOG_CLIENT=bloomreach-cli
BLOOMREACH_CLI_PATH=../bloomreach-cli/bin/bloomreach.js
BLOOMREACH_CONFIG=../bloomreach-cli/.bloomreachrc.json
BLOOMREACH_PROFILE=<profile>
CONTENTGEN_CATALOG_NAME=content
```

Optional runtime inputs:

- `PRODUCT_CATALOG_FILE` - local JSON product catalog used for product selection fallback.
- `LOOMI_MCP_URL`, `LOOMI_PROJECT_ID`, `PRODUCT_CATALOG_ID`, and `PRODUCT_VARIANTS_CATALOG_ID` - read product items through a Loomi MCP HTTP endpoint.
- `GEMINI_API_KEY` or `NANO_BANANA_API_KEY` - Google AI Studio key for Gemini 2.5 Flash Image.
- `CONTENTGEN_PUBLIC_URL` - public service URL, e.g. `https://cod-beta.solution-production.eu/contentgen`, used to build generated image URLs.
- `CONTENTGEN_PORT`, `CONTENTGEN_HOST` - HTTP bind settings.

## Design Principle

This repo intentionally does **not** create or update Bloomreach campaign assets. The user reviews the generated solution, modifies it with the assistant, then manually implements it in Bloomreach. The optional runtime backend can write generated content items to the configured `content` catalog only when explicitly started with a catalog adapter.
