Add HTTP and OpenAI integration documentation and rewrite Narratio contract
This commit is contained in:
@@ -25,6 +25,8 @@ This command renders the prepared prompt and effective runtime settings without
|
|||||||
- [Configuration reference](docs/config.md)
|
- [Configuration reference](docs/config.md)
|
||||||
- [Operations guide](docs/operations.md)
|
- [Operations guide](docs/operations.md)
|
||||||
- [Troubleshooting](docs/troubleshooting.md)
|
- [Troubleshooting](docs/troubleshooting.md)
|
||||||
|
- [HTTP API integration](docs/integrations/http-api.md)
|
||||||
|
- [OpenAI-compatible chat integration](docs/integrations/openai-compatible-chat.md)
|
||||||
- [Narratio subprocess integration](docs/integrations/narratio.md)
|
- [Narratio subprocess integration](docs/integrations/narratio.md)
|
||||||
- [Architecture policy](docs/policy/architecture.md)
|
- [Architecture policy](docs/policy/architecture.md)
|
||||||
- [Documentation roadmap](docs/roadmap/documentation.md)
|
- [Documentation roadmap](docs/roadmap/documentation.md)
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ go run ./cmd/scriptorium render \
|
|||||||
- `scriptorium render`: prepare prompt only; write prepared-run output as `text` or `json`.
|
- `scriptorium render`: prepare prompt only; write prepared-run output as `text` or `json`.
|
||||||
- `scriptorium serve`: start the HTTP server.
|
- `scriptorium serve`: start the HTTP server.
|
||||||
|
|
||||||
|
Integration references:
|
||||||
|
|
||||||
|
- HTTP contract: `docs/integrations/http-api.md`
|
||||||
|
- Narratio subprocess contract: `docs/integrations/narratio.md`
|
||||||
|
|
||||||
## Common Argument Rules
|
## Common Argument Rules
|
||||||
|
|
||||||
- `--config` is supported by `run`, `render`, and `serve`.
|
- `--config` is supported by `run`, `render`, and `serve`.
|
||||||
|
|||||||
@@ -204,3 +204,8 @@ Supported artifact reference types for request inputs are `file` and `inline`.
|
|||||||
- Profile examples: `profiles/`
|
- Profile examples: `profiles/`
|
||||||
- Schema examples: `schemas/`
|
- Schema examples: `schemas/`
|
||||||
- Input fixtures: `examples/fixtures/`
|
- Input fixtures: `examples/fixtures/`
|
||||||
|
|
||||||
|
## Integration References
|
||||||
|
|
||||||
|
- Inbound HTTP contract: `docs/integrations/http-api.md`
|
||||||
|
- Outbound OpenAI-compatible contract: `docs/integrations/openai-compatible-chat.md`
|
||||||
|
|||||||
186
docs/integrations/http-api.md
Normal file
186
docs/integrations/http-api.md
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
# HTTP API Integration
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This document defines the implemented inbound HTTP contract for Scriptorium.
|
||||||
|
|
||||||
|
Current scope is only:
|
||||||
|
|
||||||
|
- `POST /v1/runs`
|
||||||
|
|
||||||
|
For CLI behavior, see `docs/cli.md`.
|
||||||
|
|
||||||
|
## Endpoint
|
||||||
|
|
||||||
|
- Method: `POST`
|
||||||
|
- Path: `/v1/runs`
|
||||||
|
- Content type: JSON request/response
|
||||||
|
|
||||||
|
Route behavior:
|
||||||
|
|
||||||
|
- unknown path: `404 not_found`
|
||||||
|
- unsupported method on `/v1/runs`: `405 method_not_allowed`
|
||||||
|
|
||||||
|
## Request Body
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"prompt_id": "generic.structured_events",
|
||||||
|
"profile_id": "local-quality",
|
||||||
|
"prompt_version": "1.0.0",
|
||||||
|
"inputs": {
|
||||||
|
"transcript": {"type": "file", "uri": "./examples/fixtures/transcript.md"},
|
||||||
|
"glossary": {"type": "inline", "body": "party:\n - Rin"}
|
||||||
|
},
|
||||||
|
"vars": {
|
||||||
|
"session_date": "2026-05-04"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"endpoint": "http://localhost:8000/v1",
|
||||||
|
"model": "gpt-4o-mini",
|
||||||
|
"temperature": 0.0,
|
||||||
|
"max_tokens": 800,
|
||||||
|
"top_p": 1.0,
|
||||||
|
"timeout_seconds": 120,
|
||||||
|
"reasoning_effort": "medium",
|
||||||
|
"api_key_env": "SCRIPTORIUM_API_KEY",
|
||||||
|
"extra_params": {
|
||||||
|
"route": "primary"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include_raw_output": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Required fields:
|
||||||
|
|
||||||
|
- `prompt_id`
|
||||||
|
- `inputs` (must contain at least one named input)
|
||||||
|
|
||||||
|
Input reference types currently supported by runtime artifact loading:
|
||||||
|
|
||||||
|
- `file`
|
||||||
|
- `inline`
|
||||||
|
|
||||||
|
## Strict JSON Rules
|
||||||
|
|
||||||
|
Request decoding uses strict JSON field checks:
|
||||||
|
|
||||||
|
- unknown request fields are rejected with `400 invalid_json`
|
||||||
|
- unknown `model` fields are rejected with `400 invalid_json`
|
||||||
|
- raw API-key payload fields such as `api_key` are rejected as unknown fields
|
||||||
|
|
||||||
|
## Success Response
|
||||||
|
|
||||||
|
Status: `200 OK`
|
||||||
|
|
||||||
|
Response shape:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"artifact": {
|
||||||
|
"name": "output",
|
||||||
|
"content_type": "application/json",
|
||||||
|
"body": "{\"summary\":\"...\"}",
|
||||||
|
"uri": "",
|
||||||
|
"size": 123,
|
||||||
|
"hash": "..."
|
||||||
|
},
|
||||||
|
"validation": {
|
||||||
|
"status": "passed",
|
||||||
|
"mode": "json_schema",
|
||||||
|
"errors": [],
|
||||||
|
"schema_path": "structured_events.schema.json",
|
||||||
|
"repair_attempts": 0,
|
||||||
|
"is_valid": true
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"run_id": "...",
|
||||||
|
"prompt_id": "generic.structured_events",
|
||||||
|
"prompt_version": "1.0.0",
|
||||||
|
"prompt_hash": "...",
|
||||||
|
"rendered_prompt_hash": "...",
|
||||||
|
"selected_profile_id": "local-quality",
|
||||||
|
"model_name": "gpt-4o-mini",
|
||||||
|
"endpoint": "http://localhost:8000/v1",
|
||||||
|
"model_params": {
|
||||||
|
"endpoint": "http://localhost:8000/v1",
|
||||||
|
"model": "gpt-4o-mini",
|
||||||
|
"temperature": 0,
|
||||||
|
"max_tokens": 800,
|
||||||
|
"top_p": 1,
|
||||||
|
"timeout_seconds": 120,
|
||||||
|
"reasoning_effort": "medium",
|
||||||
|
"api_key_env": "SCRIPTORIUM_API_KEY",
|
||||||
|
"extra_params": {
|
||||||
|
"route": "primary"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"input_hashes": {
|
||||||
|
"transcript": "..."
|
||||||
|
},
|
||||||
|
"usage": {
|
||||||
|
"prompt_tokens": 11,
|
||||||
|
"completion_tokens": 22,
|
||||||
|
"total_tokens": 33
|
||||||
|
},
|
||||||
|
"start_time": "2026-05-04T12:00:00Z",
|
||||||
|
"end_time": "2026-05-04T12:00:01Z",
|
||||||
|
"duration_ms": 1000,
|
||||||
|
"validation_mode": "json_schema",
|
||||||
|
"validation_status": "passed",
|
||||||
|
"repair_attempts_used": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`raw_model_output` is omitted by default.
|
||||||
|
|
||||||
|
To include it, send:
|
||||||
|
|
||||||
|
- `"include_raw_output": true`
|
||||||
|
|
||||||
|
## Validation Failure Behavior
|
||||||
|
|
||||||
|
Validation content failures do not map to HTTP error status.
|
||||||
|
|
||||||
|
Behavior:
|
||||||
|
|
||||||
|
- status remains `200 OK`
|
||||||
|
- `validation.status` is `failed`
|
||||||
|
- validation errors are returned in `validation.errors`
|
||||||
|
|
||||||
|
## Error Responses
|
||||||
|
|
||||||
|
Error body shape:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"error": {
|
||||||
|
"code": "invalid_request",
|
||||||
|
"message": "prompt_id is required"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Current error mapping (non-exhaustive):
|
||||||
|
|
||||||
|
- `400 invalid_json`: malformed JSON or unknown JSON fields
|
||||||
|
- `400 invalid_request`: missing/invalid request fields
|
||||||
|
- `400 profile_required`: no explicit `profile_id` and prompt has no `default_profile`
|
||||||
|
- `400 prompt_load_failed`: prompt definition invalid/unloadable
|
||||||
|
- `400 profile_load_failed`: profile invalid/unloadable
|
||||||
|
- `400 artifact_read_failed`: input artifact loading failed
|
||||||
|
- `400 prompt_render_failed`: template render failed
|
||||||
|
- `400 api_key_env_missing`: named API-key environment variable is missing
|
||||||
|
- `404 prompt_not_found`
|
||||||
|
- `404 profile_not_found`
|
||||||
|
- `502 llm_failed`: outbound model request failed
|
||||||
|
- `500 validation_runtime_failed`: validator runtime/schema-load failure
|
||||||
|
- `500 internal_error`
|
||||||
|
|
||||||
|
## Security And Deployment Note
|
||||||
|
|
||||||
|
The HTTP adapter has no built-in authentication or authorization.
|
||||||
|
|
||||||
|
Deploy behind trusted controls (for example authenticated gateway/reverse proxy and network boundaries).
|
||||||
@@ -1,322 +1,114 @@
|
|||||||
# Narratio -> Scriptorium CLI Integration
|
# Narratio Subprocess Integration
|
||||||
|
|
||||||
## 1. Purpose
|
## Purpose
|
||||||
|
|
||||||
This document defines how Narratio should invoke Scriptorium through the **public CLI**.
|
This document defines the supported subprocess contract for Narratio invoking Scriptorium through the public CLI.
|
||||||
|
|
||||||
This is a **subprocess integration contract**, not an internal Go API contract.
|
This is a CLI contract, not an internal Go package integration.
|
||||||
|
|
||||||
## 2. Assumptions
|
## Supported Commands
|
||||||
|
|
||||||
- `scriptorium` is installed and available on `PATH`.
|
Narratio should invoke:
|
||||||
- Scriptorium is configured with `config.yml`.
|
|
||||||
- `config.yml` provides `prompt_dir`, `profile_dir`, and `schema_dir` as needed.
|
|
||||||
- Prompt and profile libraries are already deployed for the environment.
|
|
||||||
- Narratio provides prepared artifact files (for example polished transcript, glossary, previous recap, campaign notes).
|
|
||||||
- Initial integration is synchronous subprocess execution.
|
|
||||||
- Narratio remains the orchestrator.
|
|
||||||
|
|
||||||
In normal operation, Narratio does not need to pass `--prompt-dir` and `--profile-dir` if they are supplied by Scriptorium config.
|
|
||||||
|
|
||||||
Narratio may pass `--config <PATH>` when it must use a non-default Scriptorium config file.
|
|
||||||
|
|
||||||
## 3. Core Commands Narratio May Call
|
|
||||||
|
|
||||||
Primary commands for subprocess integration:
|
|
||||||
|
|
||||||
- `scriptorium run`
|
- `scriptorium run`
|
||||||
- `scriptorium render`
|
- `scriptorium render`
|
||||||
|
|
||||||
For production generation, use `scriptorium run`.
|
Use `run` for generation.
|
||||||
|
|
||||||
`scriptorium render` is for debugging, dry-runs, test assertions, and validating command construction without LLM execution.
|
Use `render` for preflight/debug output without LLM execution.
|
||||||
|
|
||||||
Note: `scriptorium serve` and HTTP API exist, but they are not the initial integration path.
|
## Recommended Invocation Shapes
|
||||||
|
|
||||||
## 4. Command Selection Guidance
|
Run:
|
||||||
|
|
||||||
- Use `run` to generate an output artifact.
|
|
||||||
- Use `render` to inspect the prepared prompt and effective settings without calling the LLM.
|
|
||||||
- Use `render --format json` when Narratio/tests need structured prepare output.
|
|
||||||
|
|
||||||
## 5. Recommended `run` Invocation Shape
|
|
||||||
|
|
||||||
Production shape:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
scriptorium run \
|
scriptorium run \
|
||||||
--prompt <prompt_id> \
|
--prompt <prompt_id> \
|
||||||
--input transcript=<processed-transcript-path> \
|
--input transcript=<path> \
|
||||||
--out <output-artifact-path>
|
--out <artifact_path>
|
||||||
```
|
```
|
||||||
|
|
||||||
Common optional additions:
|
Render:
|
||||||
|
|
||||||
- `--config <path>`: use a specific Scriptorium config file.
|
|
||||||
- `--profile <profile_id>`: override prompt default profile.
|
|
||||||
- `--var name=value` (repeatable): small metadata values.
|
|
||||||
- `--input name=path` (repeatable): additional named artifacts.
|
|
||||||
- `--timeout <duration>`: per-run timeout override.
|
|
||||||
- Runtime model override flags (`--llm-base-url`, `--model`, etc.) only for exceptional/operator-directed cases.
|
|
||||||
|
|
||||||
## 6. Recommended `render` Invocation Shape
|
|
||||||
|
|
||||||
Human-readable debug shape:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
scriptorium render \
|
scriptorium render \
|
||||||
--prompt <prompt_id> \
|
--prompt <prompt_id> \
|
||||||
--input transcript=<processed-transcript-path> \
|
--input transcript=<path> \
|
||||||
--format text
|
--format json
|
||||||
```
|
```
|
||||||
|
|
||||||
Structured debug/test shape:
|
Narratio may add:
|
||||||
|
|
||||||
```bash
|
- `--config <path>`
|
||||||
scriptorium render \
|
- `--profile <profile_id>`
|
||||||
--prompt <prompt_id> \
|
- repeatable `--input name=path`
|
||||||
--input transcript=<processed-transcript-path> \
|
- repeatable `--var name=value`
|
||||||
--format json \
|
- runtime overrides when explicitly needed (`--model`, `--llm-base-url`, `--timeout`, etc.)
|
||||||
--out <render-debug-path>
|
|
||||||
```
|
|
||||||
|
|
||||||
`render` does **not** call the LLM, does **not** validate model output, and does **not** perform repair.
|
## Config And Directory Behavior
|
||||||
|
|
||||||
## 7. Inputs
|
Narratio can rely on resolved app config or pass explicit paths.
|
||||||
|
|
||||||
- Pass inputs as repeated `--input name=path` flags.
|
- default config search order:
|
||||||
- `name` must match the Prompt Definition input name.
|
1. `/usr/local/etc/scriptorium/config.yml`
|
||||||
- Prefer absolute paths, or paths relative to a working directory controlled by Narratio.
|
2. `/etc/scriptorium/config.yml`
|
||||||
- Pass Audita output as the primary transcript input.
|
- explicit `--config` requires file existence and valid syntax
|
||||||
- Additional inputs may include glossary, previous recap, campaign notes, event logs, final state maps, or other prompt-specific artifacts.
|
- CLI flags override config values
|
||||||
- Scriptorium reads input files directly; Narratio does not need to inline file content for CLI use.
|
|
||||||
|
|
||||||
## 8. Variables
|
## Profile Selection
|
||||||
|
|
||||||
Use repeated `--var name=value` for small metadata values.
|
Profile selection follows runner behavior:
|
||||||
|
|
||||||
Typical examples:
|
1. explicit `--profile`
|
||||||
|
2. prompt `default_profile`
|
||||||
|
3. error if neither is available
|
||||||
|
|
||||||
- `session_date`
|
Narratio should treat prompt/profile IDs as deployment configuration, not hardcoded logic.
|
||||||
- `session_id`
|
|
||||||
- `campaign_name`
|
|
||||||
- `previous_session_id`
|
|
||||||
- `output_kind`
|
|
||||||
|
|
||||||
Large content belongs in input files, not `--var` values.
|
## Input And Variable Contract
|
||||||
|
|
||||||
## 9. Prompt IDs and Output Artifact Types
|
- Inputs use repeated `--input name=path`.
|
||||||
|
- Input names must match prompt definition input names.
|
||||||
|
- Variables use repeated `--var name=value` for small metadata values.
|
||||||
|
- Prefer file inputs for large content.
|
||||||
|
|
||||||
Narratio should treat prompt IDs as configuration, not hardcoded business logic.
|
## Environment Contract
|
||||||
|
|
||||||
Narratio config may map stage/output names to prompt IDs, for example:
|
|
||||||
|
|
||||||
- session recap prompt
|
|
||||||
- structured event extraction prompt
|
|
||||||
- glossary suggestion prompt
|
|
||||||
- player-facing summary prompt
|
|
||||||
|
|
||||||
Prompt IDs used by Narratio should come from the deployed Scriptorium prompt library.
|
|
||||||
|
|
||||||
## 10. Profiles
|
|
||||||
|
|
||||||
- Prompts may declare `default_profile`.
|
|
||||||
- Narratio may omit `--profile` to use prompt default profile.
|
|
||||||
- Narratio may pass `--profile` to force profile selection.
|
|
||||||
- This enables environment/profile selection like `local-fast`, `local-quality`, `frontier`, `batch`, or test profiles.
|
|
||||||
- Profile names should generally be Narratio configuration values.
|
|
||||||
|
|
||||||
## 11. Runtime Overrides
|
|
||||||
|
|
||||||
Supported runtime override flags:
|
|
||||||
|
|
||||||
- `--llm-base-url`
|
|
||||||
- `--model`
|
|
||||||
- `--api-key-env`
|
|
||||||
- `--temperature`
|
|
||||||
- `--max-tokens`
|
|
||||||
- `--top-p`
|
|
||||||
- `--timeout`
|
|
||||||
|
|
||||||
Guidance:
|
|
||||||
|
|
||||||
- Keep normal model/runtime settings in Execution Profiles.
|
|
||||||
- Use runtime overrides only for explicit per-run exceptions, tests, or operator overrides.
|
|
||||||
- Never pass raw API keys on the command line.
|
|
||||||
- `--api-key-env` names an environment variable; Narratio must ensure that variable is set in subprocess environment.
|
|
||||||
|
|
||||||
## 12. Config Behavior
|
|
||||||
|
|
||||||
- Default config path: `/etc/scriptorium/config.yml`.
|
|
||||||
- `--config <PATH>` overrides default path.
|
|
||||||
- Missing default config is allowed by Scriptorium.
|
|
||||||
- If `--config` is provided explicitly, the file must exist and be valid.
|
|
||||||
- CLI flags override `config.yml`.
|
|
||||||
- `config.yml` overrides built-in application defaults.
|
|
||||||
|
|
||||||
Narratio can either:
|
|
||||||
|
|
||||||
- rely on system default config path, or
|
|
||||||
- carry an explicit config path and pass `--config`.
|
|
||||||
|
|
||||||
## 13. Environment Handling
|
|
||||||
|
|
||||||
Subprocess environment recommendations:
|
|
||||||
|
|
||||||
- Pass through required API-key environment variables referenced by `api_key_env`.
|
- Pass through required API-key environment variables referenced by `api_key_env`.
|
||||||
- Do not pass raw API keys as CLI arguments.
|
- Never pass raw API keys via CLI arguments.
|
||||||
- Avoid logging full environment dumps.
|
- Keep subprocess environment scoped to required variables.
|
||||||
- Capture stdout and stderr separately.
|
|
||||||
- Use a controlled working directory.
|
|
||||||
- Prefer absolute artifact paths.
|
|
||||||
|
|
||||||
## 14. Output Handling
|
## Output And Error Handling
|
||||||
|
|
||||||
For `scriptorium run`:
|
`run`:
|
||||||
|
|
||||||
- Use `--out` when Narratio needs durable artifact files.
|
- stdout: artifact body unless `--out` is used
|
||||||
- Without `--out`, artifact content is written to stdout.
|
- `--out`: writes artifact to file
|
||||||
- Preferred orchestration pattern: always use `--out`, then treat the file as stage output artifact.
|
- stderr: success summary and errors
|
||||||
- Capture stderr for diagnostics.
|
|
||||||
|
|
||||||
For `scriptorium render`:
|
`render`:
|
||||||
|
|
||||||
- Use `--out` to store render diagnostics.
|
- stdout: prepared-run output unless `--out` is used
|
||||||
- Use `--format json` when tests need to inspect selected profile, effective runtime settings, input hashes, prompt hash, and rendered messages.
|
- stderr: errors
|
||||||
|
|
||||||
## 15. Exit Status and Errors
|
Narratio should capture stdout and stderr separately.
|
||||||
|
|
||||||
Current CLI behavior (verified from implementation/tests):
|
## Exit Status Contract
|
||||||
|
|
||||||
- `0`: success.
|
- `0`: success
|
||||||
- `1`: runtime/parse/config/load/render/generation/IO error.
|
- `1`: parse/config/load/render/generation/IO/runtime error
|
||||||
- `2`: run completed but output validation failed (`ValidationFailed`).
|
- `2`: run completed but validation failed
|
||||||
|
|
||||||
Additional details:
|
A `run` exit code `2` can still produce output (stdout or `--out`).
|
||||||
|
|
||||||
- On `run`, output artifact write happens before exit code selection. If validation fails, artifact may still be written and exit code is `2`.
|
## Security Notes
|
||||||
- `stderr` carries both errors and normal run summary output; non-empty stderr alone does not imply failure.
|
|
||||||
- `render` returns `0` on success and `1` on failures.
|
|
||||||
|
|
||||||
Narratio should treat non-zero exit codes as failed stage execution, but may record generated artifact paths if a run exited `2` and output file exists.
|
- Treat generated artifacts and stderr logs as potentially sensitive.
|
||||||
|
- Avoid logging full rendered prompts by default in production contexts.
|
||||||
|
- Use controlled output paths and access controls for persisted artifacts.
|
||||||
|
|
||||||
## 16. Recommended Narratio Integration Pattern
|
## Canonical References
|
||||||
|
|
||||||
1. Build CLI args from Narratio stage configuration.
|
- CLI behavior: `docs/cli.md`
|
||||||
2. Use subprocess context cancellation/timeout.
|
- Config behavior: `docs/config.md`
|
||||||
3. Pass absolute input paths.
|
- Operations and failure handling: `docs/operations.md`, `docs/troubleshooting.md`
|
||||||
4. Pass `--out` to a session-scoped artifact path.
|
|
||||||
5. Add `--var` metadata values.
|
|
||||||
6. Optionally add `--config`.
|
|
||||||
7. Optionally add `--profile`.
|
|
||||||
8. Ensure required API-key env vars are present.
|
|
||||||
9. Run subprocess synchronously.
|
|
||||||
10. Capture stdout/stderr separately.
|
|
||||||
11. On success, store output artifact path and invocation metadata in stage artifacts.
|
|
||||||
12. On failure, store exit code and stderr diagnostics in stage status.
|
|
||||||
|
|
||||||
## 17. Suggested Narratio Configuration Shape
|
|
||||||
|
|
||||||
Illustrative (not required schema):
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
scriptorium:
|
|
||||||
config_path: /etc/scriptorium/config.yml
|
|
||||||
stages:
|
|
||||||
session_recap:
|
|
||||||
prompt_id: dnd.session_recap
|
|
||||||
profile_id: local-quality # optional
|
|
||||||
inputs: [transcript, glossary, previous_recap]
|
|
||||||
vars: [session_id, session_date, campaign_name]
|
|
||||||
output_path_template: artifacts/{session_id}/session_recap.md
|
|
||||||
timeout: 2m
|
|
||||||
render_debug: false
|
|
||||||
```
|
|
||||||
|
|
||||||
The key idea: map Narratio stage/artifact names to prompt ID, optional profile, expected inputs, and output destination.
|
|
||||||
|
|
||||||
## 18. Testing Strategy for Narratio Integration
|
|
||||||
|
|
||||||
- Use `scriptorium render --format json` to verify command construction without LLM calls.
|
|
||||||
- Use dedicated test prompt/profile libraries for integration tests.
|
|
||||||
- Use small fixture transcripts.
|
|
||||||
- Verify missing-input failure behavior.
|
|
||||||
- Verify prompt `default_profile` behavior.
|
|
||||||
- Verify explicit `--profile` override behavior.
|
|
||||||
- Verify `--config` behavior (default and explicit).
|
|
||||||
- Verify output file creation when `--out` is used.
|
|
||||||
- Verify stderr capture on failures.
|
|
||||||
- Avoid real API keys in tests.
|
|
||||||
|
|
||||||
## 19. Security and Privacy Notes
|
|
||||||
|
|
||||||
- Never pass raw API keys on command line.
|
|
||||||
- Do not log full rendered prompts by default; transcripts may contain sensitive content.
|
|
||||||
- Avoid logging prompt content unless explicit debug mode is enabled.
|
|
||||||
- Treat generated artifacts as potentially sensitive.
|
|
||||||
- Use session-scoped, access-controlled output paths.
|
|
||||||
- `api_key_env` names should come from environment management, not embedded secrets.
|
|
||||||
|
|
||||||
## 20. Initial D&D Artifact Generation Examples
|
|
||||||
|
|
||||||
These are examples only. Use prompt IDs from the deployed prompt library.
|
|
||||||
|
|
||||||
Session recap:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
scriptorium run \
|
|
||||||
--prompt dnd.session_recap \
|
|
||||||
--input transcript=/work/session-42/transcript.polished.md \
|
|
||||||
--input glossary=/work/session-42/glossary.yml \
|
|
||||||
--out /work/session-42/artifacts/session_recap.md
|
|
||||||
```
|
|
||||||
|
|
||||||
Structured events:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
scriptorium run \
|
|
||||||
--prompt dnd.structured_events \
|
|
||||||
--input transcript=/work/session-42/transcript.polished.md \
|
|
||||||
--out /work/session-42/artifacts/structured_events.json
|
|
||||||
```
|
|
||||||
|
|
||||||
Glossary suggestions:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
scriptorium run \
|
|
||||||
--prompt dnd.glossary_suggestions \
|
|
||||||
--input transcript=/work/session-42/transcript.polished.md \
|
|
||||||
--input previous_recap=/work/session-41/artifacts/session_recap.md \
|
|
||||||
--out /work/session-42/artifacts/glossary_suggestions.md
|
|
||||||
```
|
|
||||||
|
|
||||||
Player-facing summary:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
scriptorium run \
|
|
||||||
--prompt dnd.player_summary \
|
|
||||||
--input transcript=/work/session-42/transcript.polished.md \
|
|
||||||
--input structured_events=/work/session-42/artifacts/structured_events.json \
|
|
||||||
--out /work/session-42/artifacts/player_summary.md
|
|
||||||
```
|
|
||||||
|
|
||||||
## 21. Non-Goals
|
|
||||||
|
|
||||||
Initial Narratio integration should not:
|
|
||||||
|
|
||||||
- call Scriptorium internal Go packages
|
|
||||||
- use HTTP API as the primary path
|
|
||||||
- expect Scriptorium to read S3 refs directly
|
|
||||||
- make Scriptorium responsible for Narratio stage state
|
|
||||||
- make Scriptorium responsible for notification
|
|
||||||
- require Scriptorium to understand D&D workflow semantics beyond prompt definitions
|
|
||||||
|
|
||||||
## 22. Future Extension Notes
|
|
||||||
|
|
||||||
Possible later extensions:
|
|
||||||
|
|
||||||
- HTTP API integration
|
|
||||||
- S3 artifact references if Scriptorium adds S3 reader support
|
|
||||||
- storing render diagnostics alongside generated artifacts
|
|
||||||
- token budgeting/prompt-size checks
|
|
||||||
- batch execution if Scriptorium later adds batch support
|
|
||||||
|
|||||||
110
docs/integrations/openai-compatible-chat.md
Normal file
110
docs/integrations/openai-compatible-chat.md
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
# OpenAI-Compatible Chat Integration
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This document defines the outbound LLM contract implemented by `internal/llm/openai_compatible_client.go`.
|
||||||
|
|
||||||
|
It documents only fields and behaviors currently serialized by code.
|
||||||
|
|
||||||
|
## Endpoint Construction
|
||||||
|
|
||||||
|
Request endpoint is built as:
|
||||||
|
|
||||||
|
1. choose base URL:
|
||||||
|
- `GenerateRequest.Target.Endpoint` if set
|
||||||
|
- otherwise client config `BaseURL`
|
||||||
|
2. trim trailing slash
|
||||||
|
3. append `/chat/completions`
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
- base URL: `http://localhost:8000/v1`
|
||||||
|
- final URL: `http://localhost:8000/v1/chat/completions`
|
||||||
|
|
||||||
|
## Request Fields Sent
|
||||||
|
|
||||||
|
Serialized JSON fields:
|
||||||
|
|
||||||
|
- `model` (required after fallback resolution)
|
||||||
|
- `messages` (role/content pairs from rendered prompt)
|
||||||
|
- `temperature` (only when non-zero)
|
||||||
|
- `max_tokens` (only when non-zero)
|
||||||
|
- `top_p` (only when non-zero)
|
||||||
|
- `response_format` (only when structured output is provided)
|
||||||
|
|
||||||
|
Structured output is currently `json_schema` only, serialized as:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"response_format": {
|
||||||
|
"type": "json_schema",
|
||||||
|
"json_schema": {
|
||||||
|
"name": "...",
|
||||||
|
"strict": true,
|
||||||
|
"schema": {"type": "object"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Authentication Header
|
||||||
|
|
||||||
|
If `Target.APIKeyEnv` is set:
|
||||||
|
|
||||||
|
- resolve environment variable value at request time
|
||||||
|
- set `Authorization: Bearer <value>`
|
||||||
|
|
||||||
|
If the environment variable is unset/empty:
|
||||||
|
|
||||||
|
- request fails before HTTP call (`ErrInvalidRequest`)
|
||||||
|
|
||||||
|
If `Target.APIKeyEnv` is empty:
|
||||||
|
|
||||||
|
- no `Authorization` header is sent
|
||||||
|
|
||||||
|
## Timeout Behavior
|
||||||
|
|
||||||
|
Base timeout comes from client configuration.
|
||||||
|
|
||||||
|
Per-request override:
|
||||||
|
|
||||||
|
- if `Target.TimeoutSeconds > 0`, use that value for request timeout
|
||||||
|
- if `Target.TimeoutSeconds < 0`, request is rejected (`ErrInvalidRequest`)
|
||||||
|
|
||||||
|
## Response Expectations
|
||||||
|
|
||||||
|
Expected successful response shape (subset used):
|
||||||
|
|
||||||
|
- `choices[0].message.content`
|
||||||
|
- `usage.prompt_tokens`
|
||||||
|
- `usage.completion_tokens`
|
||||||
|
- `usage.total_tokens`
|
||||||
|
|
||||||
|
Malformed response conditions include:
|
||||||
|
|
||||||
|
- invalid JSON
|
||||||
|
- empty `choices`
|
||||||
|
- empty `choices[0].message.content`
|
||||||
|
|
||||||
|
Malformed responses return `ErrMalformedResponse`.
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
- network/request-construction failures: `ErrRequestFailed`
|
||||||
|
- non-2xx HTTP status: `ErrUnexpectedStatus` (includes status code and trimmed response body snippet)
|
||||||
|
- malformed response shape/content: `ErrMalformedResponse`
|
||||||
|
|
||||||
|
## Unsupported Or Non-Serialized Fields
|
||||||
|
|
||||||
|
The following fields may exist in profile/effective settings but are not currently serialized into outbound chat-completions payloads:
|
||||||
|
|
||||||
|
- `reasoning_effort`
|
||||||
|
- `extra_params`
|
||||||
|
|
||||||
|
No built-in retries, tool-calls, or multi-request payload modes are implemented in this client.
|
||||||
|
|
||||||
|
## Relationship To Runner
|
||||||
|
|
||||||
|
When prompt validation mode is `json_schema`, runner prepares a structured-output schema spec and passes it to the client as `StructuredOutput`.
|
||||||
|
|
||||||
|
The client only serializes the provider request payload; it does not load schema files itself.
|
||||||
Reference in New Issue
Block a user