diff --git a/docs/.editorconfig b/docs/.editorconfig new file mode 100644 index 0000000..83f8362 --- /dev/null +++ b/docs/.editorconfig @@ -0,0 +1,8 @@ +root = true + +[*] +indent_style = space +indent_size = 4 +tab_width = 4 +end_of_line = lf +insert_final_newline = true \ No newline at end of file diff --git a/docs/.mintignore b/docs/.mintignore new file mode 100644 index 0000000..9922f06 --- /dev/null +++ b/docs/.mintignore @@ -0,0 +1,7 @@ +# Mintlify automatically ignores these files and directories: +# .git, .github, .claude, .agents, .idea, node_modules, +# README.md, LICENSE.md, CHANGELOG.md, CONTRIBUTING.md + +# Draft content +drafts/ +*.draft.mdx diff --git a/docs/AGENTS.md b/docs/AGENTS.md new file mode 100644 index 0000000..cebd973 --- /dev/null +++ b/docs/AGENTS.md @@ -0,0 +1,33 @@ +> **First-time setup**: Customize this file for your project. Prompt the user to customize this file for their project. +> For Mintlify product knowledge (components, configuration, writing standards), +> install the Mintlify skill: `npx skills add https://mintlify.com/docs` + +# Documentation project instructions + +## About this project + +- This is a documentation site built on [Mintlify](https://mintlify.com) +- Pages are MDX files with YAML frontmatter +- Configuration lives in `docs.json` +- Run `mint dev` to preview locally +- Run `mint broken-links` to check links + +## Terminology + +{/* Add product-specific terms and preferred usage */} +{/* Example: Use "workspace" not "project", "member" not "user" */} + +## Style preferences + +{/* Add any project-specific style rules below */} + +- Use active voice and second person ("you") +- Keep sentences concise — one idea per sentence +- Use sentence case for headings +- Bold for UI elements: Click **Settings** +- Code formatting for file names, commands, paths, and code references + +## Content boundaries + +{/* Define what should and shouldn't be documented */} +{/* Example: Don't document internal admin features */} diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 0000000..e0be1d4 --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,32 @@ +# Contribute to the documentation + +Thank you for your interest in contributing to Prompt Deck's documentation! This guide will help you get started. + +## How to contribute + +### Option 1: Edit directly on GitHub + +1. Navigate to the page you want to edit +2. Click the "Edit this file" button (the pencil icon) +3. Make your changes and submit a pull request + +### Option 2: Local development + +1. Fork and clone this repository +2. Install the Mintlify CLI: `npm i -g mint` +3. Create a branch for your changes +4. Make changes +5. Navigate to the docs directory and run `mint dev` +6. Preview your changes at `http://localhost:3000` +7. Commit your changes and submit a pull request + +For more details on local development, see our [development guide](development.mdx). + +## Writing guidelines + +- **Use active voice**: "Run the command" not "The command should be run" +- **Address the reader directly**: Use "you" instead of "the user" +- **Keep sentences concise**: Aim for one idea per sentence +- **Lead with the goal**: Start instructions with what the user wants to accomplish +- **Use consistent terminology**: Don't alternate between synonyms for the same concept +- **Include examples**: Show, don't just tell diff --git a/docs/LICENSE b/docs/LICENSE new file mode 100644 index 0000000..5411374 --- /dev/null +++ b/docs/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Mintlify + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..8a8afc9 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,48 @@ +# Prompt Deck + +This documentation is built upon the Mintlify starter kit. + +**[Follow the full quickstart guide](https://starter.mintlify.com/quickstart)** + +## AI-assisted writing + +Set up your AI coding tool to work with Mintlify: + +```bash +npx skills add https://mintlify.com/docs +``` + +This command installs Mintlify's documentation skill for your configured AI tools like Claude Code, Cursor, Windsurf, and others. The skill includes component reference, writing standards, and workflow guidance. + +See the [AI tools guides](/ai-tools) for tool-specific setup. + +## Development + +Install the [Mintlify CLI](https://www.npmjs.com/package/mint) to preview your documentation changes locally. To install, use the following command: + +``` +npm i -g mint +``` + +Run the following command at the root of your documentation, where your `docs.json` is located: + +``` +mint dev +``` + +View your local preview at `http://localhost:3000`. + +## Publishing changes + +Install our GitHub app from your [dashboard](https://dashboard.mintlify.com/settings/organization/github-app) to propagate changes from your repo to your deployment. Changes are deployed to production automatically after pushing to the default branch. + +## Need help? + +### Troubleshooting + +- If your dev environment isn't running: Run `mint update` to ensure you have the most recent version of the CLI. +- If a page loads as a 404: Make sure you are running in a folder with a valid `docs.json`. + +### Resources + +- [Mintlify documentation](https://mintlify.com/docs) diff --git a/docs/api-reference.md b/docs/advanced/api-reference.mdx similarity index 89% rename from docs/api-reference.md rename to docs/advanced/api-reference.mdx index 4074ca2..87560fe 100644 --- a/docs/api-reference.md +++ b/docs/advanced/api-reference.mdx @@ -1,24 +1,7 @@ -# API Reference - -- [PromptManager](#prompt-manager) -- [PromptTemplate](#prompt-template) -- [PromptDeck Facade](#promptdeck-facade) -- [HasPromptTemplate Trait](#hasprompttemplate-trait) -- [TrackPromptMiddleware](#trackpromptmiddleware) -- [AfterMakeAgent Listener](#aftermakeagent-listener) -- [Models](#models) - - [PromptVersion](#prompt-version) - - [PromptExecution](#prompt-execution) -- [Exceptions](#exceptions) - - [PromptDeckException](#promptdeckexception) - - [PromptNotFoundException](#promptnotfoundexception) - - [InvalidVersionException](#invalidversionexception) - - [ConfigurationException](#configurationexception) - - [PromptRenderingException](#promptrenderingexception) - --- - - +title: "API reference" +description: "Complete class and method reference for Prompt Deck." +--- ## PromptManager @@ -48,7 +31,7 @@ public function __construct( #### `get(string $name, ?int $version = null): PromptTemplate` -Load a prompt by name and optional version. If version is `null`, the [active version](prompts.md#version-resolution) is resolved automatically. Returns a `PromptTemplate` instance. +Load a prompt by name and optional version. If version is `null`, the [active version](/core/prompts#version-resolution-order) is resolved automatically. Returns a `PromptTemplate` instance. Caches the loaded prompt if caching is enabled. @@ -111,8 +94,6 @@ $manager->track('order-summary', 2, [ --- - - ## PromptTemplate `Veeqtoh\PromptDeck\PromptTemplate` @@ -231,15 +212,13 @@ $prompt->custom_role(); // renders 'custom_role' role --- - - -## PromptDeck Facade +## PromptDeck facade `Veeqtoh\PromptDeck\Facades\PromptDeck` Static proxy to the `PromptManager` singleton. -### Available Methods +### Available methods | Method | Returns | Description | | ------------------------------------------------------------ | ---------------- | ------------------------------------------- | @@ -251,9 +230,7 @@ Static proxy to the `PromptManager` singleton. --- - - -## HasPromptTemplate Trait +## HasPromptTemplate trait `Veeqtoh\PromptDeck\Concerns\HasPromptTemplate` @@ -269,10 +246,6 @@ Get the prompt name. Defaults to the kebab-cased class name (e.g. `SalesCoach` Get the prompt version to load. Returns `null` by default (active version). Override to pin to a specific version. -#### `promptVersion(): ?int` - -Get the prompt version to load. Returns `null` by default (active version). Override to pin to a specific version. - #### `promptVariables(): array` Get variables for prompt template interpolation. Returns an empty array by default. Override to provide dynamic context. @@ -299,8 +272,6 @@ Clear the cached `PromptTemplate`, forcing a fresh load on next access. Returns --- - - ## TrackPromptMiddleware `Veeqtoh\PromptDeck\Ai\TrackPromptMiddleware` @@ -317,9 +288,7 @@ Only tracks agents that use the `HasPromptTemplate` trait (i.e. agents with a `p --- - - -## AfterMakeAgent Listener +## AfterMakeAgent listener `Veeqtoh\PromptDeck\Listeners\AfterMakeAgent` @@ -333,12 +302,8 @@ Handle the `CommandFinished` event. Only acts on successful `make:agent` command --- - - ## Models - - ### PromptVersion `Veeqtoh\PromptDeck\Models\PromptVersion` @@ -352,8 +317,6 @@ Handle the `CommandFinished` event. Only acts on successful `make:agent` command | `metadata` | `array\|null` | `array` | Version metadata. | | `is_active` | `bool` | `boolean` | Whether this is the active version. | - - ### PromptExecution `Veeqtoh\PromptDeck\Models\PromptExecution` @@ -373,22 +336,16 @@ Handle the `CommandFinished` event. Only acts on successful `make:agent` command --- - - ## Exceptions All Prompt Deck exceptions extend the base `PromptDeckException` class. - - ### PromptDeckException `Veeqtoh\PromptDeck\Exceptions\PromptDeckException` Abstract base exception for all Prompt Deck errors. Extends PHP's `Exception` class. - - ### PromptNotFoundException `Veeqtoh\PromptDeck\Exceptions\PromptNotFoundException` @@ -399,8 +356,6 @@ Thrown when a prompt directory does not exist. | --------------------------- | -------------------------------------------------------------- | | `named(string $name): self` | Creates exception with message: `"Prompt [{name}] not found."` | - - ### InvalidVersionException `Veeqtoh\PromptDeck\Exceptions\InvalidVersionException` @@ -412,8 +367,6 @@ Thrown when a requested version does not exist or no versions are found. | `forPrompt(string $name, int $version): self` | Creates exception with message: `"Version {version} for prompt [{name}] does not exist."` | | `noVersions(string $name): self` | Creates exception with message: `"No versions found for prompt [{name}]."` | - - ### ConfigurationException `Veeqtoh\PromptDeck\Exceptions\ConfigurationException` @@ -424,8 +377,6 @@ Thrown when Prompt Deck configuration is invalid. | --------------------------------- | ------------------------------------------------------------------------------------------------ | | `invalidPath(string $path): self` | Creates exception with message: `"Prompts path [{path}] is not a directory or is not writable."` | - - ### PromptRenderingException `Veeqtoh\PromptDeck\Exceptions\PromptRenderingException` diff --git a/docs/testing.md b/docs/advanced/testing.mdx similarity index 80% rename from docs/testing.md rename to docs/advanced/testing.mdx index e0b9cc0..4c56e3d 100644 --- a/docs/testing.md +++ b/docs/advanced/testing.mdx @@ -1,34 +1,15 @@ -# Testing - -- [Introduction](#introduction) -- [Setting Up Tests](#setting-up-tests) - - [Test Base Class](#test-base-class) - - [Disabling Cache and Tracking](#disabling-cache-and-tracking) -- [Testing Prompts](#testing-prompts) - - [Creating Test Prompt Files](#creating-test-prompt-files) - - [Testing Prompt Loading](#testing-prompt-loading) - - [Testing Variable Interpolation](#testing-variable-interpolation) - - [Testing Roles](#testing-roles) - - [Testing Messages Output](#testing-messages-output) -- [Testing with the Facade](#testing-with-the-facade) -- [Testing Version Management](#testing-version-management) -- [Testing Execution Tracking](#testing-execution-tracking) - - [Using Factories](#using-factories) -- [Testing Artisan Commands](#testing-artisan-commands) -- [Testing AI SDK Integration](#testing-ai-sdk-integration) - - [Testing HasPromptTemplate](#testing-hasprompttemplate) - - [Clearing Cached Templates](#clearing-cached-templates) - - +--- +title: "Testing" +description: "Testing strategies and examples for prompts, commands, tracking, and AI SDK integration." +--- + ## Introduction Prompt Deck is designed to be easily testable. This guide covers strategies for testing prompts, commands, tracking, and AI SDK integration in your Laravel application. - -## Setting Up Tests +## Setting up tests - -### Test Base Class +### Test base class If you're using Orchestra Testbench (recommended for package testing), register the service provider in your test case: @@ -58,8 +39,7 @@ abstract class TestCase extends BaseTestCase } ``` - -### Disabling Cache and Tracking +### Disabling cache and tracking For most tests, disable caching and tracking to avoid side effects: @@ -77,11 +57,9 @@ protected function getFixturePath(string $path = ''): string } ``` - -## Testing Prompts +## Testing prompts - -### Creating Test Prompt Files +### Creating test prompt files Create fixture prompt files in your test directory: @@ -98,17 +76,18 @@ tests/ ``` `tests/fixtures/prompts/order-summary/v1/system.md`: + ```markdown You are a {{ $tone }} AI assistant specialized in order summaries. ``` `tests/fixtures/prompts/order-summary/v1/user.md`: + ```markdown Summarise this order: {{ $input }} ``` - -### Testing Prompt Loading +### Testing prompt loading ```php use Veeqtoh\PromptDeck\Facades\PromptDeck; @@ -129,8 +108,7 @@ it('throws when version does not exist', function () { })->throws(\Veeqtoh\PromptDeck\Exceptions\InvalidVersionException::class); ``` - -### Testing Variable Interpolation +### Testing variable interpolation ```php it('interpolates variables in prompt content', function () { @@ -151,8 +129,7 @@ it('leaves unmatched placeholders intact', function () { }); ``` - -### Testing Roles +### Testing roles ```php it('lists available roles', function () { @@ -183,8 +160,7 @@ it('gets raw content without interpolation', function () { }); ``` - -### Testing Messages Output +### Testing messages output ```php it('builds messages array for AI APIs', function () { @@ -207,8 +183,7 @@ it('filters messages to specific roles', function () { }); ``` - -## Testing with the Facade +## Testing with the facade You can mock the facade in tests where you don't want filesystem access: @@ -232,8 +207,7 @@ it('uses a mocked prompt', function () { }); ``` - -## Testing Version Management +## Testing version management ```php it('lists all versions for a prompt', function () { @@ -251,8 +225,7 @@ it('activates a specific version', function () { }); ``` - -## Testing Execution Tracking +## Testing execution tracking When testing tracking, enable it and run the migrations in your test setup: @@ -293,8 +266,7 @@ it('does not track when disabled', function () { }); ``` - -### Using Factories +### Using factories Use the included factories to seed test data: @@ -326,8 +298,7 @@ it('finds the active version', function () { }); ``` - -## Testing Artisan Commands +## Testing Artisan commands ```php use Illuminate\Support\Facades\File; @@ -369,9 +340,6 @@ it('tests a prompt via prompt:test', function () { it('shows diff between versions', function () { $this->artisan('make:prompt', ['name' => 'diff-test']); - // Create v2 by answering the interactive prompt - // Or set up fixtures with two versions - $this->artisan('prompt:diff', [ 'name' => 'diff-test', '--v1' => 1, @@ -380,10 +348,8 @@ it('shows diff between versions', function () { }); ``` - -## Testing AI SDK Integration +## Testing AI SDK integration - ### Testing HasPromptTemplate Create a test agent class that uses the trait: @@ -417,8 +383,7 @@ it('returns empty array for default variables', function () { }); ``` - -### Clearing Cached Templates +### Clearing cached templates When testing with different prompt versions: @@ -438,5 +403,7 @@ it('clears cached template between tests', function () { }); ``` -> **Tip** -> Always call `forgetPromptTemplate()` in tests where you modify prompt files or change the active version between assertions. + + Always call `forgetPromptTemplate()` in tests where you modify prompt files + or change the active version between assertions. + diff --git a/docs/tracking.md b/docs/advanced/tracking.mdx similarity index 59% rename from docs/tracking.md rename to docs/advanced/tracking.mdx index 332e789..9b3d3ae 100644 --- a/docs/tracking.md +++ b/docs/advanced/tracking.mdx @@ -1,31 +1,9 @@ -# Tracking & Performance - -- [Introduction](#introduction) -- [Setup](#setup) - - [Enable Tracking](#enable-tracking) - - [Publish Migrations](#publish-migrations) - - [Database Connection](#database-connection) -- [Database Schema](#database-schema) - - [prompt_versions Table](#prompt-versions-table) - - [prompt_executions Table](#prompt-executions-table) -- [Recording Executions](#recording-executions) - - [Manual Tracking](#manual-tracking) - - [Automatic Tracking via Middleware](#automatic-tracking) - - [Tracked Fields](#tracked-fields) -- [Eloquent Models](#eloquent-models) - - [PromptVersion](#prompt-version-model) - - [PromptExecution](#prompt-execution-model) -- [Factories](#factories) - - [PromptVersionFactory](#prompt-version-factory) - - [PromptExecutionFactory](#prompt-execution-factory) -- [Querying Execution Data](#querying-execution-data) - - [Basic Queries](#basic-queries) - - [Performance Analysis](#performance-analysis) - - [A/B Testing](#ab-testing) - - [Cost Analysis](#cost-analysis) -- [Version Management via Database](#version-management-via-database) - - +--- +title: "Tracking & performance" +description: "Execution logging, database schema, Eloquent models, and analytics for prompt performance monitoring." +sidebarTitle: "Tracking" +--- + ## Introduction Prompt Deck includes an optional database tracking system that logs prompt versions and execution data. This enables: @@ -38,11 +16,9 @@ Prompt Deck includes an optional database tracking system that logs prompt versi Tracking is entirely optional. Prompt Deck works fully without it. - ## Setup - -### Enable Tracking +### Enable tracking Set the tracking configuration in `config/prompt-deck.php`: @@ -61,8 +37,7 @@ PROMPTDECK_TRACKING_ENABLED=true By default, tracking is **disabled** when `APP_DEBUG=true` and **enabled** in production. - -### Publish Migrations +### Publish migrations Publish and run the migrations to create the required tables: @@ -71,8 +46,7 @@ php artisan vendor:publish --tag=prompt-deck-migrations php artisan migrate ``` - -### Database Connection +### Database connection By default, tracking uses your application's default database connection. To store tracking data on a separate database: @@ -82,61 +56,60 @@ PROMPTDECK_DB_CONNECTION=analytics The connection name must match a connection defined in `config/database.php`. - -## Database Schema +## Database schema - -### prompt_versions Table +### prompt_versions table Stores prompt version records and tracks which version is active. -| Column | Type | Nullable | Description | -|---|---|---|---| -| `id` | `bigint` | No | Auto-incrementing primary key. | -| `name` | `string` | No | The prompt name (e.g. `order-summary`). | -| `version` | `unsigned int` | No | The version number (e.g. `1`, `2`, `3`). | -| `system_prompt` | `text` | Yes | The system prompt content. | -| `user_prompt` | `text` | No | The user prompt content. | -| `metadata` | `json` | Yes | Version metadata as JSON. | -| `is_active` | `boolean` | No | Whether this version is the active version. Default: `false`. | -| `created_at` | `timestamp` | Yes | Creation timestamp. | -| `updated_at` | `timestamp` | Yes | Last update timestamp. | +| Column | Type | Nullable | Description | +| --------------- | -------------- | -------- | ------------------------------------------------------------- | +| `id` | `bigint` | No | Auto-incrementing primary key. | +| `name` | `string` | No | The prompt name (e.g. `order-summary`). | +| `version` | `unsigned int` | No | The version number (e.g. `1`, `2`, `3`). | +| `system_prompt` | `text` | Yes | The system prompt content. | +| `user_prompt` | `text` | No | The user prompt content. | +| `metadata` | `json` | Yes | Version metadata as JSON. | +| `is_active` | `boolean` | No | Whether this version is the active version. Default: `false`. | +| `created_at` | `timestamp` | Yes | Creation timestamp. | +| `updated_at` | `timestamp` | Yes | Last update timestamp. | **Indexes:** + - Unique index on `(name, version)` — ensures no duplicate versions per prompt. - Index on `(name, is_active)` — fast lookups for the active version. - -### prompt_executions Table +### prompt_executions table Logs individual prompt executions with performance data. -| Column | Type | Nullable | Description | -|---|---|---|---| -| `id` | `bigint` | No | Auto-incrementing primary key. | -| `prompt_name` | `string` | No | The prompt name. | -| `prompt_version` | `unsigned int` | No | The prompt version used. | -| `input` | `json` | Yes | The input sent to the AI provider. | -| `output` | `text` | Yes | The response received from the AI provider. | -| `tokens` | `unsigned int` | Yes | Total token usage (input + output). | -| `latency_ms` | `unsigned int` | Yes | Round-trip time in milliseconds. | -| `cost` | `decimal(8,6)` | Yes | Estimated cost in your currency. | -| `model` | `string` | Yes | The AI model used (e.g. `gpt-4o`). | -| `provider` | `string` | Yes | The AI provider (e.g. `openai`, `anthropic`). | -| `feedback` | `json` | Yes | User feedback (ratings, comments, etc.). | -| `created_at` | `timestamp` | Yes | Execution timestamp. | +| Column | Type | Nullable | Description | +| ---------------- | -------------- | -------- | --------------------------------------------- | +| `id` | `bigint` | No | Auto-incrementing primary key. | +| `prompt_name` | `string` | No | The prompt name. | +| `prompt_version` | `unsigned int` | No | The prompt version used. | +| `input` | `json` | Yes | The input sent to the AI provider. | +| `output` | `text` | Yes | The response received from the AI provider. | +| `tokens` | `unsigned int` | Yes | Total token usage (input + output). | +| `latency_ms` | `unsigned int` | Yes | Round-trip time in milliseconds. | +| `cost` | `decimal(8,6)` | Yes | Estimated cost in your currency. | +| `model` | `string` | Yes | The AI model used (e.g. `gpt-4o`). | +| `provider` | `string` | Yes | The AI provider (e.g. `openai`, `anthropic`). | +| `feedback` | `json` | Yes | User feedback (ratings, comments, etc.). | +| `created_at` | `timestamp` | Yes | Execution timestamp. | **Indexes:** + - Index on `(prompt_name, prompt_version, created_at)` — fast filtering by prompt and time range. -> **Note** -> The `prompt_executions` table does not have an `updated_at` column. Records are insert-only. + + The `prompt_executions` table does not have an `updated_at` column. Records + are insert-only. + - -## Recording Executions +## Recording executions - -### Manual Tracking +### Manual tracking Use the `PromptDeck::track()` method to record an execution manually: @@ -170,31 +143,27 @@ PromptDeck::track('order-summary', 2, [ If tracking is disabled in configuration, the `track()` method is a safe no-op — you can call it without checking configuration first. - -### Automatic Tracking via Middleware +### Automatic tracking via middleware -When using the [Laravel AI SDK integration](ai-sdk.md), the `TrackPromptMiddleware` handles tracking automatically. See [AI SDK — Performance Tracking Middleware](ai-sdk.md#performance-tracking-middleware) for setup details. +When using the [Laravel AI SDK integration](/integrations/ai-sdk), the `TrackPromptMiddleware` handles tracking automatically. See [AI SDK — Performance Tracking Middleware](/integrations/ai-sdk#performance-tracking-middleware) for setup details. - -### Tracked Fields +### Tracked fields -| Field | Type | Description | -|---|---|---| -| `input` | `array\|null` | The input data sent to the AI provider. Stored as JSON. | -| `output` | `string\|null` | The text response from the AI provider. | -| `tokens` | `int\|null` | Total token count (input + output tokens). | -| `latency` | `float\|null` | Round-trip time in milliseconds. Stored as `latency_ms`. | -| `cost` | `float\|null` | Estimated cost. Stored with up to 6 decimal places. | -| `model` | `string\|null` | AI model identifier (e.g. `gpt-4o`, `claude-3-sonnet`). | -| `provider` | `string\|null` | AI provider name (e.g. `openai`, `anthropic`). | -| `feedback` | `array\|null` | Arbitrary feedback data. Stored as JSON. | +| Field | Type | Description | +| ---------- | -------------- | -------------------------------------------------------- | +| `input` | `array\|null` | The input data sent to the AI provider. Stored as JSON. | +| `output` | `string\|null` | The text response from the AI provider. | +| `tokens` | `int\|null` | Total token count (input + output tokens). | +| `latency` | `float\|null` | Round-trip time in milliseconds. Stored as `latency_ms`. | +| `cost` | `float\|null` | Estimated cost. Stored with up to 6 decimal places. | +| `model` | `string\|null` | AI model identifier (e.g. `gpt-4o`, `claude-3-sonnet`). | +| `provider` | `string\|null` | AI provider name (e.g. `openai`, `anthropic`). | +| `feedback` | `array\|null` | Arbitrary feedback data. Stored as JSON. | - -## Eloquent Models +## Eloquent models Prompt Deck provides two Eloquent models for interacting with tracking data. - ### PromptVersion `Veeqtoh\PromptDeck\Models\PromptVersion` @@ -219,13 +188,12 @@ $versions = PromptVersion::where('name', 'order-summary') **Casts:** -| Attribute | Cast | -|---|---| -| `version` | `integer` | +| Attribute | Cast | +| ----------- | --------- | +| `version` | `integer` | | `is_active` | `boolean` | -| `metadata` | `array` | +| `metadata` | `array` | - ### PromptExecution `Veeqtoh\PromptDeck\Models\PromptExecution` @@ -251,24 +219,24 @@ $v2Executions = PromptExecution::where('prompt_name', 'order-summary') **Casts:** -| Attribute | Cast | -|---|---| -| `prompt_version` | `integer` | -| `tokens` | `integer` | -| `latency_ms` | `integer` | -| `cost` | `decimal:6` | -| `input` | `array` | -| `feedback` | `array` | +| Attribute | Cast | +| ---------------- | ----------- | +| `prompt_version` | `integer` | +| `tokens` | `integer` | +| `latency_ms` | `integer` | +| `cost` | `decimal:6` | +| `input` | `array` | +| `feedback` | `array` | -> **Note** -> `PromptExecution` sets `UPDATED_AT = null` since execution records are insert-only and never updated. + + `PromptExecution` sets `UPDATED_AT = null` since execution records are + insert-only and never updated. + - ## Factories Both models include factories for testing. - ### PromptVersionFactory ```php @@ -290,13 +258,12 @@ $version = PromptVersion::factory() **Available states:** -| Method | Description | -|---|---| -| `active()` | Mark as the active version (`is_active = true`). | -| `version(int $v)` | Set a specific version number. | -| `named(string $name)` | Set a specific prompt name. | +| Method | Description | +| --------------------- | ------------------------------------------------ | +| `active()` | Mark as the active version (`is_active = true`). | +| `version(int $v)` | Set a specific version number. | +| `named(string $name)` | Set a specific prompt name. | - ### PromptExecutionFactory ```php @@ -321,17 +288,15 @@ $execution = PromptExecution::factory() **Available states:** -| Method | Description | -|---|---| -| `withFeedback(array $feedback = [])` | Include user feedback. Generates random feedback if no argument given. | -| `minimal()` | Set all optional fields to `null`. | -| `forPrompt(string $name, int $version)` | Set a specific prompt name and version. | +| Method | Description | +| --------------------------------------- | ---------------------------------------------------------------------- | +| `withFeedback(array $feedback = [])` | Include user feedback. Generates random feedback if no argument given. | +| `minimal()` | Set all optional fields to `null`. | +| `forPrompt(string $name, int $version)` | Set a specific prompt name and version. | - -## Querying Execution Data +## Querying execution data - -### Basic Queries +### Basic queries ```php use Veeqtoh\PromptDeck\Models\PromptExecution; @@ -350,8 +315,7 @@ $recent = PromptExecution::where('prompt_name', 'order-summary') ->get(); ``` - -### Performance Analysis +### Performance analysis ```php // Average latency for a prompt version @@ -372,8 +336,7 @@ $p95 = PromptExecution::where('prompt_name', 'order-summary') ->value('latency_ms'); ``` - -### A/B Testing +### A/B testing Compare metrics across prompt versions: @@ -394,8 +357,7 @@ $ratings = PromptExecution::where('prompt_name', 'order-summary') ->get(); ``` - -### Cost Analysis +### Cost analysis ```php // Total cost for a prompt @@ -417,8 +379,7 @@ $dailyCost = PromptExecution::where('prompt_name', 'order-summary') ->get(); ``` - -## Version Management via Database +## Version management via database When tracking is enabled, version activation is managed through the `prompt_versions` table instead of `metadata.json` files. This provides a centralised, queryable record of version history. diff --git a/docs/commands.md b/docs/core/commands.mdx similarity index 63% rename from docs/commands.md rename to docs/core/commands.mdx index 93d908e..f1b26ff 100644 --- a/docs/commands.md +++ b/docs/core/commands.mdx @@ -1,26 +1,20 @@ -# Artisan Commands +--- +title: "Artisan commands" +description: "All available Artisan commands for managing prompts from the command line." +--- -- [Introduction](#introduction) -- [make:prompt](#make-prompt) -- [prompt:list](#prompt-list) -- [prompt:activate](#prompt-activate) -- [prompt:diff](#prompt-diff) -- [prompt:test](#prompt-test) - - ## Introduction Prompt Deck registers five Artisan commands for managing your prompts from the command line. All commands are available when running in the console. -| Command | Description | -|---|---| -| `make:prompt` | Create a new prompt structure with versioned role files. | -| `prompt:list` | List all available prompts and their versions. | -| `prompt:activate` | Activate a specific version of a prompt. | -| `prompt:diff` | Show differences between two prompt versions. | -| `prompt:test` | Test a prompt with sample input and see the rendered result. | +| Command | Description | +| ----------------- | ------------------------------------------------------------ | +| `make:prompt` | Create a new prompt structure with versioned role files. | +| `prompt:list` | List all available prompts and their versions. | +| `prompt:activate` | Activate a specific version of a prompt. | +| `prompt:diff` | Show differences between two prompt versions. | +| `prompt:test` | Test a prompt with sample input and see the rendered result. | - ## make:prompt Create a new prompt structure for your AI agent. @@ -31,20 +25,20 @@ make:prompt {name?} {--from=} {--desc=} {--u|user} {--role=*} {--i|interactive} ### Arguments -| Argument | Required | Description | -|----------|----------|-------------| -| `name` | No | The name of the prompt. Omit for interactive mode. Automatically normalised to kebab-case. | +| Argument | Required | Description | +| -------- | -------- | ------------------------------------------------------------------------------------------ | +| `name` | No | The name of the prompt. Omit for interactive mode. Automatically normalised to kebab-case. | ### Options -| Option | Shorthand | Description | -|---|---|---| -| `--from=` | | Path to a custom stub file to use as the user prompt template. | -| `--desc=` | | A short description stored in `metadata.json`. | -| `--user` | `-u` | Also create a `user` prompt file alongside the default `system` prompt. | -| `--role=*` | | Additional roles to scaffold. Repeatable (e.g. `--role=assistant --role=developer`). | -| `--interactive` | `-i` | Interactively choose which additional roles to create. | -| `--force` | `-f` | Overwrite an existing prompt's latest version without confirmation. | +| Option | Shorthand | Description | +| --------------- | --------- | ------------------------------------------------------------------------------------ | +| `--from=` | | Path to a custom stub file to use as the user prompt template. | +| `--desc=` | | A short description stored in `metadata.json`. | +| `--user` | `-u` | Also create a `user` prompt file alongside the default `system` prompt. | +| `--role=*` | | Additional roles to scaffold. Repeatable (e.g. `--role=assistant --role=developer`). | +| `--interactive` | `-i` | Interactively choose which additional roles to create. | +| `--force` | `-f` | Overwrite an existing prompt's latest version without confirmation. | ### Examples @@ -77,7 +71,7 @@ php artisan make:prompt order-summary --user --from=stubs/my-template.md Version 1 of the [order-summary] prompt has been created successfully with the following roles: system, user. ``` -### Behaviour with Existing Prompts +### Behaviour with existing prompts When run against a prompt that already exists, the command presents a choice: @@ -91,9 +85,8 @@ What would you like to do? With `--force`, the latest version is overwritten without prompting. -See [Creating Prompts](make-prompt.md) for comprehensive documentation. +See [Creating Prompts](/core/make-prompt) for comprehensive documentation. - ## prompt:list List all available prompts and their versions. @@ -104,8 +97,8 @@ prompt:list {--all : Show all versions for each prompt} ### Options -| Option | Description | -|---|---| +| Option | Description | +| ------- | ----------------------------------------------------------- | | `--all` | Show all versions for each prompt, not just the active one. | ### Examples @@ -151,7 +144,6 @@ Output: - If no prompts are found, an informational message is shown. - Descriptions come from each version's `metadata.json`. - ## prompt:activate Activate a specific version of a prompt. @@ -162,10 +154,10 @@ prompt:activate {name : The prompt name} {version : The version number to activa ### Arguments -| Argument | Required | Description | -|----------|----------|-------------| -| `name` | Yes | The prompt name (e.g. `order-summary`). | -| `version` | Yes | The version number to activate (e.g. `2`). | +| Argument | Required | Description | +| --------- | -------- | ------------------------------------------ | +| `name` | Yes | The prompt name (e.g. `order-summary`). | +| `version` | Yes | The version number to activate (e.g. `2`). | ### Examples @@ -179,12 +171,12 @@ Output: Version 2 of prompt [order-summary] activated. ``` -### How It Works +### How it works - **With database tracking enabled**: Updates the `prompt_versions` table — sets `is_active = false` on all versions for that prompt, then `is_active = true` on the specified version. - **Without tracking**: Writes the `active_version` key to the prompt's root `metadata.json` file. -### Error Handling +### Error handling If the prompt or version does not exist, an error message is displayed: @@ -192,7 +184,6 @@ If the prompt or version does not exist, an error message is displayed: Version 5 for prompt [order-summary] does not exist. ``` - ## prompt:diff Show differences between two prompt versions using unified diff output. @@ -203,17 +194,17 @@ prompt:diff {name : The prompt name} {--v1= : First version number} {--v2= : Sec ### Arguments -| Argument | Required | Description | -|----------|----------|-------------| -| `name` | Yes | The prompt name (e.g. `order-summary`). | +| Argument | Required | Description | +| -------- | -------- | --------------------------------------- | +| `name` | Yes | The prompt name (e.g. `order-summary`). | ### Options -| Option | Required | Description | -|---|---|---| -| `--v1=` | Yes | The first version number to compare. | -| `--v2=` | Yes | The second version number to compare. | -| `--type=` | No | Which role files to compare: `system`, `user`, or `all` (default). | +| Option | Required | Description | +| --------- | -------- | ------------------------------------------------------------------ | +| `--v1=` | Yes | The first version number to compare. | +| `--v2=` | Yes | The second version number to compare. | +| `--type=` | No | Which role files to compare: `system`, `user`, or `all` (default). | ### Examples @@ -259,7 +250,6 @@ php artisan prompt:diff order-summary --v1=1 --v2=2 --type=user - If a role file doesn't exist in either version, it is silently skipped. - Uses `sebastian/diff` for unified diff output. - ## prompt:test Test a prompt with sample input and see the rendered result. @@ -270,16 +260,16 @@ prompt:test {name : The prompt name} {--ver= : Specific version (defaults to act ### Arguments -| Argument | Required | Description | -|----------|----------|-------------| -| `name` | Yes | The prompt name to test (e.g. `order-summary`). | +| Argument | Required | Description | +| -------- | -------- | ----------------------------------------------- | +| `name` | Yes | The prompt name to test (e.g. `order-summary`). | ### Options -| Option | Description | -|---|---| -| `--ver=` | Specific version to test. Defaults to the active version. | -| `--input=` | Custom input text. Defaults to `"Sample user input"`. | +| Option | Description | +| -------------- | ------------------------------------------------------------- | +| `--ver=` | Specific version to test. Defaults to the active version. | +| `--input=` | Custom input text. Defaults to `"Sample user input"`. | | `--variables=` | JSON string of variables for interpolation. Defaults to `{}`. | ### Examples diff --git a/docs/make-prompt.md b/docs/core/make-prompt.mdx similarity index 65% rename from docs/make-prompt.md rename to docs/core/make-prompt.mdx index beb5edb..00bc559 100644 --- a/docs/make-prompt.md +++ b/docs/core/make-prompt.mdx @@ -1,41 +1,15 @@ -# Creating Prompts - -- [Introduction](#introduction) -- [Generating Prompts](#generating-prompts) - - [Basic Usage](#basic-usage) - - [Interactive Mode](#interactive-mode) -- [Command Signature](#command-signature) - - [Arguments](#arguments) - - [Options](#options) -- [Prompt Structure](#prompt-structure) - - [Directory Layout](#directory-layout) - - [Metadata](#metadata) -- [Roles](#roles) - - [System Role (Default)](#system-role-default) - - [User Role](#user-role) - - [Extra Roles](#extra-roles) -- [Versioning](#versioning) - - [Auto-Increment](#auto-increment) - - [Overwriting](#overwriting) - - [Force Mode](#force-mode) -- [Stubs](#stubs) - - [Default Stubs](#default-stubs) - - [Custom Stubs](#custom-stubs) - - [Using a One-Off Template](#using-a-one-off-template) -- [Name Normalisation](#name-normalisation) -- [Configuration](#configuration) -- [Examples](#examples) - - +--- +title: "Creating prompts" +description: "Generate versioned, role-based prompt structures with the make:prompt Artisan command." +--- + ## Introduction Prompt Deck provides an Artisan generator command that scaffolds versioned, role-based prompt structures for your AI agents. The command follows Laravel conventions and supports interactive workflows, automatic versioning, customisable stubs, and rich metadata — everything you need to manage prompts as first-class project assets. - -## Generating Prompts +## Generating prompts - -### Basic Usage +### Basic usage To create a new prompt, use the `make:prompt` Artisan command: @@ -55,8 +29,7 @@ resources/prompts/ A **system prompt** file is always created. A `metadata.json` file is placed at the prompt root to record the prompt's name, description, roles, and creation timestamp. - -### Interactive Mode +### Interactive mode Run the command without any arguments to enter a fully interactive flow: @@ -71,40 +44,38 @@ You will be guided through a series of questions: 3. **Would you also like to create a user prompt file?** — Confirm to scaffold a `user.md` alongside `system.md`. 4. **Would you like to create prompt files for additional roles?** — Confirm, then enter comma-separated role names (e.g. `assistant, developer`). -> **Note** -> The interactive description and user-prompt questions are only asked when the name argument is omitted. When passing a name directly, use the `--desc`, `--user`, and `--interactive` options instead. + + The interactive description and user-prompt questions are only asked when + the name argument is omitted. When passing a name directly, use the + `--desc`, `--user`, and `--interactive` options instead. + - -## Command Signature +## Command signature ``` make:prompt {name?} {--from=} {--desc=} {--u|user} {--role=*} {--i|interactive} {--f|force} ``` - ### Arguments -| Argument | Required | Description | -|----------|----------|-------------| +| Argument | Required | Description | +| -------- | -------- | -------------------------------------------------------------------------------------------------- | | `name` | No | The name of the prompt. Omit to be prompted interactively. Automatically normalised to kebab-case. | - ### Options -| Option | Shorthand | Description | -|----------------------|-----------|-------------| -| `--from=` | | Path to a custom stub file to use as the user prompt template. | -| `--desc=` | | A short description of what this prompt does. Stored in `metadata.json`. | -| `--user` | `-u` | Also create a `user` prompt file alongside the default `system` prompt. | -| `--role=*` | | One or more additional roles to scaffold prompt files for. Repeatable. | -| `--interactive` | `-i` | Interactively choose which additional roles to create. | -| `--force` | `-f` | Overwrite an existing prompt's latest version without confirmation. | +| Option | Shorthand | Description | +| --------------- | --------- | ------------------------------------------------------------------------ | +| `--from=` | | Path to a custom stub file to use as the user prompt template. | +| `--desc=` | | A short description of what this prompt does. Stored in `metadata.json`. | +| `--user` | `-u` | Also create a `user` prompt file alongside the default `system` prompt. | +| `--role=*` | | One or more additional roles to scaffold prompt files for. Repeatable. | +| `--interactive` | `-i` | Interactively choose which additional roles to create. | +| `--force` | `-f` | Overwrite an existing prompt's latest version without confirmation. | - -## Prompt Structure +## Prompt structure - -### Directory Layout +### Directory layout Every prompt is organised into a named directory containing versioned sub-directories and a `metadata.json` file: @@ -123,7 +94,6 @@ resources/prompts/ The file extension is controlled by the `prompt-deck.extension` configuration value (default: `md`). For example, setting it to `txt` produces `system.txt`, `user.txt`, etc. - ### Metadata A `metadata.json` file is written to the prompt root directory each time the command runs. It captures: @@ -138,19 +108,17 @@ A `metadata.json` file is written to the prompt root directory each time the com } ``` -| Field | Description | -|---------------|-------------| -| `name` | The kebab-case prompt name. | -| `description` | A human-readable summary. Populated via `--desc=` or the interactive flow. | +| Field | Description | +| ------------- | ------------------------------------------------------------------------------- | +| `name` | The kebab-case prompt name. | +| `description` | A human-readable summary. Populated via `--desc=` or the interactive flow. | | `roles` | An ordered list of every role that was scaffolded. Always starts with `system`. | -| `variables` | Reserved for future use (template variable extraction). | -| `created_at` | ISO 8601 timestamp of creation. | +| `variables` | Reserved for future use (template variable extraction). | +| `created_at` | ISO 8601 timestamp of creation. | - ## Roles - -### System Role (Default) +### System role (default) A `system.md` file is **always** created. This is the primary prompt file and represents the system-level instructions for your AI agent. No flag is needed: @@ -165,12 +133,12 @@ The default system prompt stub contains: You are an AI assistant specialized in... Follow these guidelines: + - Be helpful - Use {{ $tone }} tone ``` - -### User Role +### User role To also scaffold a user prompt file, pass the `--user` (or `-u`) flag: @@ -191,8 +159,7 @@ Your task is to... User input: {{ $input }} ``` - -### Extra Roles +### Extra roles You can scaffold prompt files for any additional roles using the `--role` option. It is repeatable: @@ -221,18 +188,18 @@ php artisan make:prompt code-reviewer -i # Then: "Which roles? (comma-separated, e.g. assistant,developer)" ``` -> **Note** -> When `--role` values are provided explicitly, the interactive role prompt is skipped — explicit values always take precedence. + + When `--role` values are provided explicitly, the interactive role prompt is + skipped — explicit values always take precedence. + All scaffolded roles (including `system` and optionally `user`) are recorded in the `roles` array of `metadata.json`. - ## Versioning Prompt Deck uses directory-based versioning. Each version lives in its own sub-directory (`v1/`, `v2/`, etc.) inside the prompt folder. - -### Auto-Increment +### Auto-increment When you run the command for a prompt that already has one or more versions, you are presented with a choice: @@ -247,15 +214,13 @@ php artisan make:prompt code-reviewer Selecting **"Create a new version"** auto-increments the version number and creates a fresh directory (e.g. `v3/`). Existing versions remain untouched. - ### Overwriting Selecting **"Overwrite"** replaces the files in the latest version directory. The version number stays the same, but the prompt files are regenerated from the current stubs. Selecting **"Cancel"** aborts the command without making any changes. - -### Force Mode +### Force mode In non-interactive environments (CI pipelines, scripts), use `--force` (or `-f`) to overwrite the latest version without any prompts: @@ -267,24 +232,21 @@ If version 2 exists, `--force` overwrites `v2/` directly. It will **never** crea For brand-new prompts, `--force` has no special effect; `v1/` is created as normal. - ## Stubs The content of generated prompt files comes from **stub templates**. Three stubs ship with the package: - -### Default Stubs +### Default stubs -| Stub | Used For | Placeholders | -|-------------------------|--------------------|--------------------| -| `system-prompt.stub` | `system.md` | `{{ $tone }}` | -| `user-prompt.stub` | `user.md` | `{{ $name }}`, `{{ $input }}` | -| `role-prompt.stub` | Extra role files | `{{ $role }}` (auto-replaced at generation time) | +| Stub | Used For | Placeholders | +| -------------------- | ---------------- | ------------------------------------------------ | +| `system-prompt.stub` | `system.md` | `{{ $tone }}` | +| `user-prompt.stub` | `user.md` | `{{ $name }}`, `{{ $input }}` | +| `role-prompt.stub` | Extra role files | `{{ $role }}` (auto-replaced at generation time) | The default stubs are located in the package's `stubs/` directory. - -### Custom Stubs +### Custom stubs To customise the stubs for your project, create a `stubs/prompt-deck/` directory at your application root and place your own versions of any stub file there: @@ -299,8 +261,7 @@ your-app/ Published stubs **always take precedence** over the package defaults. You only need to publish the stubs you want to override — any missing stubs fall back to the package defaults. - -### Using a One-Off Template +### Using a one-off template To use a specific file as the user prompt template for a single invocation, pass `--from`: @@ -310,35 +271,32 @@ php artisan make:prompt code-reviewer --user --from=path/to/my-template.md The `--from` option only affects the user prompt file. The system prompt always uses its own stub. - -## Name Normalisation +## Name normalisation All prompt names are automatically converted to **kebab-case** for consistent directory naming. The conversion handles a variety of input formats: -| Input | Result | -|--------------------|-------------------| -| `MyPrompt` | `my-prompt` | -| `orderSummary` | `order-summary` | -| `snake_case_name` | `snake-case-name` | -| `LOUD_PROMPT` | `loud-prompt` | -| `My_Cool Prompt` | `my-cool-prompt` | -| `already-kebab` | `already-kebab` | +| Input | Result | +| ----------------- | ----------------- | +| `MyPrompt` | `my-prompt` | +| `orderSummary` | `order-summary` | +| `snake_case_name` | `snake-case-name` | +| `LOUD_PROMPT` | `loud-prompt` | +| `My_Cool Prompt` | `my-cool-prompt` | +| `already-kebab` | `already-kebab` | This normalisation applies to both the prompt name and any extra role names provided via `--role`. - ## Configuration The command respects the following values from `config/prompt-deck.php`: -| Key | Default | Description | -|---------------------------|--------------------------|-------------| -| `prompt-deck.path` | `resource_path('prompts')` | Base directory where prompt structures are created. | -| `prompt-deck.extension` | `md` | File extension for generated prompt files. | +| Key | Default | Description | +| ----------------------- | -------------------------- | --------------------------------------------------- | +| `prompt-deck.path` | `resource_path('prompts')` | Base directory where prompt structures are created. | +| `prompt-deck.extension` | `md` | File extension for generated prompt files. | -See the full [Configuration](configuration.md) reference for all options. +See the full [Configuration](/getting-started/configuration) reference for all options. - ## Examples **Create a minimal prompt (system only):** @@ -383,7 +341,7 @@ php artisan make:prompt email-drafter --force php artisan make:prompt email-drafter --user --from=stubs/my-user.stub ``` -### Success Output +### Success output After successful creation, the command outputs a confirmation message: diff --git a/docs/prompts.md b/docs/core/prompts.mdx similarity index 74% rename from docs/prompts.md rename to docs/core/prompts.mdx index 6383eb4..2bc77fe 100644 --- a/docs/prompts.md +++ b/docs/core/prompts.mdx @@ -1,37 +1,8 @@ -# Prompts - -- [Introduction](#introduction) -- [Retrieving Prompts](#retrieving-prompts) - - [The PromptDeck Facade](#the-prompt-facade) - - [Dependency Injection](#dependency-injection) - - [Active Version](#active-version) - - [Specific Version](#specific-version) -- [Rendering Roles](#rendering-roles) - - [Dynamic Role Methods](#dynamic-role-methods) - - [The role Method](#the-role-method) - - [Raw Content](#raw-content) -- [Inspecting Prompts](#inspecting-prompts) - - [Available Roles](#available-roles) - - [Checking for a Role](#checking-for-a-role) - - [Metadata](#metadata) - - [Name and Version](#name-and-version) -- [Building Messages for AI APIs](#building-messages-for-ai-apis) - - [All Roles](#all-roles) - - [Filtering Roles](#filtering-roles) -- [Variable Interpolation](#variable-interpolation) - - [Syntax](#syntax) - - [Supported Value Types](#supported-value-types) - - [Missing Variables](#missing-variables) -- [Versioning](#versioning) - - [Directory Structure](#directory-structure) - - [Listing Versions](#listing-versions) - - [Activating a Version](#activating-a-version) - - [Version Resolution Order](#version-resolution) -- [Caching](#caching) -- [Execution Tracking](#execution-tracking) -- [Serialisation](#serialisation) - - +--- +title: "Working with prompts" +description: "Load, render, version, cache, and track AI prompts in your Laravel application." +--- + ## Introduction Prompt Deck provides a clean, expressive API for loading, rendering, and managing versioned AI prompts in your Laravel application. Prompts are stored as plain files on disk and organised by name, version, and role. They are accessed through the `PromptDeck` facade, which feels like any other first-party Laravel service. @@ -50,11 +21,9 @@ $prompt->user(['input' => $request->message]); // "Summarise the following order: ..." ``` - -## Retrieving Prompts +## Retrieving prompts - -### The PromptDeck Facade +### The PromptDeck facade The `PromptDeck` facade is the primary entry point for loading prompts. It delegates to the `PromptManager` singleton registered by the service provider: @@ -68,10 +37,9 @@ $prompt = PromptDeck::get('order-summary'); $prompt = PromptDeck::get('order-summary', 2); ``` -The `get` method returns a `PromptTemplate` instance. If no version is specified, the [active version](#version-resolution) is resolved automatically. +The `get` method returns a `PromptTemplate` instance. If no version is specified, the [active version](#version-resolution-order) is resolved automatically. - -### Dependency Injection +### Dependency injection You can also inject the `PromptManager` directly via Laravel's service container: @@ -92,8 +60,7 @@ class OrderController extends Controller The `PromptManager` is registered as a singleton, so the same instance is reused throughout the request lifecycle. - -### Active Version +### Active version Use the `active` method to explicitly load the active version: @@ -105,8 +72,7 @@ $prompt->version(); // e.g. 3 This is equivalent to calling `get()` without a version number. - -### Specific Version +### Specific version Pass a version number as the second argument to `get` to load a specific version, regardless of which version is currently active: @@ -118,13 +84,11 @@ $prompt->version(); // 1 If the version does not exist, an `InvalidVersionException` is thrown. - -## Rendering Roles +## Rendering roles Once you have a `PromptTemplate` instance, you can render any role's content with variable interpolation. - -### Dynamic Role Methods +### Dynamic role methods The most expressive way to render a role is to call it as a method directly on the prompt instance. This uses PHP's `__call` magic method and works for **any** role — not just `system` and `user`: @@ -149,8 +113,7 @@ When called without arguments, the content is returned with placeholders left in $prompt->system(); // "You are a {{ $tone }} AI assistant..." ``` - -### The `role` Method +### The `role` method If the role name is dynamic or stored in a variable, use the explicit `role` method: @@ -162,8 +125,7 @@ $content = $prompt->role($roleName, ['context' => $history]); This is functionally identical to the magic method approach. If the role does not exist, an empty string is returned. - -### Raw Content +### Raw content To retrieve a role's content **without** variable interpolation, use the `raw` method: @@ -174,11 +136,9 @@ $template = $prompt->raw('system'); This is useful when you need to inspect the template, store it, or perform your own interpolation logic. - -## Inspecting Prompts +## Inspecting prompts - -### Available Roles +### Available roles The `roles` method returns an array of all role names defined in the prompt: @@ -189,8 +149,7 @@ $prompt->roles(); Roles are discovered automatically from the files in the version directory. Any file matching the configured extension (e.g. `.md`) becomes a role — the filename (without extension) is the role name. - -### Checking for a Role +### Checking for a role Use the `has` method to check whether a specific role exists before attempting to render it: @@ -200,7 +159,6 @@ if ($prompt->has('assistant')) { } ``` - ### Metadata Each prompt version can carry metadata (stored in `metadata.json` at the version level). Access it via the `metadata` method: @@ -212,19 +170,16 @@ $prompt->metadata(); Metadata is an associative array. If no `metadata.json` exists in the version directory, an empty array is returned. - -### Name and Version +### Name and version ```php $prompt->name(); // 'order-summary' $prompt->version(); // 2 ``` - -## Building Messages for AI APIs +## Building messages for AI APIs - -### All Roles +### All roles The `toMessages` method builds a messages array compatible with OpenAI, Anthropic, and other chat-completion APIs. It renders every role with the given variables and returns them in definition order: @@ -257,8 +212,7 @@ $response = Anthropic::messages()->create([ ]); ``` - -### Filtering Roles +### Filtering roles Pass a second argument to limit which roles are included and in what order: @@ -271,18 +225,16 @@ $messages = $prompt->toMessages( Roles specified in the filter that don't exist in the prompt are silently skipped. - -## Variable Interpolation +## Variable interpolation - ### Syntax Prompt Deck supports two placeholder syntaxes within prompt files: -| Syntax | Example | -|---|---| +| Syntax | Example | +| -------------------- | ------------- | | Spaced (recommended) | `{{ $tone }}` | -| Compact | `{{tone}}` | +| Compact | `{{tone}}` | Both are replaced when you render a role with variables: @@ -293,11 +245,12 @@ $prompt->system(['tone' => 'friendly', 'task' => 'summarise']); // "You are a friendly AI assistant. Task: summarise" ``` -> **Tip** -> Use the spaced syntax (`{{ $variable }}`) for consistency with Laravel Blade conventions. + + Use the spaced syntax (`{{ $variable }}`) for consistency with Laravel Blade + conventions. + - -### Supported Value Types +### Supported value types Values are cast to strings via PHP's `(string)` cast, so you can pass any scalar or stringable value: @@ -310,8 +263,7 @@ $prompt->system([ ]); ``` - -### Missing Variables +### Missing variables Placeholders that are not matched by the provided variables are **left intact**. This lets you render in stages or identify unfilled variables: @@ -320,11 +272,9 @@ $prompt->system(['tone' => 'friendly']); // "You are a friendly AI assistant. Your role is {{ $role }}." ``` - ## Versioning - -### Directory Structure +### Directory structure Prompts are versioned using directory-based versioning. Each version lives in its own sub-directory (`v1/`, `v2/`, etc.) inside the prompt folder: @@ -342,11 +292,11 @@ resources/prompts/ ``` Each version directory can contain: + - Any number of role files (e.g. `system.md`, `user.md`, `assistant.md`) - An optional `metadata.json` for version-level metadata - -### Listing Versions +### Listing versions Retrieve all versions for a prompt programmatically: @@ -367,10 +317,9 @@ Or use the Artisan command: php artisan prompt:list --all ``` -See [Artisan Commands — prompt:list](commands.md#prompt-list) for details. +See [Artisan Commands — prompt:list](/core/commands#promptlist) for details. - -### Activating a Version +### Activating a version Set a specific version as the active version: @@ -388,10 +337,9 @@ Or use the Artisan command: php artisan prompt:activate order-summary 2 ``` -See [Artisan Commands — prompt:activate](commands.md#prompt-activate) for details. +See [Artisan Commands — prompt:activate](/core/commands#promptactivate) for details. - -### Version Resolution Order +### Version resolution order When you call `PromptDeck::get('name')` without a version, the active version is resolved in this priority order: @@ -401,7 +349,6 @@ When you call `PromptDeck::get('name')` without a version, the active version is If no versions exist at all, an `InvalidVersionException` is thrown. - ## Caching When caching is enabled, loaded prompts are stored in your configured cache store to avoid repeated filesystem reads: @@ -420,10 +367,9 @@ The cache key follows the pattern `{prefix}{name}.v{version}`. Prompts are cache Caching is automatically **disabled** when `APP_DEBUG=true` to ensure file changes are picked up immediately during development. -See [Configuration — Cache](configuration.md#cache) for the full reference. +See [Configuration — Cache](/getting-started/configuration#cache) for the full reference. - -## Execution Tracking +## Execution tracking When database tracking is enabled, you can log prompt executions for performance monitoring, A/B testing, and audit trails: @@ -440,14 +386,16 @@ PromptDeck::track('order-summary', 2, [ ]); ``` -All fields in the data array are optional. Records are inserted into the `prompt_executions` table: If tracking is disabled, the `track` method is a safe no-op. +All fields in the data array are optional. Records are inserted into the `prompt_executions` table. If tracking is disabled, the `track` method is a safe no-op. -See [Tracking & Performance](tracking.md) for comprehensive documentation on the tracking system, database schema, and Eloquent models. +See [Tracking & Performance](/advanced/tracking) for comprehensive documentation on the tracking system, database schema, and Eloquent models. -> **Tip** -> When using the [Laravel AI SDK integration](ai-sdk.md), the `TrackPromptMiddleware` handles execution tracking automatically — no manual `track()` calls needed. + + When using the [Laravel AI SDK integration](/integrations/ai-sdk), the + `TrackPromptMiddleware` handles execution tracking automatically — no manual + `track()` calls needed. + - ## Serialisation The `PromptTemplate` class implements Laravel's `Arrayable` contract. Call `toArray()` to get a serialisable representation: diff --git a/docs/docs.json b/docs/docs.json new file mode 100644 index 0000000..0c4c296 --- /dev/null +++ b/docs/docs.json @@ -0,0 +1,97 @@ +{ + "$schema": "https://mintlify.com/docs.json", + "theme": "mint", + "name": "Prompt Deck by PromptPHP", + "colors": { + "primary": "#6366F1", + "light": "#818CF8", + "dark": "#4F46E5" + }, + "favicon": "/logo/logo.svg", + "navigation": { + "tabs": [ + { + "tab": "Documentation", + "groups": [ + { + "group": "Getting started", + "pages": [ + "getting-started/introduction", + "getting-started/installation", + "getting-started/configuration" + ] + }, + { + "group": "Core concepts", + "pages": [ + "core/prompts", + "core/make-prompt", + "core/commands" + ] + }, + { + "group": "Integrations", + "pages": [ + "integrations/ai-sdk" + ] + }, + { + "group": "Advanced", + "pages": [ + "advanced/tracking", + "advanced/testing", + "advanced/api-reference" + ] + } + ] + } + ], + "global": { + "anchors": [ + { + "anchor": "GitHub", + "href": "https://github.com/veeqtoh/prompt-deck", + "icon": "github" + }, + { + "anchor": "Packagist", + "href": "https://packagist.org/packages/veeqtoh/prompt-deck", + "icon": "box" + } + ] + } + }, + "logo": { + "light": "/logo/logo.svg", + "dark": "/logo/logo.svg" + }, + "navbar": { + "links": [ + { + "label": "GitHub", + "href": "https://github.com/promptphp/prompt-deck" + }, + { + "label": "Sponsor", + "href": "https://github.com/sponsors/veeqtoh" + } + ] + }, + "contextual": { + "options": [ + "copy", + "view", + "chatgpt", + "claude", + "perplexity", + "mcp", + "cursor", + "vscode" + ] + }, + "footer": { + "socials": { + "github": "https://github.com/promptphp/prompt-deck" + } + } +} diff --git a/docs/favicon.svg b/docs/favicon.svg new file mode 100644 index 0000000..b785c73 --- /dev/null +++ b/docs/favicon.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/docs/configuration.md b/docs/getting-started/configuration.mdx similarity index 52% rename from docs/configuration.md rename to docs/getting-started/configuration.mdx index e26ae4c..6f64b67 100644 --- a/docs/configuration.md +++ b/docs/getting-started/configuration.mdx @@ -1,29 +1,13 @@ -# Configuration - -- [Introduction](#introduction) -- [Publishing the Configuration](#publishing-the-configuration) -- [Prompts Path](#prompts-path) -- [File Extension](#file-extension) -- [Versioning Strategy](#versioning-strategy) -- [Cache](#cache) - - [Enabling / Disabling](#enabling-disabling-cache) - - [Cache Store](#cache-store) - - [TTL](#ttl) - - [Cache Key Prefix](#cache-key-prefix) -- [Database Tracking](#database-tracking) - - [Enabling / Disabling](#enabling-disabling-tracking) - - [Database Connection](#database-connection) -- [AI SDK Integration](#ai-sdk-integration) -- [Full Configuration Reference](#full-configuration-reference) -- [Environment Variables Reference](#environment-variables-reference) - - +--- +title: "Configuration" +description: "All available configuration options for Prompt Deck." +--- + ## Introduction Prompt Deck ships with sensible defaults that work out of the box. Like most Laravel packages, all configuration lives in `config/prompt-deck.php` and every option can be overridden via environment variables for deployment flexibility. - -## Publishing the Configuration +## Publishing the configuration Publish the configuration file using the Artisan command: @@ -33,8 +17,7 @@ php artisan vendor:publish --tag=prompt-deck-config This copies the package's default configuration to `config/prompt-deck.php` in your application. Once published, you can modify it freely. - -## Prompts Path +## Prompts path The `path` option determines where your versioned prompt files are stored on disk: @@ -50,8 +33,7 @@ By default, prompts live in `resources/prompts/`. You can change this to any dir The directory is created automatically when you first run `php artisan make:prompt`. - -## File Extension +## File extension The `extension` option controls the file extension used for prompt template files: @@ -61,18 +43,19 @@ The `extension` option controls the file extension used for prompt template file Markdown (`.md`) is the default and recommended for readability. You can change it to any extension: -| Value | Result | -|---|---| -| `md` | `system.md`, `user.md` | -| `txt` | `system.txt`, `user.txt` | +| Value | Result | +| ----------- | ------------------------------------ | +| `md` | `system.md`, `user.md` | +| `txt` | `system.txt`, `user.txt` | | `blade.php` | `system.blade.php`, `user.blade.php` | -| `prompt` | `system.prompt`, `user.prompt` | +| `prompt` | `system.prompt`, `user.prompt` | -> **Note** -> Changing the extension only affects newly generated files. Existing prompt files are not renamed automatically. + + Changing the extension only affects newly generated files. Existing prompt + files are not renamed automatically. + - -## Versioning Strategy +## Versioning strategy The `versioning` option controls how prompt versions are organised: @@ -85,14 +68,13 @@ Currently, only the `directory` strategy is supported. Each version is stored in ``` resources/prompts/order-summary/ ├── v1/ -│ └── system.md + └── system.md ├── v2/ -│ ├── system.md -│ └── user.md + ├── system.md + └── user.md └── metadata.json ``` - ## Cache The `cache` section controls prompt caching behaviour. Caching avoids repeated filesystem reads by storing loaded prompts in your configured cache store. @@ -106,8 +88,7 @@ The `cache` section controls prompt caching behaviour. Caching avoids repeated f ], ``` - -### Enabling / Disabling +### Enabling / disabling ```php 'enabled' => env('PROMPTDECK_CACHE_ENABLED', env('APP_DEBUG', false) ? false : true), @@ -122,8 +103,7 @@ PROMPTDECK_CACHE_ENABLED=false # Always disable caching PROMPTDECK_CACHE_ENABLED=true # Always enable caching ``` - -### Cache Store +### Cache store ```php 'store' => env('PROMPTDECK_CACHE_STORE', 'file'), @@ -131,14 +111,13 @@ PROMPTDECK_CACHE_ENABLED=true # Always enable caching The cache store to use. Must match a store name defined in your `config/cache.php`. Common values: -| Store | Description | -|---|---| -| `file` | File-based cache (default). Simple, no extra dependencies. | -| `redis` | Redis cache. Fast, shared across workers. | -| `memcached` | Memcached. Similar to Redis. | -| `array` | In-memory only. Cleared on each request (useful for testing). | +| Store | Description | +| ----------- | ------------------------------------------------------------- | +| `file` | File-based cache (default). Simple, no extra dependencies. | +| `redis` | Redis cache. Fast, shared across workers. | +| `memcached` | Memcached. Similar to Redis. | +| `array` | In-memory only. Cleared on each request (useful for testing). | - ### TTL ```php @@ -147,8 +126,7 @@ The cache store to use. Must match a store name defined in your `config/cache.ph Cache time-to-live in **seconds**. After this duration, the prompt is re-read from disk on the next access. Default is 3600 seconds (1 hour). - -### Cache Key Prefix +### Cache key prefix ```php 'prefix' => env('CACHE_PREFIX', env('PROMPTDECK_CACHE_PREFIX', 'prompt-deck:')), @@ -157,12 +135,12 @@ Cache time-to-live in **seconds**. After this duration, the prompt is re-read fr The prefix prepended to all cache keys. The final cache key follows the pattern: `{prefix}{prompt-name}.v{version}`. For example, with the default prefix: + ``` prompt-deck:order-summary.v2 ``` - -## Database Tracking +## Database tracking The `tracking` section controls whether prompt versions and executions are logged to the database. @@ -173,8 +151,7 @@ The `tracking` section controls whether prompt versions and executions are logge ], ``` - -### Enabling / Disabling +### Enabling / disabling ```php 'enabled' => env('PROMPTDECK_TRACKING_ENABLED', env('APP_DEBUG', false) ? false : true), @@ -185,11 +162,13 @@ Like caching, tracking is **disabled** in debug mode and **enabled** in producti - **Version activation** is stored in the `prompt_versions` database table (instead of `metadata.json`). - **Execution tracking** via `PromptDeck::track()` inserts records into the `prompt_executions` table. -> **Important** -> You must publish and run the migrations before enabling tracking. See [Installation — Publishing Migrations](installation.md#publishing-migrations). + + You must publish and run the migrations before enabling tracking. See + [Installation — Publishing + migrations](/getting-started/installation#publishing-migrations). + - -### Database Connection +### Database connection ```php 'connection' => env('PROMPTDECK_DB_CONNECTION'), @@ -201,14 +180,13 @@ The database connection to use for tracking tables. Set to `null` (the default) PROMPTDECK_DB_CONNECTION=analytics ``` - -## AI SDK Integration +## AI SDK integration ```php 'scaffold_on_make_agent' => env('PROMPTDECK_SCAFFOLD_ON_MAKE_AGENT', true), ``` -When the [Laravel AI SDK](https://laravel.com/docs/ai-sdk) is installed and this option is `true`, Prompt Deck automatically creates a matching prompt directory whenever you run `php artisan make:agent`. See the [AI SDK Integration](ai-sdk.md) documentation for details. +When the [Laravel AI SDK](https://laravel.com/docs/ai-sdk) is installed and this option is `true`, Prompt Deck automatically creates a matching prompt directory whenever you run `php artisan make:agent`. See the [AI SDK Integration](/integrations/ai-sdk) documentation for details. Set to `false` to disable automatic scaffolding: @@ -216,31 +194,29 @@ Set to `false` to disable automatic scaffolding: PROMPTDECK_SCAFFOLD_ON_MAKE_AGENT=false ``` - -## Full Configuration Reference - -| Key | Type | Default | Description | -|---|---|---|---| -| `path` | `string` | `resource_path('prompts')` | Base directory where prompt files are stored. | -| `extension` | `string` | `md` | File extension for prompt template files. | -| `versioning` | `string` | `directory` | Versioning strategy (`directory`). | -| `cache.enabled` | `bool` | `true` (prod) / `false` (debug) | Enable prompt caching. | -| `cache.store` | `string` | `file` | Cache store name. | -| `cache.ttl` | `int` | `3600` | Cache TTL in seconds. | -| `cache.prefix` | `string` | `prompt-deck:` | Cache key prefix. | -| `tracking.enabled` | `bool` | `true` (prod) / `false` (debug) | Enable database tracking. | -| `tracking.connection` | `string\|null` | `null` | Database connection name. | -| `scaffold_on_make_agent` | `bool` | `true` | Auto-scaffold prompts on `make:agent`. | - - -## Environment Variables Reference - -| Variable | Default | Description | -|---|---|---| -| `PROMPTDECK_CACHE_ENABLED` | Dynamic | Enable/disable caching. | -| `PROMPTDECK_CACHE_STORE` | `file` | Cache store to use. | -| `PROMPTDECK_CACHE_TTL` | `3600` | Cache TTL in seconds. | -| `PROMPTDECK_CACHE_PREFIX` | `prompt-deck:` | Cache key prefix. | -| `PROMPTDECK_TRACKING_ENABLED` | Dynamic | Enable/disable database tracking. | -| `PROMPTDECK_DB_CONNECTION` | `null` | Database connection for tracking. | -| `PROMPTDECK_SCAFFOLD_ON_MAKE_AGENT` | `true` | Auto-scaffold on `make:agent`. | +## Full configuration reference + +| Key | Type | Default | Description | +| ------------------------ | -------------- | ------------------------------- | --------------------------------------------- | +| `path` | `string` | `resource_path('prompts')` | Base directory where prompt files are stored. | +| `extension` | `string` | `md` | File extension for prompt template files. | +| `versioning` | `string` | `directory` | Versioning strategy (`directory`). | +| `cache.enabled` | `bool` | `true` (prod) / `false` (debug) | Enable prompt caching. | +| `cache.store` | `string` | `file` | Cache store name. | +| `cache.ttl` | `int` | `3600` | Cache TTL in seconds. | +| `cache.prefix` | `string` | `prompt-deck:` | Cache key prefix. | +| `tracking.enabled` | `bool` | `true` (prod) / `false` (debug) | Enable database tracking. | +| `tracking.connection` | `string\|null` | `null` | Database connection name. | +| `scaffold_on_make_agent` | `bool` | `true` | Auto-scaffold prompts on `make:agent`. | + +## Environment variables reference + +| Variable | Default | Description | +| ----------------------------------- | -------------- | --------------------------------- | +| `PROMPTDECK_CACHE_ENABLED` | Dynamic | Enable/disable caching. | +| `PROMPTDECK_CACHE_STORE` | `file` | Cache store to use. | +| `PROMPTDECK_CACHE_TTL` | `3600` | Cache TTL in seconds. | +| `PROMPTDECK_CACHE_PREFIX` | `prompt-deck:` | Cache key prefix. | +| `PROMPTDECK_TRACKING_ENABLED` | Dynamic | Enable/disable database tracking. | +| `PROMPTDECK_DB_CONNECTION` | `null` | Database connection for tracking. | +| `PROMPTDECK_SCAFFOLD_ON_MAKE_AGENT` | `true` | Auto-scaffold on `make:agent`. | diff --git a/docs/installation.md b/docs/getting-started/installation.mdx similarity index 52% rename from docs/installation.md rename to docs/getting-started/installation.mdx index 1e0dfbc..7116c9d 100644 --- a/docs/installation.md +++ b/docs/getting-started/installation.mdx @@ -1,31 +1,29 @@ -# Installation +--- +title: "Installation" +description: "Requirements, setup, and environment configuration for Prompt Deck." +--- -- [Requirements](#requirements) -- [Installing Prompt Deck](#installing-prompt-deck) -- [Publishing the Configuration](#publishing-the-configuration) -- [Publishing Migrations](#publishing-migrations) -- [Environment Variables](#environment-variables) -- [Verifying the Installation](#verifying-the-installation) - - ## Requirements Prompt Deck has the following requirements: -| Dependency | Version | -|---|---| -| PHP | `^8.2` | -| Laravel | `^11.0` ++ | +| Dependency | Version | +| ---------- | ---------- | +| PHP | `^8.2` | +| Laravel | `^11.0` ++ | -*Note* that the `sebastian/diff` package is required and is used for the `prompt:diff` command. It may conflict with your PHPUnit/Pest PHP installation so ypu may need to upgrade these dependencies to the latest version. + + The `sebastian/diff` package is required and is used for the `prompt:diff` + command. It may conflict with your PHPUnit/Pest PHP installation so you may + need to upgrade these dependencies to the latest version. + -### Optional Dependencies +### Optional dependencies -| Package | Purpose | -|---|---| +| Package | Purpose | +| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `laravel/ai` | Enables deep integration with Laravel AI SDK agents to support automatic instructions loading, prompt version tracking in conversations, and auto-scaffolding prompts when creating agents. | - ## Installing Prompt Deck Install the package via Composer: @@ -34,34 +32,13 @@ Install the package via Composer: composer require veeqtoh/prompt-deck ``` -The package uses Laravel's auto-discovery, so the service provider and facade are registered automatically. No manual registration is needed. - -If you have disabled auto-discovery, add the provider and facade to your `bootstrap/providers.php` (Laravel 11+) or `config/app.php`: - -```php -// bootstrap/providers.php (Laravel 11+) -return [ - // ... - Veeqtoh\PromptDeck\Providers\PromptDeckServiceProvider::class, -]; -``` + + If you have disabled auto-discovery, you will need to manually register the + service provider and facade. See the [Manual discovery](#manual-discovery) + section for details. + -Or for `config/app.php`: - -```php -'providers' => [ - // ... - Veeqtoh\PromptDeck\Providers\PromptDeckServiceProvider::class, -], - -'aliases' => [ - // ... - 'PromptDeck' => Veeqtoh\PromptDeck\Facades\PromptDeck::class, -], -``` - - -## Publishing the Configuration +## Publishing the configuration Publish the configuration file to customise Prompt Deck's behaviour: @@ -69,10 +46,9 @@ Publish the configuration file to customise Prompt Deck's behaviour: php artisan vendor:publish --tag=prompt-deck-config ``` -This creates `config/prompt-deck.php` in your application. See the [Configuration](configuration.md) documentation for a full reference of all available options. +This creates `config/prompt-deck.php` in your application. See the [Configuration](/getting-started/configuration) documentation for a full reference of all available options. - -## Publishing Migrations +## Publishing migrations If you plan to use database tracking for prompt versions and execution logging, publish and run the migrations: @@ -83,21 +59,24 @@ php artisan migrate This creates two tables: -| Table | Purpose | -|---|---| -| `prompt_versions` | Stores prompt version records and tracks which version is active. | +| Table | Purpose | +| ------------------- | -------------------------------------------------------------------------------- | +| `prompt_versions` | Stores prompt version records and tracks which version is active. | | `prompt_executions` | Logs individual prompt executions with tokens, latency, cost, and feedback data. | -> **Note** -> Database tracking is optional. Prompt Deck works fully without it as version activation falls back to `metadata.json` files, and execution tracking is simply disabled. + + Database tracking is optional. Prompt Deck works fully without it as version + activation falls back to `metadata.json` files, and execution tracking is + simply disabled. + + +If you prefer, you may publish both the configuration and migration files by running a single command: -> If you prefer, you may publish both the configuration and migration files by running a single command. ```bash php artisan vendor:publish --provider="Veeqtoh\PromptDeck\Providers\PromptDeckServiceProvider" ``` - -## Environment Variables +## Environment variables Add the following to your `.env` file to configure Prompt Deck's runtime behaviour: @@ -118,8 +97,7 @@ PROMPTDECK_SCAFFOLD_ON_MAKE_AGENT=true # Auto-create prompt when running make:ag All environment variables are optional as sensible defaults are provided. - -## Verifying the Installation +## Verifying the installation After installation, verify everything is working: @@ -136,10 +114,55 @@ php artisan prompt:test hello-world You should see the scaffolded prompt structure in `resources/prompts/hello-world/`. -### What's Next? +## Manual discovery + +The package uses Laravel's auto-discovery, so the service provider and facade are registered automatically. No manual registration is needed. + +If you have disabled auto-discovery, add the provider and facade to your `bootstrap/providers.php` (Laravel 11+) or `config/app.php`: + +```php +// bootstrap/providers.php (Laravel 11+) +return [ + // ... + Veeqtoh\PromptDeck\Providers\PromptDeckServiceProvider::class, +]; +``` + +Or for `config/app.php`: + +```php +'providers' => [ + // ... + Veeqtoh\PromptDeck\Providers\PromptDeckServiceProvider::class, +], + +'aliases' => [ + // ... + 'PromptDeck' => Veeqtoh\PromptDeck\Facades\PromptDeck::class, +], +``` -- [Configuration](configuration.md) — Customise Prompt Deck's behaviour. -- [Creating Prompts](make-prompt.md) — Learn the full `make:prompt` command. -- [Working with Prompts](prompts.md) — Load, render, and manage prompts in your code. -- [Artisan Commands](commands.md) — All available Artisan commands. -- [Laravel AI SDK Integration](ai-sdk.md) — Use prompts with AI agents. +## What's next? + + + + Customise Prompt Deck's behaviour. + + + Learn the full `make:prompt` command. + + + Load, render, and manage prompts in your code. + + + Use prompts with AI agents. + + diff --git a/docs/getting-started/introduction.mdx b/docs/getting-started/introduction.mdx new file mode 100644 index 0000000..5329b73 --- /dev/null +++ b/docs/getting-started/introduction.mdx @@ -0,0 +1,166 @@ +--- +title: "Introduction" +description: "Prompt Deck helps you organise your AI Agents instructions as structured, version-controlled files, making it easy to iterate, compare, and activate prompt versions across your Laravel / PHP application." +--- + +It provides variable interpolation, performance tracking, A/B testing, and optional seamless integration with the [Laravel AI SDK](https://laravel.com/docs/ai-sdk). + +## Quick start + +Get up and running with Prompt Deck in minutes. + + + Install, configure, and verify Prompt Deck in your Laravel project. + + +## Quick usage + +### Creating a prompt + +After installing (installation guide), use the Artisan command to create a versioned prompt: + +```bash +php artisan make:prompt order-summary +``` + +This creates the following structure: + +``` +resources/prompts/ +└── order-summary/ + ├── v1/ + └── system.md + └── metadata.json +``` + +Edit `resources/prompts/order-summary/v1/system.md` with your prompt content. Use `{{ $variable }}` syntax for dynamic values: + +```markdown +You are a {{ $tone }} customer service agent. +Summarise the following order for the customer: {{ $order }}. +``` + +### Using a prompt + +Load and render prompts with the `PromptDeck` facade: + +```php +use Veeqtoh\PromptDeck\Facades\PromptDeck; + +// Load the active version of a prompt +$prompt = PromptDeck::get('order-summary'); + +// Render a role with variables +$prompt->system(['tone' => 'friendly', 'order' => $orderDetails]); +// "You are a friendly customer service agent. Summarise the following order..." + +// Build a messages array ready for any chat-completion API +$messages = $prompt->toMessages(['tone' => 'friendly', 'order' => $orderDetails]); +// [['role' => 'system', 'content' => '...']] +``` + +### Versioning + +Create a new version of an existing prompt: + +```bash +php artisan make:prompt order-summary +# Automatically creates v2, v3, etc. +``` + +Activate a specific version: + +```bash +php artisan prompt:activate order-summary v2 +``` + +Or load a specific version programmatically: + +```php +$prompt = PromptDeck::get('order-summary', 'v2'); +``` + +### Laravel AI SDK integration + +If you use the [Laravel AI SDK](https://laravel.com/docs/ai-sdk), add the `HasPromptTemplate` trait to your agents. This way, you do not need to define the `instructions()` method as it is provided automatically. + +```php +use Veeqtoh\PromptDeck\Concerns\HasPromptTemplate; + +class OrderAgent extends Agent +{ + use HasPromptTemplate; + + // instructions() and promptMessages() are provided automatically +} +``` + +Running `make:agent` will also auto-scaffold a matching prompt directory. + +## Key features + + + + Store prompts as files on disk with directory-based versioning. Load, + render, and switch between versions effortlessly. + + + Scaffold versioned, role-based prompt structures with the `make:prompt` + Artisan command. + + + Use `{{ $variable }}` syntax in prompt templates for dynamic content + rendering. + + + Convert prompts to messages arrays ready for OpenAI, Anthropic, and + other chat-completion APIs. + + + First-class integration with Laravel AI SDK — auto-scaffolding, traits, + and middleware. + + + Log executions with token usage, latency, cost, and feedback for A/B + testing and monitoring. + + + +## Explore the docs + + + + Customise caching, tracking, and file settings. + + + Five commands for managing prompts from the CLI. + + + Strategies and examples for testing prompts. + + diff --git a/docs/images/checks-passed.png b/docs/images/checks-passed.png new file mode 100644 index 0000000..3303c77 Binary files /dev/null and b/docs/images/checks-passed.png differ diff --git a/docs/images/hero-dark.png b/docs/images/hero-dark.png new file mode 100644 index 0000000..a61cbb1 Binary files /dev/null and b/docs/images/hero-dark.png differ diff --git a/docs/images/hero-light.png b/docs/images/hero-light.png new file mode 100644 index 0000000..68c712d Binary files /dev/null and b/docs/images/hero-light.png differ diff --git a/docs/index.mdx b/docs/index.mdx new file mode 100644 index 0000000..d92452d --- /dev/null +++ b/docs/index.mdx @@ -0,0 +1,118 @@ +--- +title: "Welcome" +description: Organize, version, and test your AI agent instructions with Prompt Deck, a powerful Laravel package for seamless AI integration. +mode: "custom" +--- + +{/* Top Accent Glow Effect */} +
+ +
+ {/* Hero Section */} +
+ {/*
+ ✨ Now available for Laravel 11+ +
*/} + +

