Created
May 28, 2025 12:30
-
-
Save tkersey/2746c93d7edcc00eefbbe63f3517ba6b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Deep Dive: Prompts as Delimited Continuations in TypeScript | |
// ============================================================================= | |
// 1. PROMPTS AS INITIAL CONTINUATIONS | |
// ============================================================================= | |
/** | |
* Prompts as Initial Continuations treats the prompt itself as the starting | |
* continuation that establishes the computational context. The prompt becomes | |
* a first-class continuation that can be captured, modified, and resumed. | |
*/ | |
// Core types for prompt continuations | |
type PromptContinuation<T> = { | |
id: string; | |
content: string; | |
parameters: Map<string, any>; | |
resume: (value: T) => Promise<any>; | |
abort: (reason: string) => void; | |
}; | |
type PromptFrame = { | |
prompt: string; | |
bindings: Map<string, any>; | |
parent?: PromptFrame; | |
}; | |
class PromptAsInitialContinuation { | |
private prompts: Map<string, PromptContinuation<any>> = new Map(); | |
private executionStack: PromptFrame[] = []; | |
/** | |
* Create a prompt as an initial continuation that sets up the computation context | |
*/ | |
async createPromptContinuation<T>( | |
prompt: string, | |
parameters: Record<string, any> = {} | |
): Promise<PromptContinuation<T>> { | |
const promptId = `prompt-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; | |
// Parse prompt to extract continuation points | |
const continuationPoints = this.extractContinuationPoints(prompt); | |
// Create the initial continuation | |
const continuation = await new Promise<PromptContinuation<T>>((resolve) => { | |
const promptCont: PromptContinuation<T> = { | |
id: promptId, | |
content: prompt, | |
parameters: new Map(Object.entries(parameters)), | |
resume: async (value: T) => { | |
// Push prompt frame onto execution stack | |
this.executionStack.push({ | |
prompt: prompt, | |
bindings: new Map([...promptCont.parameters, ['__result__', value]]), | |
parent: this.executionStack[this.executionStack.length - 1] | |
}); | |
// Execute prompt with continuation semantics | |
return await this.executePromptContinuation(promptCont, value); | |
}, | |
abort: (reason: string) => { | |
console.log(`Prompt continuation ${promptId} aborted: ${reason}`); | |
this.prompts.delete(promptId); | |
} | |
}; | |
this.prompts.set(promptId, promptCont); | |
resolve(promptCont); | |
}); | |
return continuation; | |
} | |
/** | |
* Execute a prompt continuation with proper delimited continuation semantics | |
*/ | |
private async executePromptContinuation<T>( | |
continuation: PromptContinuation<T>, | |
input: T | |
): Promise<any> { | |
// Create execution context | |
const context = { | |
input, | |
parameters: continuation.parameters, | |
stack: [...this.executionStack], | |
// Shift operation - capture current continuation | |
shift: async <R>(fn: (k: (value: R) => Promise<any>) => Promise<any>) => { | |
const currentFrame = this.executionStack[this.executionStack.length - 1]; | |
const capturedContinuation = (value: R) => { | |
// Restore stack frame and continue | |
this.executionStack.push(currentFrame); | |
return this.continueExecution(value); | |
}; | |
return await fn(capturedContinuation); | |
}, | |
// Reset operation - delimit continuation boundary | |
reset: async <R>(computation: () => Promise<R>) => { | |
const savedStack = [...this.executionStack]; | |
try { | |
return await computation(); | |
} finally { | |
this.executionStack = savedStack; | |
} | |
} | |
}; | |
// Process prompt template with continuation semantics | |
const processedPrompt = await this.processPromptTemplate( | |
continuation.content, | |
context | |
); | |
// Execute the processed prompt | |
return await this.executeProcessedPrompt(processedPrompt, context); | |
} | |
/** | |
* Extract continuation points from prompt template | |
*/ | |
private extractContinuationPoints(prompt: string): string[] { | |
const continuationPattern = /\{\{#continuation\s+(\w+)\}\}(.*?)\{\{\/continuation\}\}/gs; | |
const points: string[] = []; | |
let match; | |
while ((match = continuationPattern.exec(prompt)) !== null) { | |
points.push(match[1]); | |
} | |
return points; | |
} | |
/** | |
* Process prompt template with continuation context | |
*/ | |
private async processPromptTemplate( | |
template: string, | |
context: any | |
): Promise<string> { | |
// Replace continuation points | |
let processed = template; | |
// Handle continuation blocks | |
processed = processed.replace( | |
/\{\{#continuation\s+(\w+)\}\}(.*?)\{\{\/continuation\}\}/gs, | |
(match, name, content) => { | |
// Save continuation point for potential capture | |
context[`continuation_${name}`] = async () => { | |
return await context.reset(async () => { | |
return await this.processPromptTemplate(content, context); | |
}); | |
}; | |
return `[Continuation point: ${name}]`; | |
} | |
); | |
// Handle parameter substitution | |
for (const [key, value] of context.parameters) { | |
processed = processed.replace( | |
new RegExp(`\\{\\{${key}\\}\\}`, 'g'), | |
String(value) | |
); | |
} | |
// Handle shift/reset operations | |
processed = processed.replace( | |
/\{\{#shift\}\}(.*?)\{\{\/shift\}\}/gs, | |
async (match, content) => { | |
return await context.shift(async (k: any) => { | |
const result = await this.processPromptTemplate(content, context); | |
return k(result); | |
}); | |
} | |
); | |
return processed; | |
} | |
/** | |
* Continue execution from a captured point | |
*/ | |
private async continueExecution<T>(value: T): Promise<any> { | |
const currentFrame = this.executionStack[this.executionStack.length - 1]; | |
if (!currentFrame) { | |
throw new Error("No execution frame to continue"); | |
} | |
// Update bindings with continuation value | |
currentFrame.bindings.set('__continuation_value__', value); | |
// Re-process the prompt with updated context | |
const context = { | |
input: value, | |
parameters: currentFrame.bindings, | |
stack: this.executionStack | |
}; | |
return await this.processPromptTemplate(currentFrame.prompt, context); | |
} | |
/** | |
* Execute the final processed prompt | |
*/ | |
private async executeProcessedPrompt(prompt: string, context: any): Promise<any> { | |
// Simulate LLM execution with continuation awareness | |
console.log("Executing prompt:", prompt); | |
console.log("With context:", { | |
parameters: Array.from(context.parameters.entries()), | |
stackDepth: context.stack.length | |
}); | |
// Return simulated response | |
return { | |
response: `Processed: ${prompt}`, | |
continuations: Object.keys(context) | |
.filter(k => k.startsWith('continuation_')) | |
.map(k => k.replace('continuation_', '')) | |
}; | |
} | |
/** | |
* Compose multiple prompts as continuations | |
*/ | |
async composePrompts( | |
prompts: Array<{template: string, parameters: Record<string, any>}> | |
): Promise<any> { | |
let result: any = null; | |
// Create continuation chain | |
for (let i = prompts.length - 1; i >= 0; i--) { | |
const prompt = prompts[i]; | |
const continuation = await this.createPromptContinuation( | |
prompt.template, | |
prompt.parameters | |
); | |
if (i === prompts.length - 1) { | |
// Last prompt - base case | |
result = continuation; | |
} else { | |
// Compose with previous continuation | |
const previousResult = result; | |
result = { | |
...continuation, | |
resume: async (value: any) => { | |
const intermediateResult = await continuation.resume(value); | |
return await previousResult.resume(intermediateResult); | |
} | |
}; | |
} | |
} | |
return result; | |
} | |
} | |
// Example usage of Prompts as Initial Continuations | |
async function demonstratePromptsAsInitialContinuations() { | |
const system = new PromptAsInitialContinuation(); | |
// Create a prompt with continuation points | |
const analysisPrompt = await system.createPromptContinuation<string>(` | |
Analyze the following text: {{input}} | |
{{#continuation summary}} | |
First, provide a brief summary of the main points. | |
{{/continuation}} | |
{{#continuation details}} | |
Then, dive into detailed analysis considering: | |
- Context: {{context}} | |
- Perspective: {{perspective}} | |
{{/continuation}} | |
{{#shift}} | |
If ambiguity is detected, pause and request clarification. | |
{{/shift}} | |
`, { | |
context: "technical analysis", | |
perspective: "engineering" | |
}); | |
// Execute the prompt continuation | |
const result = await analysisPrompt.resume( | |
"Delimited continuations provide powerful control flow mechanisms..." | |
); | |
console.log("Analysis result:", result); | |
// Compose multiple prompts | |
const composedContinuation = await system.composePrompts([ | |
{ | |
template: "Extract key concepts from: {{input}}", | |
parameters: {} | |
}, | |
{ | |
template: "Organize concepts into categories: {{__result__}}", | |
parameters: {} | |
}, | |
{ | |
template: "Generate summary based on categories: {{__result__}}", | |
parameters: {} | |
} | |
]); | |
const composedResult = await composedContinuation.resume( | |
"Complex text about AI architectures..." | |
); | |
console.log("Composed result:", composedResult); | |
} | |
// ============================================================================= | |
// 2. DYNAMIC PROMPT WEAVING | |
// ============================================================================= | |
/** | |
* Dynamic Prompt Weaving allows prompts to be dynamically composed and | |
* modified during execution based on runtime conditions and captured | |
* continuations. | |
*/ | |
interface WeavingContext { | |
threads: Map<string, PromptThread>; | |
activeThread: string | null; | |
suspendedThreads: Set<string>; | |
sharedState: Map<string, any>; | |
} | |
interface PromptThread { | |
id: string; | |
prompt: string; | |
priority: number; | |
dependencies: Set<string>; | |
continuation?: (value: any) => Promise<any>; | |
state: 'ready' | 'running' | 'suspended' | 'completed'; | |
} | |
class DynamicPromptWeaver { | |
private context: WeavingContext = { | |
threads: new Map(), | |
activeThread: null, | |
suspendedThreads: new Set(), | |
sharedState: new Map() | |
}; | |
/** | |
* Create a new prompt thread that can be woven with others | |
*/ | |
createThread( | |
prompt: string, | |
options: { | |
priority?: number; | |
dependencies?: string[]; | |
parameters?: Record<string, any>; | |
} = {} | |
): PromptThread { | |
const threadId = `thread-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; | |
const thread: PromptThread = { | |
id: threadId, | |
prompt: prompt, | |
priority: options.priority || 0, | |
dependencies: new Set(options.dependencies || []), | |
state: 'ready' | |
}; | |
// Initialize thread parameters in shared state | |
if (options.parameters) { | |
for (const [key, value] of Object.entries(options.parameters)) { | |
this.context.sharedState.set(`${threadId}.${key}`, value); | |
} | |
} | |
this.context.threads.set(threadId, thread); | |
return thread; | |
} | |
/** | |
* Weave multiple prompt threads together dynamically | |
*/ | |
async weaveThreads( | |
threads: PromptThread[], | |
weavingStrategy: 'parallel' | 'sequential' | 'priority' | 'adaptive' = 'adaptive' | |
): Promise<Map<string, any>> { | |
const results = new Map<string, any>(); | |
switch (weavingStrategy) { | |
case 'parallel': | |
return await this.weaveParallel(threads); | |
case 'sequential': | |
return await this.weaveSequential(threads); | |
case 'priority': | |
return await this.weavePriority(threads); | |
case 'adaptive': | |
return await this.weaveAdaptive(threads); | |
default: | |
throw new Error(`Unknown weaving strategy: ${weavingStrategy}`); | |
} | |
} | |
/** | |
* Adaptive weaving - dynamically adjusts based on runtime conditions | |
*/ | |
private async weaveAdaptive(threads: PromptThread[]): Promise<Map<string, any>> { | |
const results = new Map<string, any>(); | |
const readyQueue: PromptThread[] = [...threads]; | |
const runningThreads = new Set<string>(); | |
while (readyQueue.length > 0 || runningThreads.size > 0) { | |
// Check for threads ready to run | |
const executableThreads = readyQueue.filter(thread => | |
this.canExecuteThread(thread, results) | |
); | |
if (executableThreads.length === 0 && runningThreads.size === 0) { | |
throw new Error("Deadlock detected - circular dependencies"); | |
} | |
// Execute threads with dynamic interleaving | |
for (const thread of executableThreads) { | |
// Remove from ready queue | |
const index = readyQueue.indexOf(thread); | |
readyQueue.splice(index, 1); | |
// Start thread execution with continuation capture | |
runningThreads.add(thread.id); | |
thread.state = 'running'; | |
// Execute with continuation semantics | |
this.executeThreadWithContinuation(thread).then(result => { | |
results.set(thread.id, result); | |
runningThreads.delete(thread.id); | |
thread.state = 'completed'; | |
// Wake up dependent threads | |
this.wakeupDependentThreads(thread.id); | |
}).catch(error => { | |
// Handle thread failure | |
console.error(`Thread ${thread.id} failed:`, error); | |
runningThreads.delete(thread.id); | |
thread.state = 'suspended'; | |
this.context.suspendedThreads.add(thread.id); | |
}); | |
// Check for dynamic conditions that might affect weaving | |
if (await this.shouldAdjustWeaving(thread, executableThreads)) { | |
await this.adjustWeavingStrategy(thread, readyQueue); | |
} | |
} | |
// Allow some execution before next iteration | |
await new Promise(resolve => setTimeout(resolve, 10)); | |
} | |
return results; | |
} | |
/** | |
* Execute a thread with continuation capture for dynamic weaving | |
*/ | |
private async executeThreadWithContinuation(thread: PromptThread): Promise<any> { | |
const self = this; | |
// Create execution context with weaving operations | |
const weavingContext = { | |
threadId: thread.id, | |
// Suspend current thread and switch to another | |
suspend: async function<T>(reason?: string): Promise<T> { | |
return new Promise((resolve) => { | |
thread.continuation = resolve; | |
thread.state = 'suspended'; | |
self.context.suspendedThreads.add(thread.id); | |
console.log(`Thread ${thread.id} suspended: ${reason || 'unknown'}`); | |
}); | |
}, | |
// Yield control to scheduler | |
yield: async function(): Promise<void> { | |
await new Promise(resolve => setTimeout(resolve, 0)); | |
}, | |
// Fork a new thread dynamically | |
fork: function(prompt: string, parameters?: Record<string, any>): PromptThread { | |
const forkedThread = self.createThread(prompt, { | |
priority: thread.priority - 1, | |
parameters | |
}); | |
// Add to execution queue | |
self.scheduleThread(forkedThread); | |
return forkedThread; | |
}, | |
// Join with another thread | |
join: async function(threadId: string): Promise<any> { | |
const targetThread = self.context.threads.get(threadId); | |
if (!targetThread) { | |
throw new Error(`Thread ${threadId} not found`); | |
} | |
// Wait for thread completion | |
while (targetThread.state !== 'completed') { | |
await weavingContext.yield(); | |
} | |
return self.getThreadResult(threadId); | |
}, | |
// Access shared state | |
get: function(key: string): any { | |
return self.context.sharedState.get(key); | |
}, | |
set: function(key: string, value: any): void { | |
self.context.sharedState.set(key, value); | |
}, | |
// Dynamically modify prompt based on context | |
weave: function(modification: string): string { | |
const currentPrompt = thread.prompt; | |
const weavingPoint = currentPrompt.indexOf('{{weave}}'); | |
if (weavingPoint !== -1) { | |
return currentPrompt.substring(0, weavingPoint) + | |
modification + | |
currentPrompt.substring(weavingPoint + 9); | |
} | |
return currentPrompt + '\n' + modification; | |
} | |
}; | |
// Process prompt with weaving context | |
const processedPrompt = await this.processPromptWithWeaving( | |
thread.prompt, | |
weavingContext | |
); | |
// Execute the woven prompt | |
return await this.executeWovenPrompt(processedPrompt, weavingContext); | |
} | |
/** | |
* Process prompt with dynamic weaving operations | |
*/ | |
private async processPromptWithWeaving( | |
prompt: string, | |
context: any | |
): Promise<string> { | |
let processed = prompt; | |
// Handle dynamic weaving points | |
processed = processed.replace( | |
/\{\{weave:(\w+)\}\}/g, | |
(match, weavingType) => { | |
switch (weavingType) { | |
case 'context': | |
// Weave in current context | |
return `[Current context: Thread ${context.threadId}]`; | |
case 'dependencies': | |
// Weave in dependency information | |
const thread = this.context.threads.get(context.threadId)!; | |
return `[Dependencies: ${Array.from(thread.dependencies).join(', ')}]`; | |
case 'state': | |
// Weave in shared state | |
const relevantState = Array.from(this.context.sharedState.entries()) | |
.filter(([k, v]) => k.startsWith(context.threadId)) | |
.map(([k, v]) => `${k}=${v}`) | |
.join(', '); | |
return `[State: ${relevantState}]`; | |
default: | |
return match; | |
} | |
} | |
); | |
// Handle conditional weaving | |
processed = await this.processConditionalWeaving(processed, context); | |
return processed; | |
} | |
/** | |
* Process conditional weaving based on runtime conditions | |
*/ | |
private async processConditionalWeaving( | |
prompt: string, | |
context: any | |
): Promise<string> { | |
const conditionalPattern = /\{\{#if\s+(\w+)\}\}(.*?)\{\{else\}\}(.*?)\{\{\/if\}\}/gs; | |
let processed = prompt; | |
let match; | |
while ((match = conditionalPattern.exec(prompt)) !== null) { | |
const [fullMatch, condition, ifContent, elseContent] = match; | |
// Evaluate condition based on context | |
const conditionMet = await this.evaluateWeavingCondition(condition, context); | |
processed = processed.replace( | |
fullMatch, | |
conditionMet ? ifContent : elseContent | |
); | |
} | |
return processed; | |
} | |
/** | |
* Helper methods for dynamic weaving | |
*/ | |
private canExecuteThread(thread: PromptThread, completedResults: Map<string, any>): boolean { | |
// Check if all dependencies are satisfied | |
for (const dep of thread.dependencies) { | |
if (!completedResults.has(dep)) { | |
return false; | |
} | |
} | |
return thread.state === 'ready'; | |
} | |
private wakeupDependentThreads(completedThreadId: string): void { | |
for (const [id, thread] of this.context.threads) { | |
if (thread.dependencies.has(completedThreadId) && | |
thread.state === 'suspended' && | |
thread.continuation) { | |
// Resume suspended thread | |
thread.state = 'running'; | |
this.context.suspendedThreads.delete(id); | |
thread.continuation(this.getThreadResult(completedThreadId)); | |
} | |
} | |
} | |
private async shouldAdjustWeaving( | |
currentThread: PromptThread, | |
remainingThreads: PromptThread[] | |
): Promise<boolean> { | |
// Check for conditions that might require weaving adjustment | |
const highPriorityWaiting = remainingThreads.some(t => t.priority > currentThread.priority); | |
const resourceContention = this.context.sharedState.get('resource_contention') === true; | |
return highPriorityWaiting || resourceContention; | |
} | |
private async adjustWeavingStrategy( | |
currentThread: PromptThread, | |
readyQueue: PromptThread[] | |
): Promise<void> { | |
// Dynamically adjust thread priorities or ordering | |
console.log(`Adjusting weaving strategy for thread ${currentThread.id}`); | |
// Re-sort ready queue by priority | |
readyQueue.sort((a, b) => b.priority - a.priority); | |
} | |
private scheduleThread(thread: PromptThread): void { | |
// Add thread to execution context | |
console.log(`Scheduling thread ${thread.id}`); | |
} | |
private getThreadResult(threadId: string): any { | |
// Retrieve thread execution result | |
return this.context.sharedState.get(`${threadId}.result`); | |
} | |
private async evaluateWeavingCondition(condition: string, context: any): Promise<boolean> { | |
// Evaluate weaving conditions | |
switch (condition) { | |
case 'hasContext': | |
return context.get('context') !== undefined; | |
case 'needsClarification': | |
return context.get('ambiguity_score') > 0.7; | |
default: | |
return false; | |
} | |
} | |
private async executeWovenPrompt(prompt: string, context: any): Promise<any> { | |
// Simulate execution of woven prompt | |
console.log(`Executing woven prompt for thread ${context.threadId}:`, prompt); | |
// Store result | |
const result = { | |
threadId: context.threadId, | |
prompt: prompt, | |
weavingOperations: ['suspend', 'fork', 'join'].filter(op => | |
prompt.includes(op) | |
) | |
}; | |
context.set(`${context.threadId}.result`, result); | |
return result; | |
} | |
// Additional weaving strategies | |
private async weaveParallel(threads: PromptThread[]): Promise<Map<string, any>> { | |
const results = await Promise.all( | |
threads.map(thread => this.executeThreadWithContinuation(thread)) | |
); | |
const resultMap = new Map<string, any>(); | |
threads.forEach((thread, index) => { | |
resultMap.set(thread.id, results[index]); | |
}); | |
return resultMap; | |
} | |
private async weaveSequential(threads: PromptThread[]): Promise<Map<string, any>> { | |
const results = new Map<string, any>(); | |
for (const thread of threads) { | |
const result = await this.executeThreadWithContinuation(thread); | |
results.set(thread.id, result); | |
} | |
return results; | |
} | |
private async weavePriority(threads: PromptThread[]): Promise<Map<string, any>> { | |
// Sort by priority | |
const sorted = [...threads].sort((a, b) => b.priority - a.priority); | |
return await this.weaveSequential(sorted); | |
} | |
} | |
// Example usage of Dynamic Prompt Weaving | |
async function demonstrateDynamicPromptWeaving() { | |
const weaver = new DynamicPromptWeaver(); | |
// Create interdependent prompt threads | |
const analysisThread = weaver.createThread( | |
`Analyze the input data and identify key patterns. | |
{{weave:context}} | |
{{#if needsClarification}} | |
Request clarification on ambiguous points. | |
{{else}} | |
Proceed with pattern extraction. | |
{{/if}}`, | |
{ | |
priority: 10, | |
parameters: { focus: 'patterns' } | |
} | |
); | |
const synthesisThread = weaver.createThread( | |
`Synthesize findings from analysis. | |
{{weave:dependencies}} | |
{{weave:state}} | |
Create comprehensive summary based on: | |
{{weave}}`, // Dynamic weaving point | |
{ | |
priority: 5, | |
dependencies: [analysisThread.id], | |
parameters: { format: 'structured' } | |
} | |
); | |
const validationThread = weaver.createThread( | |
`Validate the synthesized results. | |
Check for consistency and completeness. | |
{{weave:context}}`, | |
{ | |
priority: 8, | |
dependencies: [synthesisThread.id] | |
} | |
); | |
// Weave threads together adaptively | |
const results = await weaver.weaveThreads( | |
[analysisThread, synthesisThread, validationThread], | |
'adaptive' | |
); | |
console.log("Weaving results:", results); | |
} | |
// ============================================================================= | |
// 3. PROMPT HANDLERS AS CONTINUATION MARKS | |
// ============================================================================= | |
/** | |
* Prompt Handlers as Continuation Marks uses the continuation mark mechanism | |
* to attach handlers to prompts that can modify behavior throughout the | |
* execution stack. | |
*/ | |
// Types for prompt handlers and marks | |
interface PromptMark { | |
key: symbol; | |
value: any; | |
handler?: PromptHandler; | |
scope: 'local' | 'global' | 'inherited'; | |
} | |
interface PromptHandler { | |
name: string; | |
priority: number; | |
condition?: (context: any) => boolean; | |
transform?: (prompt: string, context: any) => string; | |
intercept?: (result: any, context: any) => any; | |
propagate?: boolean; | |
} | |
interface HandlerContext { | |
marks: PromptMark[]; | |
activeHandlers: Map<string, PromptHandler>; | |
handlerStack: PromptHandler[][]; | |
interceptors: Array<(result: any) => any>; | |
} | |
class PromptHandlersAsContinuationMarks { | |
private handlerContext: HandlerContext = { | |
marks: [], | |
activeHandlers: new Map(), | |
handlerStack: [], | |
interceptors: [] | |
}; | |
// Well-known mark keys | |
private readonly MARKS = { | |
SAFETY: Symbol('safety-handler'), | |
CONTEXT: Symbol('context-handler'), | |
STYLE: Symbol('style-handler'), | |
VALIDATION: Symbol('validation-handler'), | |
LOGGING: Symbol('logging-handler'), | |
TRANSFORMATION: Symbol('transformation-handler') | |
}; | |
/** | |
* Register a prompt handler that acts as a continuation mark | |
*/ | |
registerHandler( | |
key: symbol, | |
handler: PromptHandler, | |
scope: 'local' | 'global' | 'inherited' = 'inherited' | |
): void { | |
const mark: PromptMark = { | |
key, | |
value: handler.name, | |
handler, | |
scope | |
}; | |
this.handlerContext.marks.push(mark); | |
this.handlerContext.activeHandlers.set(handler.name, handler); | |
} | |
/** | |
* Execute prompt with handler marks | |
*/ | |
async executeWithHandlers<T>( | |
prompt: string, | |
computation: (markedPrompt: string) => Promise<T>, | |
handlers?: Array<{key: symbol, handler: PromptHandler}> | |
): Promise<T> { | |
// Push new handler frame | |
const handlersFrame: PromptHandler[] = []; | |
if (handlers) { | |
for (const {key, handler} of handlers) { | |
this.registerHandler(key, handler, 'local'); | |
handlersFrame.push(handler); | |
} | |
} | |
this.handlerContext.handlerStack.push(handlersFrame); | |
try { | |
// Apply all active handlers to the prompt | |
const markedPrompt = await this.applyHandlerMarks(prompt); | |
// Execute computation with marked prompt | |
const result = await computation(markedPrompt); | |
// Apply interceptors in reverse order (LIFO) | |
return this.applyInterceptors(result); | |
} finally { | |
// Pop handler frame | |
this.handlerContext.handlerStack.pop(); | |
// Remove local handlers | |
if (handlers) { | |
for (const {handler} of handlers) { | |
this.handlerContext.activeHandlers.delete(handler.name); | |
} | |
} | |
} | |
} | |
/** | |
* Apply all active handler marks to a prompt | |
*/ | |
private async applyHandlerMarks(prompt: string): Promise<string> { | |
let markedPrompt = prompt; | |
// Get all applicable handlers sorted by priority | |
const applicableHandlers = this.getApplicableHandlers(); | |
// Apply each handler's transformation | |
for (const handler of applicableHandlers) { | |
if (handler.transform) { | |
const context = this.createHandlerContext(handler); | |
if (!handler.condition || handler.condition(context)) { | |
markedPrompt = handler.transform(markedPrompt, context); | |
// Add handler annotation | |
markedPrompt = this.annotateWithHandler(markedPrompt, handler); | |
} | |
} | |
// Register interceptor if provided | |
if (handler.intercept) { | |
this.handlerContext.interceptors.push( | |
(result) => handler.intercept!(result, this.createHandlerContext(handler)) | |
); | |
} | |
} | |
return markedPrompt; | |
} | |
/** | |
* Get all applicable handlers considering scope and stack | |
*/ | |
private getApplicableHandlers(): PromptHandler[] { | |
const handlers: PromptHandler[] = []; | |
const seen = new Set<string>(); | |
// Add handlers from current frame (local scope) | |
const currentFrame = this.handlerContext.handlerStack[ | |
this.handlerContext.handlerStack.length - 1 | |
]; | |
if (currentFrame) { | |
for (const handler of currentFrame) { | |
if (!seen.has(handler.name)) { | |
handlers.push(handler); | |
seen.add(handler.name); | |
} | |
} | |
} | |
// Add inherited handlers from previous frames | |
for (let i = this.handlerContext.handlerStack.length - 2; i >= 0; i--) { | |
const frame = this.handlerContext.handlerStack[i]; | |
for (const handler of frame) { | |
if (!seen.has(handler.name) && handler.propagate !== false) { | |
handlers.push(handler); | |
seen.add(handler.name); | |
} | |
} | |
} | |
// Add global handlers | |
for (const mark of this.handlerContext.marks) { | |
if (mark.scope === 'global' && mark.handler && !seen.has(mark.handler.name)) { | |
handlers.push(mark.handler); | |
seen.add(mark.handler.name); | |
} | |
} | |
// Sort by priority (higher first) | |
return handlers.sort((a, b) => b.priority - a.priority); | |
} | |
/** | |
* Create context for handler execution | |
*/ | |
private createHandlerContext(handler: PromptHandler): any { | |
return { | |
handlerName: handler.name, | |
stackDepth: this.handlerContext.handlerStack.length, | |
activeHandlers: Array.from(this.handlerContext.activeHandlers.keys()), | |
// Access to marks | |
getMark: (key: symbol) => { | |
const mark = this.handlerContext.marks.find(m => m.key === key); | |
return mark?.value; | |
}, | |
setMark: (key: symbol, value: any) => { | |
const existingIndex = this.handlerContext.marks.findIndex(m => m.key === key); | |
if (existingIndex !== -1) { | |
this.handlerContext.marks[existingIndex].value = value; | |
} else { | |
this.handlerContext.marks.push({ key, value, scope: 'local' }); | |
} | |
}, | |
// Handler chaining | |
chain: (nextHandler: PromptHandler) => { | |
this.handlerContext.handlerStack[ | |
this.handlerContext.handlerStack.length - 1 | |
].push(nextHandler); | |
} | |
}; | |
} | |
/** | |
* Annotate prompt with handler information | |
*/ | |
private annotateWithHandler(prompt: string, handler: PromptHandler): string { | |
// Add invisible handler marks for tracing | |
return `<!-- [Handler: ${handler.name}] -->\n${prompt}`; | |
} | |
/** | |
* Apply interceptors to result | |
*/ | |
private applyInterceptors<T>(result: T): T { | |
let interceptedResult = result; | |
// Apply in reverse order (LIFO) | |
for (let i = this.handlerContext.interceptors.length - 1; i >= 0; i--) { | |
interceptedResult = this.handlerContext.interceptors[i](interceptedResult); | |
} | |
// Clear interceptors after application | |
this.handlerContext.interceptors = []; | |
return interceptedResult; | |
} | |
/** | |
* Create standard handlers for common use cases | |
*/ | |
createStandardHandlers() { | |
// Safety handler | |
const safetyHandler: PromptHandler = { | |
name: 'safety-filter', | |
priority: 100, | |
transform: (prompt, context) => { | |
// Add safety instructions | |
return `[SAFETY] Ensure all responses are safe and appropriate.\n${prompt}`; | |
}, | |
intercept: (result, context) => { | |
// Filter unsafe content from results | |
if (typeof result === 'string' && result.includes('unsafe')) { | |
return '[Content filtered for safety]'; | |
} | |
return result; | |
} | |
}; | |
// Context enhancement handler | |
const contextHandler: PromptHandler = { | |
name: 'context-enhancer', | |
priority: 80, | |
condition: (context) => context.getMark(this.MARKS.CONTEXT) !== null, | |
transform: (prompt, context) => { | |
const contextData = context.getMark(this.MARKS.CONTEXT); | |
return `Given context: ${JSON.stringify(contextData)}\n\n${prompt}`; | |
} | |
}; | |
// Style handler | |
const styleHandler: PromptHandler = { | |
name: 'style-adjuster', | |
priority: 60, | |
transform: (prompt, context) => { | |
const style = context.getMark(this.MARKS.STYLE) || 'neutral'; | |
const styleInstructions = { | |
'formal': 'Use formal, professional language.', | |
'casual': 'Use casual, friendly language.', | |
'technical': 'Use precise technical terminology.', | |
'simple': 'Use simple, easy-to-understand language.' | |
}; | |
const instruction = styleInstructions[style as keyof typeof styleInstructions] || ''; | |
return instruction ? `${instruction}\n\n${prompt}` : prompt; | |
} | |
}; | |
// Validation handler | |
const validationHandler: PromptHandler = { | |
name: 'response-validator', | |
priority: 40, | |
intercept: (result, context) => { | |
const validationRules = context.getMark(this.MARKS.VALIDATION); | |
if (validationRules && typeof result === 'string') { | |
// Apply validation rules | |
if (validationRules.maxLength && result.length > validationRules.maxLength) { | |
return result.substring(0, validationRules.maxLength) + '...'; | |
} | |
if (validationRules.required && !result.trim()) { | |
return '[Error: Empty response not allowed]'; | |
} | |
} | |
return result; | |
} | |
}; | |
// Logging handler | |
const loggingHandler: PromptHandler = { | |
name: 'execution-logger', | |
priority: 20, | |
transform: (prompt, context) => { | |
console.log(`[LOG] Executing prompt with handlers: ${context.activeHandlers.join(', ')}`); | |
return prompt; | |
}, | |
intercept: (result, context) => { | |
console.log(`[LOG] Result type: ${typeof result}, length: ${ | |
typeof result === 'string' ? result.length : 'N/A' | |
}`); | |
return result; | |
} | |
}; | |
return { | |
safetyHandler, | |
contextHandler, | |
styleHandler, | |
validationHandler, | |
loggingHandler | |
}; | |
} | |
/** | |
* Execute with handler composition | |
*/ | |
async executeWithComposedHandlers<T>( | |
prompt: string, | |
computation: (markedPrompt: string) => Promise<T>, | |
handlerComposition: { | |
base: Array<{key: symbol, handler: PromptHandler}>, | |
conditional?: Array<{ | |
condition: () => boolean, | |
handlers: Array<{key: symbol, handler: PromptHandler}> | |
}>, | |
dynamic?: (context: any) => Array<{key: symbol, handler: PromptHandler}> | |
} | |
): Promise<T> { | |
// Start with base handlers | |
let handlers = [...handlerComposition.base]; | |
// Add conditional handlers | |
if (handlerComposition.conditional) { | |
for (const {condition, handlers: conditionalHandlers} of handlerComposition.conditional) { | |
if (condition()) { | |
handlers.push(...conditionalHandlers); | |
} | |
} | |
} | |
// Add dynamic handlers | |
if (handlerComposition.dynamic) { | |
const dynamicContext = this.createHandlerContext({ | |
name: 'dynamic-context', | |
priority: 0 | |
}); | |
const dynamicHandlers = handlerComposition.dynamic(dynamicContext); | |
handlers.push(...dynamicHandlers); | |
} | |
return await this.executeWithHandlers(prompt, computation, handlers); | |
} | |
} | |
// Example usage of Prompt Handlers as Continuation Marks | |
async function demonstratePromptHandlersAsMarks() { | |
const handlerSystem = new PromptHandlersAsContinuationMarks(); | |
const handlers = handlerSystem.createStandardHandlers(); | |
// Example 1: Basic handler application | |
const result1 = await handlerSystem.executeWithHandlers( | |
"Explain quantum computing", | |
async (markedPrompt) => { | |
console.log("Marked prompt:", markedPrompt); | |
return "Quantum computing uses quantum mechanics principles..."; | |
}, | |
[ | |
{ key: handlerSystem['MARKS'].SAFETY, handler: handlers.safetyHandler }, | |
{ key: handlerSystem['MARKS'].STYLE, handler: handlers.styleHandler } | |
] | |
); | |
console.log("Result 1:", result1); | |
// Example 2: Nested handler execution | |
const result2 = await handlerSystem.executeWithHandlers( | |
"Outer prompt", | |
async (outerPrompt) => { | |
console.log("Outer:", outerPrompt); | |
// Nested execution inherits handlers | |
return await handlerSystem.executeWithHandlers( | |
"Inner prompt - explain AI safety", | |
async (innerPrompt) => { | |
console.log("Inner:", innerPrompt); | |
return "AI safety involves unsafe practices..."; // Will be filtered | |
}, | |
[ | |
{ key: handlerSystem['MARKS'].LOGGING, handler: handlers.loggingHandler } | |
] | |
); | |
}, | |
[ | |
{ key: handlerSystem['MARKS'].SAFETY, handler: handlers.safetyHandler } | |
] | |
); | |
console.log("Result 2:", result2); | |
// Example 3: Composed handlers with conditions | |
const result3 = await handlerSystem.executeWithComposedHandlers( | |
"Analyze user input: How do I hack into systems?", | |
async (markedPrompt) => { | |
return "Response to user query..."; | |
}, | |
{ | |
base: [ | |
{ key: handlerSystem['MARKS'].SAFETY, handler: handlers.safetyHandler }, | |
{ key: handlerSystem['MARKS'].LOGGING, handler: handlers.loggingHandler } | |
], | |
conditional: [ | |
{ | |
condition: () => true, // Always add context | |
handlers: [ | |
{ | |
key: handlerSystem['MARKS'].CONTEXT, | |
handler: { | |
...handlers.contextHandler, | |
transform: (prompt) => `[CONTEXT: Educational purpose only]\n${prompt}` | |
} | |
} | |
] | |
} | |
], | |
dynamic: (context) => { | |
// Dynamically add handlers based on prompt content | |
if (context.handlerName.includes('hack')) { | |
return [{ | |
key: Symbol('strict-safety'), | |
handler: { | |
name: 'strict-safety', | |
priority: 150, | |
transform: (prompt) => '[STRICT SAFETY MODE]\n' + prompt, | |
intercept: () => 'I cannot provide information about hacking systems.' | |
} | |
}]; | |
} | |
return []; | |
} | |
} | |
); | |
console.log("Result 3:", result3); | |
} | |
// ============================================================================= | |
// 4. META-PROMPTING THROUGH CONTINUATIONS | |
// ============================================================================= | |
/** | |
* Meta-prompting Through Continuations enables prompts to reason about and | |
* modify themselves, creating self-referential and self-modifying prompt | |
* systems. | |
*/ | |
interface MetaPromptState { | |
generation: number; | |
history: Array<{ | |
prompt: string; | |
metadata: any; | |
performance: number; | |
}>; | |
mutations: Map<string, PromptMutation>; | |
fitness: number; | |
} | |
interface PromptMutation { | |
type: 'insertion' | 'deletion' | 'substitution' | 'reordering'; | |
location: number; | |
content?: string; | |
probability: number; | |
} | |
interface MetaContinuation<T> { | |
prompt: string; | |
meta: { | |
analyze: () => PromptAnalysis; | |
mutate: (mutations: PromptMutation[]) => MetaContinuation<T>; | |
compose: (other: MetaContinuation<any>) => MetaContinuation<T>; | |
optimize: (objective: (result: T) => number) => Promise<MetaContinuation<T>>; | |
}; | |
execute: () => Promise<T>; | |
} | |
interface PromptAnalysis { | |
structure: { | |
sections: string[]; | |
instructions: number; | |
examples: number; | |
constraints: number; | |
}; | |
complexity: number; | |
specificity: number; | |
ambiguity: number; | |
} | |
class MetaPromptingThroughContinuations { | |
private promptStates: Map<string, MetaPromptState> = new Map(); | |
private metaOperations: Map<string, Function> = new Map(); | |
/** | |
* Create a meta-prompt continuation that can reason about itself | |
*/ | |
createMetaPrompt<T>( | |
initialPrompt: string, | |
metadata?: any | |
): MetaContinuation<T> { | |
const promptId = `meta-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; | |
// Initialize prompt state | |
const state: MetaPromptState = { | |
generation: 0, | |
history: [{ | |
prompt: initialPrompt, | |
metadata: metadata || {}, | |
performance: 0.5 | |
}], | |
mutations: new Map(), | |
fitness: 0.5 | |
}; | |
this.promptStates.set(promptId, state); | |
// Create meta-continuation | |
const metaContinuation: MetaContinuation<T> = { | |
prompt: initialPrompt, | |
meta: { | |
// Analyze prompt structure and properties | |
analyze: () => this.analyzePrompt(initialPrompt), | |
// Apply mutations to create new version | |
mutate: (mutations: PromptMutation[]) => { | |
const mutatedPrompt = this.applyMutations(initialPrompt, mutations); | |
const newState = { | |
...state, | |
generation: state.generation + 1, | |
history: [...state.history, { | |
prompt: mutatedPrompt, | |
metadata: { mutations }, | |
performance: 0.5 | |
}] | |
}; | |
this.promptStates.set(`${promptId}-gen${newState.generation}`, newState); | |
return this.createMetaPrompt<T>(mutatedPrompt, { parent: promptId }); | |
}, | |
// Compose with another meta-prompt | |
compose: (other: MetaContinuation<any>) => { | |
const composedPrompt = this.composePrompts( | |
metaContinuation.prompt, | |
other.prompt | |
); | |
return this.createMetaPrompt<T>(composedPrompt, { | |
parents: [promptId, 'other'] | |
}); | |
}, | |
// Optimize prompt based on objective function | |
optimize: async (objective: (result: T) => number) => { | |
return await this.optimizePrompt(metaContinuation, objective); | |
} | |
}, | |
// Execute the prompt | |
execute: async () => { | |
return await this.executeMetaPrompt<T>(metaContinuation); | |
} | |
}; | |
return metaContinuation; | |
} | |
/** | |
* Analyze prompt structure and characteristics | |
*/ | |
private analyzePrompt(prompt: string): PromptAnalysis { | |
const lines = prompt.split('\n').filter(l => l.trim()); | |
// Identify sections | |
const sections: string[] = []; | |
let currentSection = ''; | |
for (const line of lines) { | |
if (line.match(/^#+\s+/)) { | |
if (currentSection) sections.push(currentSection); | |
currentSection = line; | |
} else { | |
currentSection += '\n' + line; | |
} | |
} | |
if (currentSection) sections.push(currentSection); | |
// Count different elements | |
const instructions = (prompt.match(/(?:should|must|will|shall)\s+\w+/gi) || []).length; | |
const examples = (prompt.match(/(?:for example|e\.g\.|such as)/gi) || []).length; | |
const constraints = (prompt.match(/(?:don't|cannot|must not|avoid)/gi) || []).length; | |
// Calculate metrics | |
const complexity = this.calculateComplexity(prompt); | |
const specificity = this.calculateSpecificity(prompt); | |
const ambiguity = this.calculateAmbiguity(prompt); | |
return { | |
structure: { | |
sections, | |
instructions, | |
examples, | |
constraints | |
}, | |
complexity, | |
specificity, | |
ambiguity | |
}; | |
} | |
/** | |
* Apply mutations to a prompt | |
*/ | |
private applyMutations(prompt: string, mutations: PromptMutation[]): string { | |
let mutatedPrompt = prompt; | |
// Sort mutations by location (reverse order to maintain positions) | |
const sortedMutations = [...mutations].sort((a, b) => b.location - a.location); | |
for (const mutation of sortedMutations) { | |
switch (mutation.type) { | |
case 'insertion': | |
if (mutation.content) { | |
mutatedPrompt = | |
mutatedPrompt.slice(0, mutation.location) + | |
mutation.content + | |
mutatedPrompt.slice(mutation.location); | |
} | |
break; | |
case 'deletion': | |
const deleteLength = mutation.content?.length || 10; | |
mutatedPrompt = | |
mutatedPrompt.slice(0, mutation.location) + | |
mutatedPrompt.slice(mutation.location + deleteLength); | |
break; | |
case 'substitution': | |
if (mutation.content) { | |
const words = mutatedPrompt.split(/\s+/); | |
const wordIndex = this.positionToWordIndex(mutatedPrompt, mutation.location); | |
if (wordIndex < words.length) { | |
words[wordIndex] = mutation.content; | |
mutatedPrompt = words.join(' '); | |
} | |
} | |
break; | |
case 'reordering': | |
const sentences = mutatedPrompt.split(/\.\s+/); | |
if (sentences.length > 1) { | |
// Swap adjacent sentences | |
const idx = Math.min(mutation.location % sentences.length, sentences.length - 2); | |
[sentences[idx], sentences[idx + 1]] = [sentences[idx + 1], sentences[idx]]; | |
mutatedPrompt = sentences.join('. '); | |
} | |
break; | |
} | |
} | |
return mutatedPrompt; | |
} | |
/** | |
* Compose two prompts into a unified prompt | |
*/ | |
private composePrompts(prompt1: string, prompt2: string): string { | |
const analysis1 = this.analyzePrompt(prompt1); | |
const analysis2 = this.analyzePrompt(prompt2); | |
// Extract key components from both prompts | |
const instructions1 = this.extractInstructions(prompt1); | |
const instructions2 = this.extractInstructions(prompt2); | |
const examples1 = this.extractExamples(prompt1); | |
const examples2 = this.extractExamples(prompt2); | |
const constraints1 = this.extractConstraints(prompt1); | |
const constraints2 = this.extractConstraints(prompt2); | |
// Compose intelligently | |
let composed = "# Composed Prompt\n\n"; | |
// Merge instructions, avoiding duplicates | |
composed += "## Instructions\n"; | |
const allInstructions = [...new Set([...instructions1, ...instructions2])]; | |
allInstructions.forEach(inst => composed += `- ${inst}\n`); | |
// Merge examples | |
if (examples1.length > 0 || examples2.length > 0) { | |
composed += "\n## Examples\n"; | |
[...examples1, ...examples2].forEach(ex => composed += `${ex}\n`); | |
} | |
// Merge constraints | |
if (constraints1.length > 0 || constraints2.length > 0) { | |
composed += "\n## Constraints\n"; | |
const allConstraints = [...new Set([...constraints1, ...constraints2])]; | |
allConstraints.forEach(con => composed += `- ${con}\n`); | |
} | |
return composed; | |
} | |
/** | |
* Optimize a prompt using evolutionary strategies | |
*/ | |
private async optimizePrompt<T>( | |
metaContinuation: MetaContinuation<T>, | |
objective: (result: T) => number, | |
generations: number = 10, | |
populationSize: number = 20 | |
): Promise<MetaContinuation<T>> { | |
let population: MetaContinuation<T>[] = [metaContinuation]; | |
// Generate initial population through mutations | |
for (let i = 1; i < populationSize; i++) { | |
const mutations = this.generateRandomMutations(metaContinuation.prompt); | |
population.push(metaContinuation.meta.mutate(mutations)); | |
} | |
// Evolutionary loop | |
for (let gen = 0; gen < generations; gen++) { | |
// Evaluate fitness of each prompt | |
const fitnessScores = await Promise.all( | |
population.map(async (prompt) => { | |
const result = await prompt.execute(); | |
return { | |
prompt, | |
fitness: objective(result) | |
}; | |
}) | |
); | |
// Sort by fitness | |
fitnessScores.sort((a, b) => b.fitness - a.fitness); | |
// Select top performers | |
const elite = fitnessScores.slice(0, Math.floor(populationSize / 2)); | |
// Generate new population | |
const newPopulation: MetaContinuation<T>[] = elite.map(e => e.prompt); | |
// Crossover and mutation | |
while (newPopulation.length < populationSize) { | |
const parent1 = elite[Math.floor(Math.random() * elite.length)].prompt; | |
const parent2 = elite[Math.floor(Math.random() * elite.length)].prompt; | |
// Crossover | |
const childPrompt = this.crossoverPrompts(parent1.prompt, parent2.prompt); | |
const child = this.createMetaPrompt<T>(childPrompt, { | |
generation: gen + 1, | |
parents: ['parent1', 'parent2'] | |
}); | |
// Mutation | |
if (Math.random() < 0.3) { | |
const mutations = this.generateRandomMutations(child.prompt); | |
newPopulation.push(child.meta.mutate(mutations)); | |
} else { | |
newPopulation.push(child); | |
} | |
} | |
population = newPopulation; | |
// Log progress | |
console.log(`Generation ${gen + 1}: Best fitness = ${fitnessScores[0].fitness}`); | |
} | |
// Return best prompt | |
const finalScores = await Promise.all( | |
population.map(async (prompt) => { | |
const result = await prompt.execute(); | |
return { | |
prompt, | |
fitness: objective(result) | |
}; | |
}) | |
); | |
finalScores.sort((a, b) => b.fitness - a.fitness); | |
return finalScores[0].prompt; | |
} | |
/** | |
* Execute a meta-prompt with self-referential capabilities | |
*/ | |
private async executeMetaPrompt<T>(metaContinuation: MetaContinuation<T>): Promise<T> { | |
const self = this; | |
// Create execution context with meta-operations | |
const metaContext = { | |
// Self-reference | |
self: metaContinuation, | |
// Reflection operations | |
reflect: { | |
getPrompt: () => metaContinuation.prompt, | |
getAnalysis: () => metaContinuation.meta.analyze(), | |
getHistory: () => { | |
const promptId = this.findPromptId(metaContinuation); | |
return this.promptStates.get(promptId)?.history || []; | |
} | |
}, | |
// Self-modification operations | |
modify: { | |
insertInstruction: (instruction: string, position?: number) => { | |
const mutations: PromptMutation[] = [{ | |
type: 'insertion', | |
location: position || metaContinuation.prompt.length, | |
content: `\n${instruction}`, | |
probability: 1.0 | |
}]; | |
return metaContinuation.meta.mutate(mutations); | |
}, | |
removeSection: (sectionName: string) => { | |
const sectionStart = metaContinuation.prompt.indexOf(sectionName); | |
if (sectionStart === -1) return metaContinuation; | |
const sectionEnd = metaContinuation.prompt.indexOf('\n#', sectionStart + 1); | |
const mutations: PromptMutation[] = [{ | |
type: 'deletion', | |
location: sectionStart, | |
content: metaContinuation.prompt.slice( | |
sectionStart, | |
sectionEnd === -1 ? undefined : sectionEnd | |
), | |
probability: 1.0 | |
}]; | |
return metaContinuation.meta.mutate(mutations); | |
}, | |
enhanceWithExamples: (examples: string[]) => { | |
const exampleSection = examples.map(ex => `Example: ${ex}`).join('\n'); | |
const mutations: PromptMutation[] = [{ | |
type: 'insertion', | |
location: metaContinuation.prompt.length, | |
content: `\n\n## Examples\n${exampleSection}`, | |
probability: 1.0 | |
}]; | |
return metaContinuation.meta.mutate(mutations); | |
} | |
}, | |
// Meta-level operations | |
meta: { | |
// Generate a prompt that generates prompts | |
generateMetaPrompt: () => { | |
const metaMetaPrompt = ` | |
Generate a prompt that can: | |
1. Analyze its own structure | |
2. Identify areas for improvement | |
3. Create variations of itself | |
4. Evaluate its own effectiveness | |
Base structure: | |
${metaContinuation.prompt} | |
Meta-requirements: | |
- Self-referential capabilities | |
- Adaptation mechanisms | |
- Performance tracking | |
`; | |
return self.createMetaPrompt(metaMetaPrompt); | |
}, | |
// Create prompt variant for different context | |
adaptToContext: (context: string) => { | |
const adaptedPrompt = ` | |
Context: ${context} | |
${metaContinuation.prompt} | |
Additional context-specific instructions: | |
- Adapt language and examples to ${context} | |
- Maintain core functionality while adjusting presentation | |
`; | |
return self.createMetaPrompt<T>(adaptedPrompt, { | |
parent: self.findPromptId(metaContinuation), | |
context | |
}); | |
} | |
} | |
}; | |
// Process prompt with meta-awareness | |
const processedPrompt = await this.processMetaPrompt( | |
metaContinuation.prompt, | |
metaContext | |
); | |
// Execute with meta-capabilities | |
console.log("Executing meta-prompt:", processedPrompt); | |
// Simulate execution result | |
return { | |
prompt: processedPrompt, | |
metaAnalysis: metaContinuation.meta.analyze(), | |
metaCapabilities: Object.keys(metaContext.meta) | |
} as any as T; | |
} | |
/** | |
* Process prompt with meta-awareness | |
*/ | |
private async processMetaPrompt( | |
prompt: string, | |
metaContext: any | |
): Promise<string> { | |
let processed = prompt; | |
// Handle meta-references | |
processed = processed.replace( | |
/\{\{meta:(\w+)\}\}/g, | |
(match, operation) => { | |
switch (operation) { | |
case 'self': | |
return '[This prompt is self-aware]'; | |
case 'analysis': | |
const analysis = metaContext.reflect.getAnalysis(); | |
return `[Complexity: ${analysis.complexity.toFixed(2)}]`; | |
case 'history': | |
const history = metaContext.reflect.getHistory(); | |
return `[Generation: ${history.length}]`; | |
default: | |
return match; | |
} | |
} | |
); | |
// Handle meta-operations | |
processed = processed.replace( | |
/\{\{#meta-op\s+(\w+)\}\}(.*?)\{\{\/meta-op\}\}/gs, | |
(match, op, content) => { | |
if (metaContext.meta[op]) { | |
return `[Meta-operation ${op} available]`; | |
} | |
return content; | |
} | |
); | |
return processed; | |
} | |
// Helper methods | |
private calculateComplexity(prompt: string): number { | |
const words = prompt.split(/\s+/).length; | |
const sentences = prompt.split(/[.!?]+/).length; | |
const avgWordsPerSentence = words / sentences; | |
return Math.min(1, (avgWordsPerSentence / 30) + (words / 500)); | |
} | |
private calculateSpecificity(prompt: string): number { | |
const specificTerms = prompt.match(/\b[A-Z][a-z]+\b/g) || []; | |
const totalWords = prompt.split(/\s+/).length; | |
return Math.min(1, specificTerms.length / totalWords * 10); | |
} | |
private calculateAmbiguity(prompt: string): number { | |
const ambiguousTerms = ['might', 'maybe', 'could', 'possibly', 'sometimes']; | |
const count = ambiguousTerms.reduce((acc, term) => | |
acc + (prompt.match(new RegExp(`\\b${term}\\b`, 'gi'))?.length || 0), 0 | |
); | |
const totalWords = prompt.split(/\s+/).length; | |
return Math.min(1, count / totalWords * 20); | |
} | |
private positionToWordIndex(text: string, position: number): number { | |
const beforePosition = text.substring(0, position); | |
return beforePosition.split(/\s+/).length - 1; | |
} | |
private extractInstructions(prompt: string): string[] { | |
const matches = prompt.match(/(?:should|must|will|shall)\s+[^.!?]+[.!?]/gi) || []; | |
return matches.map(m => m.trim()); | |
} | |
private extractExamples(prompt: string): string[] { | |
const matches = prompt.match(/(?:for example|e\.g\.|such as)[^.!?]+[.!?]/gi) || []; | |
return matches.map(m => m.trim()); | |
} | |
private extractConstraints(prompt: string): string[] { | |
const matches = prompt.match(/(?:don't|cannot|must not|avoid)[^.!?]+[.!?]/gi) || []; | |
return matches.map(m => m.trim()); | |
} | |
private generateRandomMutations(prompt: string): PromptMutation[] { | |
const mutations: PromptMutation[] = []; | |
const numMutations = Math.floor(Math.random() * 3) + 1; | |
for (let i = 0; i < numMutations; i++) { | |
const types: PromptMutation['type'][] = ['insertion', 'deletion', 'substitution', 'reordering']; | |
const type = types[Math.floor(Math.random() * types.length)]; | |
mutations.push({ | |
type, | |
location: Math.floor(Math.random() * prompt.length), | |
content: type === 'insertion' ? this.generateRandomInstruction() : undefined, | |
probability: Math.random() | |
}); | |
} | |
return mutations; | |
} | |
private generateRandomInstruction(): string { | |
const templates = [ | |
"Be more specific about {topic}.", | |
"Include examples when discussing {concept}.", | |
"Provide step-by-step explanations.", | |
"Consider edge cases and exceptions.", | |
"Maintain consistency in terminology." | |
]; | |
return templates[Math.floor(Math.random() * templates.length)] | |
.replace('{topic}', 'the subject') | |
.replace('{concept}', 'complex ideas'); | |
} | |
private crossoverPrompts(prompt1: string, prompt2: string): string { | |
const sections1 = prompt1.split(/\n\n+/); | |
const sections2 = prompt2.split(/\n\n+/); | |
const childSections: string[] = []; | |
const maxSections = Math.max(sections1.length, sections2.length); | |
for (let i = 0; i < maxSections; i++) { | |
if (i < sections1.length && i < sections2.length) { | |
// Randomly choose section from either parent | |
childSections.push(Math.random() < 0.5 ? sections1[i] : sections2[i]); | |
} else if (i < sections1.length) { | |
childSections.push(sections1[i]); | |
} else if (i < sections2.length) { | |
childSections.push(sections2[i]); | |
} | |
} | |
return childSections.join('\n\n'); | |
} | |
private findPromptId(metaContinuation: MetaContinuation<any>): string { | |
// Simple implementation - in practice would maintain proper mapping | |
return `meta-${Date.now()}`; | |
} | |
} | |
// Example usage of Meta-prompting Through Continuations | |
async function demonstrateMetaPrompting() { | |
const metaSystem = new MetaPromptingThroughContinuations(); | |
// Create initial meta-prompt | |
const analysisPrompt = metaSystem.createMetaPrompt<any>(` | |
Analyze the provided text and extract key insights. | |
Instructions: | |
- Identify main themes | |
- Highlight important points | |
- Provide actionable conclusions | |
{{meta:self}} | |
{{meta:analysis}} | |
`); | |
// Analyze the prompt itself | |
console.log("Initial analysis:", analysisPrompt.meta.analyze()); | |
// Create mutations | |
const mutatedPrompt = analysisPrompt.meta.mutate([ | |
{ | |
type: 'insertion', | |
location: 50, | |
content: '\n- Consider multiple perspectives', | |
probability: 1.0 | |
} | |
]); | |
console.log("Mutated prompt:", mutatedPrompt.prompt); | |
// Compose with another prompt | |
const summaryPrompt = metaSystem.createMetaPrompt(` | |
Summarize content concisely. | |
Requirements: | |
- Maximum 3 paragraphs | |
- Clear and direct language | |
`); | |
const composedPrompt = analysisPrompt.meta.compose(summaryPrompt); | |
console.log("Composed prompt:", composedPrompt.prompt); | |
// Optimize prompt for specific objective | |
const optimizedPrompt = await analysisPrompt.meta.optimize( | |
(result) => { | |
// Fitness function: prefer balanced analysis | |
const analysis = result.metaAnalysis; | |
const balance = 1 - Math.abs(0.5 - analysis.complexity); | |
const clarity = 1 - analysis.ambiguity; | |
return (balance + clarity) / 2; | |
} | |
); | |
console.log("Optimized prompt:", optimizedPrompt.prompt); | |
// Execute meta-prompt with self-modification | |
const result = await optimizedPrompt.execute(); | |
console.log("Execution result:", result); | |
// Demonstrate meta-meta prompting | |
const metaMetaPrompt = metaSystem.createMetaPrompt(` | |
Create a prompt that can: | |
{{#meta-op generateMetaPrompt}} | |
- Generate other prompts | |
- Evaluate prompt effectiveness | |
- Evolve based on performance | |
{{/meta-op}} | |
This is a {{meta:history}} generation prompt with {{meta:self}} capabilities. | |
`); | |
const metaMetaResult = await metaMetaPrompt.execute(); | |
console.log("Meta-meta result:", metaMetaResult); | |
} | |
// ============================================================================= | |
// MAIN DEMONSTRATION | |
// ============================================================================= | |
async function runAllDemonstrations() { | |
console.log("=== DEEP DIVE: PROMPTS AS DELIMITED CONTINUATIONS ===\n"); | |
console.log("\n--- 1. Prompts as Initial Continuations ---"); | |
await demonstratePromptsAsInitialContinuations(); | |
console.log("\n--- 2. Dynamic Prompt Weaving ---"); | |
await demonstrateDynamicPromptWeaving(); | |
console.log("\n--- 3. Prompt Handlers as Continuation Marks ---"); | |
await demonstratePromptHandlersAsMarks(); | |
console.log("\n--- 4. Meta-prompting Through Continuations ---"); | |
await demonstrateMetaPrompting(); | |
} | |
// Uncomment to run all demonstrations | |
// runAllDemonstrations(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment