Metadata-Version: 2.4
Name: design-scout-backend
Version: 0.1.0
Summary: SQLite job service and configurable image-agent toolkit for Design Scout.
Requires-Python: >=3.11
Description-Content-Type: text/markdown

# Design Scout

Design Scout is a browser workspace for researching physical-digital product ideas, generating object concept images with MuleRun, animating them with image-to-video, and saving every run to SQLite.

The static frontend can be hosted publicly with MuleRun Pages. The local backend package adds the SQLite job API and the agent toolkit that searches the generated-media dataset.

## What Is Included

- `index.html` plus `design-scout-v17.js` and `design-scout-v10.css`: the web app.
- `design_scout_backend/`: the packaged Python backend.
- `services/`: compatibility wrappers for older commands/imports.
- `model-config.example.json`: agent tool configuration.
- `example.env`: local environment template.
- `job-service-client.js`: browser client for `/api/jobs` and `/api/agent`.

## Backend Package

The real backend package is `design_scout_backend`.

```text
design_scout_backend/
  __init__.py
  __main__.py
  cli.py
  image_agent.py
  job_service.py
  mcp_server.py
```

Run it directly from this repo:

```bash
python3 -m design_scout_backend
```

The old command still works through a compatibility wrapper:

```bash
python3 services/job_service.py
```

You can also install the package in editable mode:

```bash
python3 -m pip install -e .
design-scout --help
design-scout-mcp --help
design-scout-service
```

## CLI

The package exposes a general CLI:

```bash
design-scout --help
```

During local development you can run the same CLI without installing:

```bash
python3 -m design_scout_backend.cli --help
```

Start the backend:

```bash
design-scout serve
```

Inspect resolved paths and config:

```bash
design-scout config
design-scout config --json
```

Work with jobs:

```bash
design-scout jobs list
design-scout jobs list --json
design-scout jobs export ./design-scout-jobs.sqlite3
design-scout jobs upsert ./job.json
design-scout jobs clear --yes
```

Use a different database or config path:

```bash
design-scout --db-path /tmp/design-scout.sqlite3 jobs list
design-scout agent search --db-path /tmp/design-scout.sqlite3 --query "pcb actuator enclosure"
```

Use the agent toolkit from the terminal:

```bash
design-scout agent tools
design-scout agent dataset --json
design-scout agent search --image "https://example.com/reference.jpg" --query "autonomous assembly machine" --limit 5
```

## MCP Server

Design Scout can also run as a stdio MCP server:

```bash
design-scout mcp
```

or directly:

```bash
python3 -m design_scout_backend.mcp_server
```

After editable install, a dedicated script is also available:

```bash
design-scout-mcp
```

Example MCP client config:

```json
{
  "mcpServers": {
    "design-scout": {
      "command": "python3",
      "args": [
        "-m",
        "design_scout_backend.mcp_server",
        "--root",
        "/path/to/mulerun-sample"
      ]
    }
  }
}
```

The MCP server exposes these tools:

- `design_scout_config`
- `design_scout_jobs_list`
- `design_scout_jobs_upsert`
- `design_scout_agent_tools`
- `design_scout_agent_dataset`
- `design_scout_search_images`

## Local Setup

Copy the env template:

```bash
cp example.env .env
```

Set at least:

```bash
MULEROUTER_SITE=mulerun
MULEROUTER_BASE_URL=https://api.mulerun.com
MULEROUTER_API_KEY=your-mulerun-key-here
```

Start the backend:

```bash
python3 -m design_scout_backend
```

Open:

```text
http://127.0.0.1:8787
```

## Environment Variables

- `DESIGN_SCOUT_ROOT`: root folder containing the static app and config files. Defaults to this repo when running locally.
- `JOB_SERVICE_HOST`: backend host, default `127.0.0.1`.
- `JOB_SERVICE_PORT`: backend port, default `8787`.
- `JOB_SERVICE_DB_PATH`: SQLite database path, default `./data/design-scout-jobs.sqlite3`.
- `JOB_SERVICE_STATIC_ROOT`: static files served by the backend, default `.`.
- `JOB_SERVICE_ALLOWED_ORIGINS`: comma-separated CORS allow-list.
- `DESIGN_SCOUT_JOB_SERVICE_URL`: frontend API base path, default `/api`.
- `IMAGE_AGENT_MODEL_CONFIG`: model/tool config path, default `./model-config.example.json`.
- `IMAGE_AGENT_SEARCH_ENDPOINT`: optional external image-search endpoint.
- `IMAGE_AGENT_SEARCH_AUTH`: optional auth header value for the external search endpoint.

## API

Jobs:

- `GET /api/jobs/health`
- `GET /api/jobs`
- `POST /api/jobs`
- `DELETE /api/jobs`
- `GET /api/jobs/export`

Agent:

- `GET /api/agent/tools`
- `GET /api/agent/dataset`
- `POST /api/agent/search-images`

Search request example:

```json
{
  "image": "https://example.com/reference.jpg",
  "query": "pcb actuator enclosure",
  "limit": 8
}
```

## Agent Toolkit

Agents should import the toolkit from the package:

```python
from pathlib import Path
from design_scout_backend import ImageAgentToolkit
from design_scout_backend.job_service import list_jobs

toolkit = ImageAgentToolkit(
    jobs_loader=list_jobs,
    config_path=Path("model-config.example.json"),
)

tools = toolkit.tools()
dataset = toolkit.dataset()
results = toolkit.search_images({
    "image": "https://example.com/reference.jpg",
    "query": "pcb actuator enclosure",
    "limit": 5,
})
```

Generic tool invocation is also supported:

```python
toolkit.invoke("search_images", {"query": "autonomous assembly machine"})
```

The dataset contract is stable:

```text
design-scout-image-dataset-v1
```

The implementation is environment-dependent. `model-config.example.json` decides which tools are enabled. By default, the toolkit uses `metadata_search`. If you enable `http_image_search`, the backend posts this payload to your configured endpoint:

```json
{
  "dataset": {},
  "image": "https://example.com/reference.jpg",
  "query": "pcb actuator enclosure",
  "limit": 8,
  "tool": "external-image-search"
}
```

The endpoint should return either:

```json
{
  "results": []
}
```

or a raw JSON array of results.

Set `"required": true` or `"require_tools": true` when you want the agent to fail instead of falling back to metadata search.

## Public Page

The static page is deployed at:

```text
https://c7p6rcsu.mule.page
```

The public page can load the UI, generate through the user's MuleRun key, and use browser-side job storage. The full SQLite job service and agent API require the local Python backend.

## Verification

Run syntax checks:

```bash
python3 -m py_compile design_scout_backend/*.py services/*.py
python3 -m design_scout_backend.cli --help
python3 -m design_scout_backend.mcp_server --help
node --check --input-type=module < design-scout-v17.js
node --check --input-type=module < job-service-client.js
```

Smoke-test the toolkit:

```bash
python3 - <<'PY'
from pathlib import Path
from design_scout_backend.image_agent import ImageAgentToolkit

jobs = lambda: [{
    "id": "demo",
    "created_at": "2026-01-01T00:00:00Z",
    "updated_at": "2026-01-01T00:00:00Z",
    "status": "succeeded",
    "object": "PCB actuator enclosure",
    "query": "robot harness service cover",
    "category": "electromechanical system",
    "aspect_ratio": "16:9",
    "prompt": "A generated product render",
    "brief": "Controller PCB and actuator packaging",
    "references_json": "[]",
    "job_type": "image",
    "task_id": "task-demo",
    "image_url": "https://example.com/demo.png",
    "video_url": "",
}]

toolkit = ImageAgentToolkit(jobs, config_path=Path("model-config.example.json"))
print(toolkit.search_images({"query": "pcb actuator", "limit": 3})["tool"])
PY
```
