Adopt the Promptkit v0.9 compatibility baseline

This commit is contained in:
2026-08-29 14:08:35 +00:00
parent c35ac5a0cb
commit 1806df9888
19 changed files with 136 additions and 43 deletions

View File

@@ -6,7 +6,7 @@ OpenAI-compatible model endpoints, and returns generated output with validation
metadata. metadata.
The application uses The application uses
[Promptkit v0.1.0](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/) [Promptkit v0.9.0](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/)
for prompt, profile, schema, preparation, generation, and validation behavior. for prompt, profile, schema, preparation, generation, and validation behavior.
Scriptorium owns executable configuration, CLI and HTTP mapping, process Scriptorium owns executable configuration, CLI and HTTP mapping, process
behavior, output presentation, and HTTP artifact-containment policy. behavior, output presentation, and HTTP artifact-containment policy.
@@ -38,8 +38,8 @@ a model. For complete invocation and output behavior, see the
- [Migration from the former Go package](docs/consumers/migrating-to-promptkit.md) - [Migration from the former Go package](docs/consumers/migrating-to-promptkit.md)
- [Subprocess integration](docs/integrations/subprocess.md) - [Subprocess integration](docs/integrations/subprocess.md)
- [Architecture policy](docs/policy/architecture.md) - [Architecture policy](docs/policy/architecture.md)
- [Promptkit framework formats](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md) - [Promptkit framework formats](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/formats.md)
- [Promptkit Go consumer guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md) - [Promptkit Go consumer guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/consumers/pkg-promptkit.md)
## Examples ## Examples

View File