+ Prompt Deck +

+ +

+ Organise your AI Agent instructions as structured, version-controlled files in your Laravel application. +

+ +
+ + Get Started +
+ + + GitHub + +
+
+
+ +{/* Main Layout Wrapper */} +
+ + {/* Interactive Feature Grid */} +
+ + {/* Card 1 */} +
+
📁
+

Versioned Prompts

+

Organise instructions as versioned markdown structures directly inside your source control repository.

+
+ + {/* Card 2 */} +
+
🔄
+

Interpolation

+

Inject application state instantly into your system prompts using clean, readable syntax at execution runtime.

+
+ + {/* Card 3 */} +
+
📊
+

A/B Testing

+

Route LLM flows between different prompt iterations to track metrics and evaluate response consistency.

+
+ + {/* Card 4 */} +
+
💻
+

Artisan Scaffold

+

Generate directories, active config variants, and markdown code structures quickly with command-line tooling.

+
+ + {/* Card 5 */} +
+
📈
+

Performance logs

+

Log historical execution speed and prompt token payloads inside internal metrics pipelines seamlessly.

+
+ + {/* Card 6 */} +
+
🔌
+

AI SDK Native

+

Uses trait mappings designed to natively inject files into Laravel AI SDK setups automatically.

+
+
+ + {/* Interactive Code Preview Block */} +
+
+ +
+

