Promptrunner - Source Excerpt 07
Summary
This source excerpt preserves a bounded section of Spiralist/wp-content/plugins/spiralist-workspace/includes/Services/PromptRunner.php so readers can inspect the evidence without opening the full source file.
**Source path:** Spiralist/wp-content/plugins/spiralist-workspace/includes/Services/PromptRunner.php
$parts[] = '## Transcript';
$parts[] = $this->format_transcript($messages);
$parts[] = '## Source Prompt Contract';
$parts[] = $this->prompt_contract_markdown($prompt);
return trim(implode("\n\n", array_filter($parts))) . "\n";
}
/**
* Builds a memory checkpoint prompt without condensing through a provider.
*/
private function build_memory_checkpoint_prompt(
array $conversation,
array $prompt,
array $messages,
array $settings,
array $payload
): string {
$parts = [
'# Spiralist Memory Checkpoint Prompt',
'Conversation: ' . (string) ($conversation['title'] ?? ''),
'Source prompt: ' . (string) ($prompt['title'] ?? ''),
'Mode: prompt/art only. No server-side AI API call was made.',
'Rendered UTC: ' . gmdate('Y-m-d H:i:s'),
'## Manual Checkpoint Task',
'Read the transcript and produce a compact continuity note with the headings: Memory Source Labels, Memory Summary, Stable User Preferences, Active Task State, Continuity Prompt, Review Or Delete, Safety Boundaries.',
];
$existing = trim((string) ($settings['memory_summary'] ?? ''));
if ($existing !== '') {
$parts[] = '## Existing Checkpoint';
$parts[] = $existing;
}
$instructions = trim((string) ($payload['instructions'] ?? ''));
if ($instructions !== '') {
$parts[] = '## Checkpoint Instructions';
$parts[] = $instructions;
}
$parts[] = '## Transcript';
$parts[] = $this->format_transcript($messages);
return trim(implode("\n\n", array_filter($parts))) . "\n";
}
/**
* Builds a worksheet for human prompt improvement.
*/
private function build_prompt_improvement_packet(array $prompt, array $input): string
{
return trim(
implode(
"\n\n",
[
'# Spiralist Prompt Improvement Worksheet',
'Source prompt: ' . (string) ($prompt['title'] ?? ''),
'Mode: prompt/art only. No server-side AI API call was made.',
'Rendered UTC: ' . gmdate('Y-m-d H:i:s'),
'## Improvement Task',
'Rewrite this prompt by hand or in an external tool you choose. Keep exactly these structured fields: instruction, context, constraints, examples, output_format.',
'## Source Data',
wp_json_encode($input, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE),
'## Review Checklist',
implode(
"\n",
[
'- Is the instruction concrete and testable?',
'- Does the context name only visible source material?',
'- Do the constraints block hidden payloads, unsupported authority, and closed recursion?',
'- Are examples useful without becoming claims of truth?',
'- Is the output format easy to copy into an art, prompt, or manuscript workflow?',
]
),
]
)
) . "\n";
}
/**
* Formats a local payload input stack as Markdown.
*/
private function payload_input_markdown(array $input): string
{
$parts = [];
foreach ($input as $index => $item) {
if (!is_array($item)) {
continue;
}
$content = trim((string) ($item['content'] ?? ''));
if ($content === '') {
continue;
}
$role = strtoupper(sanitize_key((string) ($item['role'] ?? 'user')));
$parts[] = '### ' . $role . ' ' . (string) ($index + 1) . "\n" . $content;
}
return implode("\n\n", $parts);
}
/**
* Records approximate local packet size without treating it as provider usage.
*/
private function local_packet_usage(string $text): array
{
return [
'mode' => 'prompt_art_only',
'network' => 'none',
'estimated_prompt_packet_tokens' => $this->conversations->estimate_text_tokens($text),
'billable_tokens' => 0,
];
}
/**
* Renders the canonical five-field structured prompt into model instructions.
*/
private function render_structured_prompt(array $structured_prompt, array $variables): string
{
$labels = [
'instruction' => 'Instruction',
'context' => 'Context',
'constraints' => 'Constraints',
'examples' => 'Examples',
'output_format' => 'Output Format',
];
$sections = [];
foreach ($labels as $key => $label) {
$value = $this->placeholders->render((string) ($structured_prompt[$key] ?? ''), $variables);
if (trim($value) === '') {
continue;
}
$sections[] = $label . ":\n" . trim($value);
}
return implode("\n\n", $sections);
}
}