@@ -67,15 +67,19 @@ The optional `model` object accepts `endpoint`, `model`, `temperature`,
`max_tokens`, `top_p`, `timeout_seconds`, `service_tier`, `max_tokens`, `top_p`, `timeout_seconds`, `service_tier`,
`reasoning_effort`, `api_key_env`, and `extra_params`. Numeric ranges and `reasoning_effort`, `api_key_env`, and `extra_params`. Numeric ranges and
framework credential semantics are defined by the framework credential semantics are defined by the
[Promptkit format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md). [Promptkit format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/formats.md).
Explicit zero values for the numeric fields are overrides; zero Explicit zero values for the numeric fields are overrides; zero
`timeout_seconds` disables the per-generation deadline only, retaining the `timeout_seconds` disables the per-generation deadline only, retaining the
request context and configured transport cap. The timeout layers are defined in request context and configured transport cap. The timeout layers are defined in
the [Promptkit outbound integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/integrations/openai-compatible-chat.md#timeout-and-cancellation). the [Promptkit outbound integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/integrations/openai-compatible-chat.md#timeout-and-cancellation).
Raw API-key values are not accepted. `api_key` and any other unknown model Raw API-key values are not accepted. `api_key` and any other unknown model
field cause `400 invalid_json`. field cause `400 invalid_json`.
`model.reasoning_effort` is an optional JSON string with three states: omission
inherits the selected profile, a non-empty string replaces its value, and an
empty string explicitly clears it. JSON `null` is treated as omission.
### Strict JSON ### Strict JSON
Request decoding rejects malformed JSON, unknown fields at every request level, Request decoding rejects malformed JSON, unknown fields at every request level,

View File

@@ -69,7 +69,7 @@ only; the caller context and configured transport cap remain active. CLI
durations are converted to whole seconds by truncation toward zero, so any durations are converted to whole seconds by truncation toward zero, so any
duration whose absolute value is below one second becomes an explicit duration whose absolute value is below one second becomes an explicit
zero-second override. The timeout layers are defined in the zero-second override. The timeout layers are defined in the
[Promptkit outbound integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/integrations/openai-compatible-chat.md#timeout-and-cancellation). [Promptkit outbound integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/integrations/openai-compatible-chat.md#timeout-and-cancellation).
There is no raw API-key flag. Use `--api-key-env`. There is no raw API-key flag. Use `--api-key-env`.

View File

@@ -3,7 +3,7 @@
This is the canonical reference for Scriptorium application settings. Prompt, This is the canonical reference for Scriptorium application settings. Prompt,
profile, schema, execution-setting, built-in profile, and framework credential profile, schema, execution-setting, built-in profile, and framework credential
semantics are defined by the semantics are defined by the
[Promptkit v0.1.0 format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md). [Promptkit v0.9.0 format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/formats.md).
For command syntax, see the [CLI reference](cli.md); for HTTP request shapes and For command syntax, see the [CLI reference](cli.md); for HTTP request shapes and
outcomes, see the [HTTP API reference](api.md). outcomes, see the [HTTP API reference](api.md).
@@ -58,7 +58,7 @@ parse those framework file formats.
contracts. contracts.
See the See the
[tagged Promptkit format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md) [tagged Promptkit format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/formats.md)
for all of those definitions. The files under for all of those definitions. The files under
[`examples/prompts`](../examples/prompts/), [`examples/prompts`](../examples/prompts/),
[`examples/profiles`](../examples/profiles/), and [`examples/profiles`](../examples/profiles/), and
@@ -73,8 +73,20 @@ their names in configuration or framework source files. Do not place raw keys
in configuration, prompts, profiles, CLI arguments, examples, or HTTP in configuration, prompts, profiles, CLI arguments, examples, or HTTP
payloads. payloads.
An optional `api_key_env` whose environment value is absent or empty can result
in an unauthenticated provider request. A profile that declares credentials
required still fails as an invalid request when no credential source is
selected, and fails with `ErrAPIKeyEnvMissing` when its selected environment
source is absent or empty. Scriptorium never reads or emits the environment
value itself.
Unset optional provider controls are omitted from compatible provider requests.
A positive Promptkit `repair_attempts` budget can add provider calls, latency,
token use, and cost; see the tagged format reference for its permitted values
and validation-mode requirements.
Promptkit's Promptkit's
[OpenAI-compatible integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/integrations/openai-compatible-chat.md) [OpenAI-compatible integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/integrations/openai-compatible-chat.md)
defines outbound authentication, provider request mapping, transport limits, defines outbound authentication, provider request mapping, transport limits,
and timeout layering. and timeout layering.
@@ -83,4 +95,4 @@ and timeout layering.
- [CLI reference](cli.md) - [CLI reference](cli.md)
- [HTTP API reference](api.md) - [HTTP API reference](api.md)
- [Operations guide](operations.md) - [Operations guide](operations.md)
- [Promptkit framework formats](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md) - [Promptkit framework formats](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/formats.md)

View File

@@ -14,7 +14,7 @@ and the HTTP service according to the boundary your application needs.
Go applications that need an in-process prompt framework should import Go applications that need an in-process prompt framework should import
Promptkit directly. The tagged Promptkit directly. The tagged
[Promptkit Go consumer guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md) [Promptkit Go consumer guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/consumers/pkg-promptkit.md)
owns that interface; Scriptorium does not provide a Go library package. owns that interface; Scriptorium does not provide a Go library package.
Consumers arriving from the former Scriptorium Go API should follow the Consumers arriving from the former Scriptorium Go API should follow the
[migration guide](migrating-to-promptkit.md). [migration guide](migrating-to-promptkit.md).
@@ -35,4 +35,4 @@ Scriptorium does not persist run state. A retry can produce different output
and can incur another provider request. CLI exits belong to the and can incur another provider request. CLI exits belong to the
[CLI reference](../cli.md), HTTP status behavior belongs to the [CLI reference](../cli.md), HTTP status behavior belongs to the
[HTTP API reference](../api.md), and framework semantics belong to [HTTP API reference](../api.md), and framework semantics belong to
[Promptkit v0.1.0](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md). [Promptkit v0.9.0](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/formats.md).

View File

@@ -4,7 +4,7 @@
Scriptorium `v0.11.1` at Scriptorium `v0.11.1` at
`gitea.maximumdirect.net/eric/scriptorium` is the final release that provides `gitea.maximumdirect.net/eric/scriptorium` is the final release that provides
the former in-process Go framework. Promptkit `v0.1.0` at the former in-process Go framework. Promptkit `v0.9.0` at
`gitea.maximumdirect.net/eric/promptkit` is the destination for that framework `gitea.maximumdirect.net/eric/promptkit` is the destination for that framework
API. Scriptorium `v0.12.0` and later provide the CLI and HTTP application only. API. Scriptorium `v0.12.0` and later provide the CLI and HTTP application only.
@@ -19,7 +19,7 @@ Start from a clean consumer checkout and review the pending diff before
committing it. Add the published Promptkit module: committing it. Add the published Promptkit module:
```sh ```sh
go get gitea.maximumdirect.net/eric/promptkit@v0.1.0 go get gitea.maximumdirect.net/eric/promptkit@v0.9.0
``` ```
For an ordinary consumer that imports the former root package under its For an ordinary consumer that imports the former root package under its
@@ -51,14 +51,14 @@ go mod tidy
go test ./... go test ./...
``` ```
Confirm that `go.mod` selects Promptkit `v0.1.0` and that no Go file imports Confirm that `go.mod` selects Promptkit `v0.9.0` and that no Go file imports
the former Scriptorium package: the former Scriptorium package:
```sh ```sh
test "$( test "$(
go list -m -f '{{.Path}}@{{.Version}}' \ go list -m -f '{{.Path}}@{{.Version}}' \
gitea.maximumdirect.net/eric/promptkit gitea.maximumdirect.net/eric/promptkit
)" = 'gitea.maximumdirect.net/eric/promptkit@v0.1.0' )" = 'gitea.maximumdirect.net/eric/promptkit@v0.9.0'
if git grep -n \ if git grep -n \
'gitea.maximumdirect.net/eric/scriptorium' \ 'gitea.maximumdirect.net/eric/scriptorium' \
-- '*.go' -- '*.go'
@@ -73,20 +73,20 @@ fi
Promptkit preserves the established engine, request, result, profile, Promptkit preserves the established engine, request, result, profile,
source-option, model-client, artifact, validation-value, and public-error source-option, model-client, artifact, validation-value, and public-error
shapes where practical. Exact declarations and current behavior belong to the shapes where practical. Exact declarations and current behavior belong to the
tagged [Promptkit consumer guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md) tagged [Promptkit consumer guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/consumers/pkg-promptkit.md)
and Go source. and Go source.
Promptkit also includes migration-relevant public contracts that were not in Promptkit also includes migration-relevant public contracts that were not in
Scriptorium `v0.11.1`: Scriptorium `v0.11.1`:
- [`WithArtifactReader`](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/engine.go#L96-L105) - [`WithArtifactReader`](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/engine.go#L182)
and the and the
[`ArtifactReader` declaration](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/types.go#L129-L135) [`ArtifactReader` declaration](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/types.go#L304)
provide the artifact-reading extension described by the tagged provide the artifact-reading extension described by the tagged
[extension-interface guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md#extension-interfaces). [extension-interface guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/consumers/pkg-promptkit.md#extension-interfaces).
- [`ErrProfileRequired` and `ErrAPIKeyEnvMissing`](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/engine.go#L28-L40) - [`ErrProfileRequired` and `ErrAPIKeyEnvMissing`](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/engine.go#L46-L61)
provide the specific identities described by the tagged provide the specific identities described by the tagged
[error guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md#errors). [error guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/consumers/pkg-promptkit.md#errors).
Use those tagged owners for exact signatures, wrapping guarantees, and Use those tagged owners for exact signatures, wrapping guarantees, and
extension behavior. extension behavior.

View File

@@ -2,7 +2,7 @@
This is the contributor entry point for Scriptorium. Scriptorium is an This is the contributor entry point for Scriptorium. Scriptorium is an
application that consumes the public application that consumes the public
[Promptkit v0.1.0 package](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md); [Promptkit v0.9.0 package](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/consumers/pkg-promptkit.md);
framework implementation work belongs in Promptkit. framework implementation work belongs in Promptkit.
## Initial Orientation ## Initial Orientation
@@ -27,12 +27,12 @@ tests.
| HTTP routes, DTOs, limits, status mapping, or artifact policy | [HTTP API contract](api.md), [adapter internals](internal/adapters.md), and [source internals](internal/sources.md) | | HTTP routes, DTOs, limits, status mapping, or artifact policy | [HTTP API contract](api.md), [adapter internals](internal/adapters.md), and [source internals](internal/sources.md) |
| Application configuration or precedence | [Configuration contract](config.md), [adapter internals](internal/adapters.md), and [source internals](internal/sources.md) | | Application configuration or precedence | [Configuration contract](config.md), [adapter internals](internal/adapters.md), and [source internals](internal/sources.md) |
| Prepared-run presentation | [CLI contract](cli.md), [adapter internals](internal/adapters.md), and `internal/format` | | Prepared-run presentation | [CLI contract](cli.md), [adapter internals](internal/adapters.md), and `internal/format` |
| Prompt, profile, schema, generation, or validation semantics | [Promptkit framework formats](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md) and the [Promptkit consumer guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md) | | Prompt, profile, schema, generation, or validation semantics | [Promptkit framework formats](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/formats.md) and the [Promptkit consumer guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/consumers/pkg-promptkit.md) |
| OpenAI-compatible outbound behavior or timeout layering | [Promptkit integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/integrations/openai-compatible-chat.md) | | OpenAI-compatible outbound behavior or timeout layering | [Promptkit integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/integrations/openai-compatible-chat.md) |
| Subprocess behavior | [Subprocess integration](integrations/subprocess.md) and [CLI contract](cli.md) | | Subprocess behavior | [Subprocess integration](integrations/subprocess.md) and [CLI contract](cli.md) |
| Runtime operation or recovery | [Operations](operations.md) | | Runtime operation or recovery | [Operations](operations.md) |
| Release packaging or publication | The [release procedure](release.md), [hosted release workflow](../.woodpecker/release.yml), and [architecture policy](policy/architecture.md) | | Release packaging or publication | The [release procedure](release.md), [hosted release workflow](../.woodpecker/release.yml), and [architecture policy](policy/architecture.md) |
| Examples or copyable assets | The owning Scriptorium contract, the relevant [Promptkit format contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md), and the related files under `examples/` | | Examples or copyable assets | The owning Scriptorium contract, the relevant [Promptkit format contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/formats.md), and the related files under `examples/` |
| Architecture decisions or future work | The [documentation policy](policy/documentation.md), relevant accepted ADRs, and relevant roadmap documents | | Architecture decisions or future work | The [documentation policy](policy/documentation.md), relevant accepted ADRs, and relevant roadmap documents |
Cross-project changes land and release in Promptkit before Scriptorium adopts Cross-project changes land and release in Promptkit before Scriptorium adopts

View File

@@ -9,7 +9,7 @@ own IO and presentation mechanics, not framework decisions.
External contracts are canonical in the [CLI reference](../cli.md) and External contracts are canonical in the [CLI reference](../cli.md) and
[HTTP API reference](../api.md). Promptkit's public engine contract is [HTTP API reference](../api.md). Promptkit's public engine contract is
described by its tagged described by its tagged
[Go consumer guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md). [Go consumer guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/consumers/pkg-promptkit.md).
## Components And Collaborators ## Components And Collaborators

View File

@@ -14,5 +14,5 @@ public behavior belongs in the linked contracts.
| `internal/format` | Formats Promptkit prepared-run values for CLI text or JSON output. | [CLI contract](../cli.md), [adapter internals](adapters.md) | | `internal/format` | Formats Promptkit prepared-run values for CLI text or JSON output. | [CLI contract](../cli.md), [adapter internals](adapters.md) |
Framework implementation packages are provided by Framework implementation packages are provided by
[Promptkit v0.1.0](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md) [Promptkit v0.9.0](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/consumers/pkg-promptkit.md)
and are not part of this repository. and are not part of this repository.

View File

@@ -5,7 +5,7 @@
This document covers Scriptorium-owned source locations and the restricted HTTP This document covers Scriptorium-owned source locations and the restricted HTTP
artifact reader. Prompt, profile, schema, and ordinary artifact semantics are artifact reader. Prompt, profile, schema, and ordinary artifact semantics are
owned by the tagged owned by the tagged
[Promptkit format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md). [Promptkit format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/formats.md).
## Application Source Locations ## Application Source Locations

View File

@@ -9,7 +9,7 @@ fields, or HTTP wire behavior.
- [CLI reference](cli.md): commands, output destinations, and exit codes. - [CLI reference](cli.md): commands, output destinations, and exit codes.
- [Configuration reference](config.md): application settings, source - [Configuration reference](config.md): application settings, source
locations, defaults, and credential mapping. locations, defaults, and credential mapping.
- [Promptkit framework formats](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md): - [Promptkit framework formats](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/formats.md):
prompt, profile, schema, execution-setting, and framework credential prompt, profile, schema, execution-setting, and framework credential
contracts. contracts.
- [HTTP API reference](api.md): route, request/response schema, status codes, - [HTTP API reference](api.md): route, request/response schema, status codes,

View File

@@ -10,7 +10,7 @@ Scriptorium is an executable application with three entry paths: CLI `run`, CLI
root Go package. root Go package.
The application consumes The application consumes
[Promptkit v0.1.0](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md) [Promptkit v0.9.0](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/consumers/pkg-promptkit.md)
through its supported root package. Promptkit owns prompt execution, through its supported root package. Promptkit owns prompt execution,
preparation, source formats, built-in profiles, model-client behavior, and preparation, source formats, built-in profiles, model-client behavior, and
validation. Scriptorium owns application configuration, executable adapters, validation. Scriptorium owns application configuration, executable adapters,
@@ -33,6 +33,7 @@ gitea.maximumdirect.net/eric/promptkit
- Retained application packages may import Promptkit's root package. - Retained application packages may import Promptkit's root package.
- They must not import Promptkit `internal` packages. - They must not import Promptkit `internal` packages.
- They must not import Promptkit catalog modules directly.
- They must not import the removed Scriptorium root facade or recreate former - They must not import the removed Scriptorium root facade or recreate former
framework package families. framework package families.
- Adapter-owned interfaces use Promptkit public values when a consumer-side - Adapter-owned interfaces use Promptkit public values when a consumer-side
@@ -54,9 +55,9 @@ invariants.
- `internal/defaults` owns Scriptorium application and HTTP defaults only. - `internal/defaults` owns Scriptorium application and HTTP defaults only.
- `internal/format` owns deterministic prepared-run text and JSON presentation. - `internal/format` owns deterministic prepared-run text and JSON presentation.
- Promptkit owns framework orchestration and contracts. Its - Promptkit owns framework orchestration and contracts. Its
[format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md) [format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/formats.md)
and and
[outbound integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/integrations/openai-compatible-chat.md) [outbound integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/integrations/openai-compatible-chat.md)
are canonical. are canonical.
## HTTP Artifact Security Boundary ## HTTP Artifact Security Boundary

View File

@@ -103,7 +103,7 @@ test "$(
)" = 'gitea.maximumdirect.net/eric/scriptorium 1.25.5' )" = 'gitea.maximumdirect.net/eric/scriptorium 1.25.5'
``` ```
Require Promptkit `v0.1.0` as both the direct module-graph edge and the selected Require Promptkit `v0.9.0` as both the direct module-graph edge and the selected
module version: module version:
```sh ```sh
@@ -117,11 +117,11 @@ direct_promptkit=$(
' '
) )
test "$direct_promptkit" = \ test "$direct_promptkit" = \
'gitea.maximumdirect.net/eric/promptkit@v0.1.0' 'gitea.maximumdirect.net/eric/promptkit@v0.9.0'
test "$( test "$(
GOWORK=off go list -m -f '{{.Path}}@{{.Version}}' \ GOWORK=off go list -m -f '{{.Path}}@{{.Version}}' \
gitea.maximumdirect.net/eric/promptkit gitea.maximumdirect.net/eric/promptkit
)" = 'gitea.maximumdirect.net/eric/promptkit@v0.1.0' )" = 'gitea.maximumdirect.net/eric/promptkit@v0.9.0'
GOWORK=off go list -m all GOWORK=off go list -m all
``` ```

View File

@@ -31,6 +31,8 @@ stage's completion conditions are unmet.
## Stage 1: Adopt The Promptkit v0.9.0 Compatibility Baseline ## Stage 1: Adopt The Promptkit v0.9.0 Compatibility Baseline
**Completion: Complete.**
Make the released dependency the build baseline before adding new application Make the released dependency the build baseline before adding new application
surface area. surface area.

4
go.mod
View File

@@ -3,11 +3,13 @@ module gitea.maximumdirect.net/eric/scriptorium
go 1.25.5 go 1.25.5
require ( require (
gitea.maximumdirect.net/eric/promptkit v0.1.0 gitea.maximumdirect.net/eric/promptkit v0.9.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
) )
require ( require (
gitea.maximumdirect.net/eric/promptkit-backend-openrouter v1.0.0 // indirect
gitea.maximumdirect.net/eric/promptkit-backend-rakestrawhome v1.0.0 // indirect
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
golang.org/x/text v0.14.0 // indirect golang.org/x/text v0.14.0 // indirect
) )

8
go.sum
View File

@@ -1,5 +1,9 @@
gitea.maximumdirect.net/eric/promptkit v0.1.0 h1:vuKeBxkiY8E54LRFbLQFjlJJCiOfMvB1++DYBCrD/ug= gitea.maximumdirect.net/eric/promptkit v0.9.0 h1:IpvDRC8L6xRxQ9hpuyKOmMc5b6MeLTKYyx+h1YAjy08=
gitea.maximumdirect.net/eric/promptkit v0.1.0/go.mod h1:R95NM6fbMDGDC0/UomgnSBP6ui2ns+8SZb8bESNvrDQ= gitea.maximumdirect.net/eric/promptkit v0.9.0/go.mod h1:oMJ/WUJImUtwJ5e+6MAGECPYAErAkOaKel0G+3T/b4E=
gitea.maximumdirect.net/eric/promptkit-backend-openrouter v1.0.0 h1:lc062euk2qseO//D762i3JaFyulDNML3eQQX7DkYTho=
gitea.maximumdirect.net/eric/promptkit-backend-openrouter v1.0.0/go.mod h1:AIa7kAu2mfrRQgcspe4L+DW51WqgnALQT60lqkEywJI=
gitea.maximumdirect.net/eric/promptkit-backend-rakestrawhome v1.0.0 h1:j9YY7wsTVjzke2kHH4YAzpU0oUpM+x+nXwl1IeS+2eg=
gitea.maximumdirect.net/eric/promptkit-backend-rakestrawhome v1.0.0/go.mod h1:4RNS+LILDg4JbS4Ts9Lwy1C92wauXJIbeQaalps4Koo=
github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ= github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=

View File

@@ -14,8 +14,10 @@ import (
) )
const ( const (
scriptoriumModulePath = "gitea.maximumdirect.net/eric/scriptorium" scriptoriumModulePath = "gitea.maximumdirect.net/eric/scriptorium"
promptkitInternalPath = "gitea.maximumdirect.net/eric/promptkit/internal" promptkitInternalPath = "gitea.maximumdirect.net/eric/promptkit/internal"
promptkitOpenRouterCatalogPath = "gitea.maximumdirect.net/eric/promptkit-backend-openrouter"
promptkitRakestrawhomeCatalogPath = "gitea.maximumdirect.net/eric/promptkit-backend-rakestrawhome"
) )
var ( var (
@@ -120,6 +122,24 @@ func TestForbiddenImportScannerDetectsPromptkitInternalPackages(t *testing.T) {
} }
} }
func TestForbiddenImportScannerDetectsPromptkitCatalogPackages(t *testing.T) {
for _, importPath := range []string{
promptkitOpenRouterCatalogPath,
promptkitRakestrawhomeCatalogPath,
} {
t.Run(importPath, func(t *testing.T) {
root := t.TempDir()
sourcePath := writeGoSource(t, root, "nested/consumer/catalog.go", importPath)
violations, err := findForbiddenProductionImports(root)
if err != nil {
t.Fatalf("scan source fixture: %v", err)
}
assertSingleViolation(t, violations, sourcePath, importPath)
})
}
}
func TestForbiddenImportScannerAllowsRetainedApplicationPackages(t *testing.T) { func TestForbiddenImportScannerAllowsRetainedApplicationPackages(t *testing.T) {
root := t.TempDir() root := t.TempDir()
sourcePath := filepath.Join(root, "nested/consumer/application.go") sourcePath := filepath.Join(root, "nested/consumer/application.go")
@@ -201,6 +221,12 @@ func isForbiddenProductionImport(importPath string) bool {
if importPath == promptkitInternalPath || strings.HasPrefix(importPath, promptkitInternalPath+"/") { if importPath == promptkitInternalPath || strings.HasPrefix(importPath, promptkitInternalPath+"/") {
return true return true
} }
if importPath == promptkitOpenRouterCatalogPath || strings.HasPrefix(importPath, promptkitOpenRouterCatalogPath+"/") {
return true
}
if importPath == promptkitRakestrawhomeCatalogPath || strings.HasPrefix(importPath, promptkitRakestrawhomeCatalogPath+"/") {
return true
}
for _, root := range removedFrameworkPackageRoots { for _, root := range removedFrameworkPackageRoots {
if importPath == root || strings.HasPrefix(importPath, root+"/") { if importPath == root || strings.HasPrefix(importPath, root+"/") {
return true return true

View File

@@ -28,7 +28,7 @@ type modelOverrideRequestDTO struct {
TopP *float64 `json:"top_p,omitempty"` TopP *float64 `json:"top_p,omitempty"`
TimeoutSeconds *int `json:"timeout_seconds,omitempty"` TimeoutSeconds *int `json:"timeout_seconds,omitempty"`
ServiceTier string `json:"service_tier,omitempty"` ServiceTier string `json:"service_tier,omitempty"`
ReasoningEffort string `json:"reasoning_effort,omitempty"` ReasoningEffort *string `json:"reasoning_effort,omitempty"`
APIKeyEnv string `json:"api_key_env,omitempty"` APIKeyEnv string `json:"api_key_env,omitempty"`
ExtraParams map[string]any `json:"extra_params,omitempty"` ExtraParams map[string]any `json:"extra_params,omitempty"`
} }

View File

@@ -365,10 +365,12 @@ func TestHandlerModelOverrideMapsAllSupportedExecutionFields(t *testing.T) {
if got.Endpoint != "http://override/v1" || if got.Endpoint != "http://override/v1" ||
got.Model != "override-model" || got.Model != "override-model" ||
got.ServiceTier != "flex" || got.ServiceTier != "flex" ||
got.ReasoningEffort != "medium" ||
got.APIKeyEnv != "SCRIPTORIUM_API_KEY" { got.APIKeyEnv != "SCRIPTORIUM_API_KEY" {
t.Fatalf("unexpected mapped execution target: %+v", got) t.Fatalf("unexpected mapped execution target: %+v", got)
} }
if got.ReasoningEffort == nil || *got.ReasoningEffort != "medium" {
t.Fatalf("unexpected mapped reasoning_effort: %#v", got.ReasoningEffort)
}
if got.Temperature == nil || *got.Temperature != 0.6 { if got.Temperature == nil || *got.Temperature != 0.6 {
t.Fatalf("unexpected mapped temperature: %#v", got.Temperature) t.Fatalf("unexpected mapped temperature: %#v", got.Temperature)
} }
@@ -386,6 +388,46 @@ func TestHandlerModelOverrideMapsAllSupportedExecutionFields(t *testing.T) {
} }
} }
func TestHandlerModelOverridePreservesReasoningEffortPresence(t *testing.T) {
tests := []struct {
name string
model string
wantPresent bool
wantValue string
}{
{name: "omitted", model: `{}`},
{name: "explicit empty", model: `{"reasoning_effort":""}`, wantPresent: true},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
r := &fakeRunner{result: &promptkit.RunResult{
Artifact: promptkit.Artifact{Body: []byte("ok")},
Validation: promptkit.ValidationResult{Status: promptkit.ValidationPassed, Mode: promptkit.ValidationBasic, IsValid: true},
EffectiveModelParams: promptkit.ExecutionTarget{Endpoint: "http://llm/v1", Model: "m1"},
}}
h := NewHandler(r)
req := httptest.NewRequest(http.MethodPost, "/v1/runs", bytes.NewBufferString(`{"prompt_id":"prompt-1","inputs":{"transcript":{"type":"file","uri":"./t.md"}},"model":`+tc.model+`}`))
w := httptest.NewRecorder()
h.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected 200, got %d body=%s", w.Code, w.Body.String())
}
if r.last.Execution == nil {
t.Fatal("expected execution override")
}
if (r.last.Execution.ReasoningEffort != nil) != tc.wantPresent {
t.Fatalf("unexpected reasoning_effort presence: %#v", r.last.Execution.ReasoningEffort)
}
if tc.wantPresent && *r.last.Execution.ReasoningEffort != tc.wantValue {
t.Fatalf("unexpected reasoning_effort: got %q want %q", *r.last.Execution.ReasoningEffort, tc.wantValue)
}
})
}
}
func TestHandlerModelOverrideAcceptsJSONCompatibleExtraParams(t *testing.T) { func TestHandlerModelOverrideAcceptsJSONCompatibleExtraParams(t *testing.T) {
r := &fakeRunner{result: &promptkit.RunResult{ r := &fakeRunner{result: &promptkit.RunResult{
Artifact: promptkit.Artifact{Body: []byte("ok")}, Artifact: promptkit.Artifact{Body: []byte("ok")},