Beautifully simple implementation

+

Manage file configurations via artisan and load compilation states natively into your codebases.

+
+ + + ```bash Artisan Command + # Generate a versioned system prompt template + php artisan make:prompt order-summary + ``` + + ```markdown Prompt File (v1/system.md) + You are a {{ $tone }} customer service agent. + Summarise the following order details: {{ $order }}. + ``` + + ```php Implementation (Controller) + use Veeqtoh\PromptDeck\Facades\PromptDeck; + + // Loads active markdown context and returns compiled payload arrays + $messages = PromptDeck::get('order-summary') + ->toMessages([ + 'tone' => 'friendly', + 'order' => $orderDetails + ]); + ``` + +
+
diff --git a/docs/ai-sdk.md b/docs/integrations/ai-sdk.mdx similarity index 65% rename from docs/ai-sdk.md rename to docs/integrations/ai-sdk.mdx index 7d2ffd1..d170ac5 100644 --- a/docs/ai-sdk.md +++ b/docs/integrations/ai-sdk.mdx @@ -1,34 +1,9 @@ -# Laravel AI SDK Integration - -- [Introduction](#introduction) -- [Installation](#installation) -- [Automatic Prompt Scaffolding](#automatic-prompt-scaffolding) - - [How It Works](#how-scaffolding-works) - - [Example Output](#example-output) - - [Disabling Auto-Scaffolding](#disabling-auto-scaffolding) -- [Quick Start](#quick-start) -- [The HasPromptTemplate Trait](#the-hasprompttemplate-trait) - - [How It Maps to AI SDK Contracts](#how-it-maps) - - [Mapping Diagram](#mapping-diagram) -- [Customising the Prompt](#customising-the-prompt) - - [Prompt Name](#prompt-name) - - [Pinning a Version](#pinning-a-version) - - [Variable Interpolation](#variable-interpolation) -- [Full Agent Example](#full-agent-example) -- [Conversation Context](#conversation-context) - - [Loading All Non-System Roles](#loading-all-non-system-roles) - - [Limiting to Specific Roles](#limiting-to-specific-roles) - - [Merging with Database History](#merging-with-database-history) -- [Performance Tracking Middleware](#performance-tracking-middleware) - - [Setting Up the Middleware](#setting-up-the-middleware) - - [What Gets Tracked](#what-gets-tracked) - - [How It Works Internally](#how-middleware-works) -- [Accessing the Template Directly](#accessing-the-template-directly) -- [Clearing the Cached Template](#clearing-the-cached-template) -- [Without the AI SDK](#without-the-ai-sdk) -- [API Reference](#api-reference) - - +--- +title: "Laravel AI SDK integration" +description: "Use Prompt Deck with Laravel AI SDK agents for automatic prompt loading, version tracking, and performance monitoring." +sidebarTitle: "Laravel AI SDK" +--- + ## Introduction Prompt Deck provides first-class, optional integration with the [Laravel AI SDK](https://laravel.com/docs/ai-sdk). When the AI SDK is installed, you get: @@ -39,7 +14,6 @@ Prompt Deck provides first-class, optional integration with the [Laravel AI SDK] All of this is entirely optional. Prompt Deck works perfectly without the AI SDK. - ## Installation Prompt Deck does **not** require the AI SDK — it's listed as a `suggest` dependency. Install it when you're ready: @@ -50,8 +24,7 @@ composer require laravel/ai Once `laravel/ai` is installed, Prompt Deck's AI SDK features activate automatically. No additional configuration is needed. - -## Automatic Prompt Scaffolding +## Automatic prompt scaffolding When the Laravel AI SDK is installed, Prompt Deck automatically hooks into the `make:agent` command. Whenever you create a new agent: @@ -67,8 +40,7 @@ php artisan make:prompt sales-coach This creates a versioned prompt directory ready for the agent to use via the `HasPromptTemplate` trait — zero extra setup required. - -### How It Works +### How it works Prompt Deck registers a listener (`AfterMakeAgent`) on Laravel's `CommandFinished` event. When `make:agent` completes successfully, the listener: @@ -80,8 +52,7 @@ Prompt Deck registers a listener (`AfterMakeAgent`) on Laravel's `CommandFinishe The listener is only registered when `laravel/ai` is installed. If the prompt creation fails for any reason, it does **not** break the `make:agent` workflow — the agent is still created successfully. - -### Example Output +### Example output ``` $ php artisan make:agent SalesCoach @@ -91,8 +62,7 @@ $ php artisan make:agent SalesCoach PromptDeck: Created prompt sales-coach for SalesCoach. ``` - -### Disabling Auto-Scaffolding +### Disabling auto-scaffolding To disable automatic prompt scaffolding, set the configuration option: @@ -107,8 +77,7 @@ Or via environment variable: PROMPTDECK_SCAFFOLD_ON_MAKE_AGENT=false ``` - -## Quick Start +## Quick start Use the `HasPromptTemplate` trait on any agent class: @@ -132,30 +101,27 @@ class SalesCoach implements Agent That's it. The `HasPromptTemplate` trait provides the `instructions()` method required by the `Agent` contract, loading the system prompt from your Prompt Deck files. - -## The HasPromptTemplate Trait +## The HasPromptTemplate trait The `HasPromptTemplate` trait bridges Prompt Deck's file-based templates with the Laravel AI SDK's agent contracts. - -### How It Maps to AI SDK Contracts +### How it maps to AI SDK contracts -| Prompt Deck | AI SDK | Description | -|---|---|---| -| `system.md` role file | `instructions()` | Agent's system prompt. | -| `user.md`, `assistant.md`, etc. | `messages()` via `promptMessages()` | Conversation context. | -| `metadata.json` | — | Prompt metadata (description, variables, etc.). | -| `v1/`, `v2/`, etc. | — | Version management. | +| Prompt Deck | AI SDK | Description | +| ------------------------------- | ----------------------------------- | ----------------------------------------------- | +| `system.md` role file | `instructions()` | Agent's system prompt. | +| `user.md`, `assistant.md`, etc. | `messages()` via `promptMessages()` | Conversation context. | +| `metadata.json` | — | Prompt metadata (description, variables, etc.). | +| `v1/`, `v2/`, etc. | — | Version management. | - -### Mapping Diagram +### Mapping diagram ``` prompts/sales-coach/ ├── v1/ -│ ├── system.md → instructions() -│ ├── user.md → promptMessages() -│ └── metadata.json + ├── system.md → instructions() + ├── user.md → promptMessages() + └── metadata.json └── v2/ ├── system.md → instructions() (active version) ├── user.md → promptMessages() @@ -163,11 +129,9 @@ prompts/sales-coach/ └── metadata.json ``` - -## Customising the Prompt +## Customising the prompt - -### Prompt Name +### Prompt name By default, the prompt name is derived from the class name in kebab-case: @@ -188,8 +152,7 @@ class SalesCoach implements Agent } ``` - -### Pinning a Version +### Pinning a version By default, the active version is loaded. Pin to a specific version by overriding `promptVersion()`: @@ -202,8 +165,7 @@ public function promptVersion(): ?int Return `null` (the default) to always load the active version — useful for A/B testing and gradual rollouts. - -### Variable Interpolation +### Variable interpolation Pass dynamic values into your prompt templates by overriding `promptVariables()`: @@ -233,8 +195,7 @@ You are helping {{ $user_name }} improve their technique. Variables are interpolated into **all** roles (system, user, assistant, etc.) when accessed via `instructions()` or `promptMessages()`. - -## Full Agent Example +## Full agent example Here's a complete agent using all Prompt Deck features with the AI SDK: @@ -328,17 +289,16 @@ You are a sales coach for {{ $company }}. You are helping {{ $user_name }} improve their sales technique. Analyse transcripts carefully and provide: + - Specific, actionable feedback - A score from 1-10 ``` - -## Conversation Context +## Conversation context If your agent implements `Conversational`, you can load pre-defined conversation context from Prompt Deck role files using the `promptMessages()` method. - -### Loading All Non-System Roles +### Loading all non-system roles By default, `promptMessages()` returns all roles **except** `system` (which goes through `instructions()`): @@ -350,8 +310,7 @@ public function messages(): iterable } ``` - -### Limiting to Specific Roles +### Limiting to specific roles Pass an array to limit which roles are included: @@ -362,8 +321,7 @@ public function messages(): iterable } ``` - -### Merging with Database History +### Merging with database history Combine template messages with conversation history from your database: @@ -388,70 +346,70 @@ public function messages(): iterable } ``` - -## Performance Tracking Middleware +## Performance tracking middleware The `TrackPromptMiddleware` automatically records prompt executions via Prompt Deck's tracking system. - -### Setting Up the Middleware - -1. **Enable tracking** in your configuration: - -```php -// config/prompt-deck.php -'tracking' => [ - 'enabled' => true, - 'connection' => null, // uses default database connection -], -``` - -2. **Publish and run the migrations** (if you haven't already): - -```bash -php artisan vendor:publish --tag=prompt-deck-migrations -php artisan migrate -``` - -3. **Add the middleware** to your agent: - -```php -use Laravel\Ai\Contracts\HasMiddleware; -use Veeqtoh\PromptDeck\Ai\TrackPromptMiddleware; - -class SalesCoach implements Agent, HasMiddleware -{ - use Promptable, HasPromptTemplate; - - public function middleware(): array +### Setting up the middleware + + + + Set the tracking configuration in `config/prompt-deck.php`: + + ```php + 'tracking' => [ + 'enabled' => true, + 'connection' => null, // uses default database connection + ], + ``` + + + + ```bash + php artisan vendor:publish --tag=prompt-deck-migrations + php artisan migrate + ``` + + + ```php + use Laravel\Ai\Contracts\HasMiddleware; + use Veeqtoh\PromptDeck\Ai\TrackPromptMiddleware; + + class SalesCoach implements Agent, HasMiddleware { - return [ - new TrackPromptMiddleware, - ]; + use Promptable, HasPromptTemplate; + + public function middleware(): array + { + return [ + new TrackPromptMiddleware, + ]; + } } -} -``` + ``` + + + - -### What Gets Tracked +### What gets tracked The middleware automatically records the following fields to the `prompt_executions` table: -| Field | Source | -|---|---| -| `prompt_name` | Agent's `promptName()` method. | -| `prompt_version` | Resolved template version number. | -| `input` | The user's prompt text from the `AgentPrompt`. | -| `output` | The AI response text. | -| `tokens` | Total token usage from the response. | -| `latency_ms` | Round-trip time in milliseconds (measured via `hrtime`). | -| `model` | Model used (e.g. `gpt-4o`, `claude-3-sonnet`). | -| `provider` | Provider name (e.g. `openai`, `anthropic`). | +| Field | Source | +| ---------------- | -------------------------------------------------------- | +| `prompt_name` | Agent's `promptName()` method. | +| `prompt_version` | Resolved template version number. | +| `input` | The user's prompt text from the `AgentPrompt`. | +| `output` | The AI response text. | +| `tokens` | Total token usage from the response. | +| `latency_ms` | Round-trip time in milliseconds (measured via `hrtime`). | +| `model` | Model used (e.g. `gpt-4o`, `claude-3-sonnet`). | +| `provider` | Provider name (e.g. `openai`, `anthropic`). | - -### How It Works Internally +### How it works internally The middleware: + 1. Records the start time before the request using `hrtime(true)`. 2. Passes the prompt to the next middleware in the pipeline. 3. Uses the response's `then()` hook to record execution data after the response completes. @@ -459,8 +417,7 @@ The middleware: The middleware only tracks agents that use the `HasPromptTemplate` trait. If the agent doesn't have a `promptName()` method, the tracking is silently skipped. - -## Accessing the Template Directly +## Accessing the template directly You can access the full `PromptTemplate` object from within your agent for advanced use cases: @@ -484,8 +441,7 @@ $template->metadata(); // ['description' => '...', ...] The template instance is cached for the lifetime of the agent object, so repeated calls to `promptTemplate()` don't incur additional filesystem or cache lookups. - -## Clearing the Cached Template +## Clearing the cached template Clear the cached template to force a fresh load on next access: @@ -494,6 +450,7 @@ $agent->forgetPromptTemplate(); ``` This is useful in: + - **Long-running processes** (queue workers, daemons) where prompts might change between jobs. - **Tests** where you switch prompt versions between assertions. @@ -503,7 +460,6 @@ The method returns `$this` for fluent chaining: $agent->forgetPromptTemplate()->promptTemplate(); // fresh load ``` - ## Without the AI SDK The `HasPromptTemplate` trait works even without `laravel/ai` installed. The `instructions()` method simply returns a string, and `promptMessages()` falls back to returning raw arrays instead of AI SDK `Message` objects: @@ -519,30 +475,3 @@ $messages = $agent->promptMessages(); ``` This allows you to use Prompt Deck's template loading in any context, not just with the AI SDK. - - -## API Reference - -### HasPromptTemplate Trait - -| Method | Returns | Description | -|---|---|---| -| `promptName()` | `string` | Prompt name (default: kebab-cased class name). | -| `promptVersion()` | `?int` | Version to load (`null` = active). | -| `promptVariables()` | `array` | Variables for interpolation. | -| `promptTemplate()` | `PromptTemplate` | The loaded template (cached per instance). | -| `instructions()` | `Stringable\|string` | System role content (satisfies `Agent` contract). | -| `promptMessages(?array $only)` | `array` | Non-system roles as `Message` objects (or raw arrays). | -| `forgetPromptTemplate()` | `static` | Clear the cached template. | - -### TrackPromptMiddleware - -| Method | Description | -|---|---| -| `handle($prompt, $next)` | Wraps the agent call, measures latency, and records execution data via `PromptManager::track()`. | - -### AfterMakeAgent Listener - -| Method | Description | -|---|---| -| `handle(CommandFinished $event)` | Detects `make:agent` completion and scaffolds a matching prompt. | diff --git a/docs/logo/dark.svg b/docs/logo/dark.svg new file mode 100644 index 0000000..8b343cd --- /dev/null +++ b/docs/logo/dark.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/logo/light.svg b/docs/logo/light.svg new file mode 100644 index 0000000..03e62bf --- /dev/null +++ b/docs/logo/light.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/public/logo.svg b/docs/logo/logo.svg similarity index 100% rename from docs/public/logo.svg rename to docs/logo/logo.svg