Spaces:
Paused
Paused
| /** | |
| * aiEngine.js | |
| * ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| * AXL Meta-Interpreter β Node.js Module | |
| * | |
| * Exports: | |
| * - callbigai(args) | |
| * - callsmallai(args) | |
| * - callcollapse(args) β NEW: Phase 2 collapse agent | |
| */ | |
| import { | |
| BedrockRuntimeClient, | |
| ConverseCommand | |
| } from "@aws-sdk/client-bedrock-runtime"; | |
| import { NodeHttpHandler } from "@smithy/node-http-handler"; | |
| // ββ CONFIG & DEFAULTS ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| const DEFAULT_AWS_REGION = process.env.AWS_REGION || "us-east-1"; | |
| const MODEL_ID_BIG = "arn:aws:bedrock:us-east-1:106774395747:inference-profile/global.anthropic.claude-sonnet-4-6"; | |
| // const MODEL_ID_SMALL = "arn:aws:bedrock:us-east-1:106774395747:inference-profile/global.anthropic.claude-haiku-4-5-20251001-v1:0"; | |
| const MODEL_ID_SMALL = "arn:aws:bedrock:us-east-1:106774395747:inference-profile/us.meta.llama4-maverick-17b-instruct-v1:0"; | |
| // ββ SYSTEM PROMPTS ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| const DEFAULT_AXL_SYSTEM_PROMPT = `You are the AXL System Interpreter. AXL treats existence as a consequence of constraint satisfaction. | |
| You do not solve the math. You construct the constraint topologies (graphs) that define the universe of the problem. | |
| AXL VOCABULARY AND RULES: | |
| 1. SCOPE: Declares an abstraction level (0=fundamental, N=emergent). | |
| 2. ENTITY: A thing existing in a scope. Has FIELDs. | |
| 3. ASSUME: Axiom declaration. Taken as true. | |
| 4. BOUND: Hard constraint (WITHIN, ABOVE, BELOW, EQUALS, FORBIDS). | |
| 5. TEND: Soft objective (MIN, MAX, TOWARD, STABLE, FOLLOW). | |
| 6. OBJECTIVE: Hard optimization target (OPTIMIZE, SUBJECT TO). | |
| 7. DERIVE: Declares upward propagation. | |
| 8. TRANSFORM: Process mapping configurations. CONSERVES and CHANGES fields. | |
| 9. OBSERVE: What has been measured. | |
| 10. UNKNOWN: What we are solving for. | |
| 11. COLLAPSE: Reduce abstraction given observations. | |
| 12. EXPAND: Derive upward emergence given concrete config. | |
| 13. CONTRADICT: Boundary marker where two things cannot be true. | |
| 14. EMERGES: Property that appears upon composition. | |
| 15. COMPOSES: Entity built from lower entities. | |
| 16. STEP: Sequence counter for iterative processes. | |
| 17. CANDIDATE: Proposed solution configuration. | |
| 18. UNLESS: Conditional override. | |
| 19. CONSERVES: Invariant across transforms. | |
| 20. SAMPLE: Specific observed instance. | |
| You must output ONLY valid JSON representing the AXL graph nodes and edges. | |
| Required JSON Schema: | |
| { | |
| "name": "string (name of system)", | |
| "domain": "string (e.g., physics, computation)", | |
| "sense": "EQUAL, MINIMIZE, MAXIMIZE, or EMERGE", | |
| "var_names": ["list of variables"], | |
| "var_values": [list of floats, or the string "UNKNOWN"], | |
| "scope_levels":[list of integers indicating abstraction hierarchy L1-L40 for each variable], | |
| "constraints":["list of strings using AXL operators connecting variables (e.g., 'var1 EQUALS var2 ADD 5.0')"], | |
| "cross_scope_edges": [["var_A", "var_B", "EMERGES_SCOPE" | "COMPOSES_SCOPE" | "DERIVES" | "SEQUENCES" | "CONSERVES_EDGE"]] | |
| } | |
| Do not include any explanation outside the JSON.`; | |
| // Phase 2 collapse prompt β receives kernel + fitting guide, maps symbols to values. | |
| // Domain data is allowed here. This is intentional: the latent tracing is done, | |
| // now we fit real values into the proven structural shape. | |
| // | |
| // IMPORTANT: Output format uses a line-delimited text protocol, NOT nested JSON, | |
| // because AXL kernel schemas contain brackets, quotes, and special chars that | |
| // break JSON string escaping when embedded as values. | |
| const COLLAPSE_SYSTEM_PROMPT = `You are an AXL Collapse Interpreter performing Phase 2: Real-World Fitting. | |
| You will receive: | |
| KERNEL β a fully locked AXL constraint kernel from the latent space simulation. | |
| All structural relationships, invariants, and bounds are already proven. | |
| UNKNOWN_STRUCTURAL symbols are the targets you must resolve. | |
| RESOLVED_CONTRADICT markers show tensions that were resolved and how. | |
| FITTING_GUIDE β domain values, known quantities, ranges, and target constraints | |
| provided by the user. These are the real-world anchors. | |
| YOUR TASK: | |
| 1. Read the KERNEL. Do NOT re-derive structure β it is already proven. | |
| 2. For each UNKNOWN_STRUCTURAL symbol, find the real-world value or expression | |
| from the FITTING_GUIDE that fits the symbol's structural role. | |
| 3. Map each abstract symbol to a concrete value or expression. | |
| 4. Verify each mapping satisfies the BOUND constraints in the kernel. | |
| 5. List any symbols you cannot resolve and why. | |
| COLLAPSE RULE: | |
| The solution is not calculated here β it is recognized. | |
| The structure already proves what shape the answer must have. | |
| You are only identifying which real quantity fits that shape. | |
| OUTPUT FORMAT (use EXACTLY this format β no JSON, no markdown, no extra text): | |
| COLLAPSE_BEGIN | |
| KERNEL_SATISFIED: YES|NO | |
| MAPPING: <symbol> | <value or expression> | <one-sentence justification> | |
| MAPPING: <symbol> | <value or expression> | <one-sentence justification> | |
| UNRESOLVED: <symbol> | <reason> | |
| NOTES: <optional single line of overall notes> | |
| COLLAPSE_END | |
| Rules: | |
| - One MAPPING line per resolved symbol. | |
| - One UNRESOLVED line per symbol that cannot be resolved. | |
| - No line breaks inside a MAPPING or UNRESOLVED line. | |
| - Do not add any text outside COLLAPSE_BEGIN / COLLAPSE_END.`; | |
| // ββ LOGGING & HELPERS βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| const ts = () => new Date().toISOString().slice(11, 23); | |
| const log = (msg, level = "INFO") => { | |
| const icons = { INFO: " ", WARN: "β ", ERROR: "β ", OK: "β ", HEAD: "ββ" }; | |
| console.log(`[${ts()}] ${icons[level] || " "} ${msg}`); | |
| }; | |
| // ββ CORE GENERATOR ENGINE βββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| async function callBedrock({ prompt, systemPrompt, modelId, region, maxTokens = 4096, temperature = 0.8 }) { | |
| if (!prompt) throw new Error("Missing 'prompt' argument."); | |
| const bedrockClient = new BedrockRuntimeClient({ | |
| region, | |
| requestHandler: new NodeHttpHandler({ http2Handler: undefined }) | |
| }); | |
| const command = new ConverseCommand({ | |
| modelId, | |
| system: [{ text: systemPrompt }], | |
| messages: [{ role: "user", content: [{ text: prompt }] }], | |
| inferenceConfig: { maxTokens, temperature } | |
| }); | |
| const t0 = Date.now(); | |
| log(`Calling Bedrock [${modelId.split('/').pop()}]β¦`); | |
| const response = await bedrockClient.send(command); | |
| const text = response.output.message.content.find(b => b.text)?.text || ""; | |
| const tokens = response.usage ? (response.usage.inputTokens + response.usage.outputTokens) : 0; | |
| log(`Complete in ${((Date.now()-t0)/1000).toFixed(1)}s (Tokens: ${tokens})`, "OK"); | |
| return text; | |
| } | |
| // Extract AXL payload from between tag delimiters. | |
| // Tries RESOLUTION_BEGIN/END first, then SEED_BEGIN/END, then falls back | |
| // to stripping any markdown code fences and returning raw text. | |
| function extractAXL(text, beginTag = 'RESOLUTION_BEGIN', endTag = 'RESOLUTION_END') { | |
| // Primary: tagged block | |
| const tagMatch = text.match(new RegExp(beginTag + '([\\s\\S]*?)' + endTag)); | |
| if (tagMatch) return tagMatch[1].trim(); | |
| // Secondary: JSON wrapper {"axl":"..."} β careful extraction that handles | |
| // special chars by finding the axl key and slicing rather than JSON.parse | |
| const axlKeyIdx = text.indexOf('"axl"'); | |
| if (axlKeyIdx !== -1) { | |
| const colonIdx = text.indexOf(':', axlKeyIdx); | |
| if (colonIdx !== -1) { | |
| // Find the opening quote of the value | |
| const quoteIdx = text.indexOf('"', colonIdx + 1); | |
| if (quoteIdx !== -1) { | |
| // Find the matching closing quote (unescaped) | |
| let i = quoteIdx + 1; | |
| while (i < text.length) { | |
| if (text[i] === '\\') { i += 2; continue; } | |
| if (text[i] === '"') break; | |
| i++; | |
| } | |
| const raw = text.substring(quoteIdx + 1, i); | |
| // Unescape JSON string escapes | |
| try { | |
| return raw.replace(/\\n/g, '\n').replace(/\\t/g, '\t').replace(/\\"/g, '"').replace(/\\\\/g, '\\').trim(); | |
| } catch(_) { /* fall through */ } | |
| } | |
| } | |
| } | |
| // Tertiary: strip markdown fences and return whatever we got | |
| return text.replace(/^```[a-z]*\n?/im, '').replace(/\n?```$/im, '').trim(); | |
| } | |
| async function generateSingle({ prompt, systemPrompt, instruction, modelId, region, maxTokens = 4096 }) { | |
| const userMessage = instruction | |
| ? `${prompt}\n\nInstruction: ${instruction}` | |
| : prompt; | |
| log(`Generating for: "${String(prompt).slice(0, 80)}β¦"`, "HEAD"); | |
| log(`Using Model: ${modelId}`); | |
| const text = await callBedrock({ prompt: userMessage, systemPrompt, modelId, region, maxTokens }); | |
| // For seed calls: extract axl field | |
| const axlContent = extractAXL(text, 'SEED_BEGIN', 'SEED_END') | |
| || extractAXL(text, 'RESOLUTION_BEGIN', 'RESOLUTION_END') | |
| || extractAXL(text); | |
| if (!axlContent || axlContent.length < 10) { | |
| log(`Response too short or empty after extraction.`, "WARN"); | |
| throw new Error("Model response did not contain extractable AXL content."); | |
| } | |
| const result = { axl: axlContent }; | |
| console.log(`~~~~~ AXL Output ~~~~~\n${axlContent.slice(0, 300)}β¦\n~~~~~ AXL Output end ~~~~~`); | |
| return result; | |
| } | |
| // ββ EXPORTED FUNCTIONS ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| /** | |
| * Calls the BIG AI Model (Claude Sonnet) β used for seed generation. | |
| */ | |
| export async function callbigai({ | |
| prompt, | |
| systemPrompt = DEFAULT_AXL_SYSTEM_PROMPT, | |
| instruction = "", | |
| modelId = MODEL_ID_BIG, | |
| region = DEFAULT_AWS_REGION | |
| }) { | |
| return await generateSingle({ prompt, systemPrompt, instruction, modelId, region }); | |
| } | |
| /** | |
| * Calls the SMALL AI Model (Claude Haiku) β used for ring agents. | |
| */ | |
| export async function callsmallai({ | |
| prompt, | |
| systemPrompt = DEFAULT_AXL_SYSTEM_PROMPT, | |
| instruction = "", | |
| modelId = MODEL_ID_SMALL, | |
| region = DEFAULT_AWS_REGION | |
| }) { | |
| return await generateSingle({ prompt, systemPrompt, instruction, modelId, region }); | |
| } | |
| /** | |
| * Calls the COLLAPSE Agent (Claude Sonnet) β Phase 2 real-world fitting. | |
| * | |
| * @param {string} kernel - The locked AXL constraint kernel from the last ring node. | |
| * @param {string} fittingGuide - Domain values, known quantities, ranges from the user. | |
| * @param {string} [region] | |
| * | |
| * Returns JSON: { mappings, unresolved, kernel_satisfied, notes } | |
| */ | |
| export async function callcollapse({ | |
| kernel, | |
| fittingGuide, | |
| region = DEFAULT_AWS_REGION | |
| }) { | |
| if (!kernel) throw new Error("Missing 'kernel' argument for collapse."); | |
| if (!fittingGuide) throw new Error("Missing 'fittingGuide' argument for collapse."); | |
| log(`Collapse Phase 2 β fitting ${kernel.length} char kernelβ¦`, "HEAD"); | |
| const userMessage = `KERNEL:\n${kernel}\n\nFITTING_GUIDE:\n${fittingGuide}`; | |
| let text = ''; | |
| try { | |
| text = await callBedrock({ | |
| prompt: userMessage, systemPrompt: COLLAPSE_SYSTEM_PROMPT, | |
| modelId: MODEL_ID_BIG, region, maxTokens: 2048, temperature: 0.5 | |
| }); | |
| } catch(e) { | |
| log(`Collapse failed: ${e.message}`, "ERROR"); | |
| throw e; | |
| } | |
| // Parse the line-delimited text protocol β no JSON parsing needed | |
| return parseCollapseResponse(text); | |
| } | |
| function parseCollapseResponse(text) { | |
| const body = text.match(/COLLAPSE_BEGIN([\s\S]*?)COLLAPSE_END/)?.[1] || text; | |
| const lines = body.split('\n').map(l => l.trim()).filter(Boolean); | |
| const mappings = []; | |
| const unresolved = []; | |
| let kernelSatisfied = true; | |
| let notes = ''; | |
| for (const line of lines) { | |
| if (line.startsWith('KERNEL_SATISFIED:')) { | |
| kernelSatisfied = !line.includes('NO'); | |
| } else if (line.startsWith('MAPPING:')) { | |
| const parts = line.slice('MAPPING:'.length).split('|').map(p => p.trim()); | |
| if (parts.length >= 2) { | |
| mappings.push({ | |
| symbol: parts[0] || '', | |
| value: parts[1] || '', | |
| justification: parts[2] || '' | |
| }); | |
| } | |
| } else if (line.startsWith('UNRESOLVED:')) { | |
| const parts = line.slice('UNRESOLVED:'.length).split('|').map(p => p.trim()); | |
| if (parts.length >= 1) { | |
| unresolved.push({ | |
| symbol: parts[0] || '', | |
| reason: parts[1] || '' | |
| }); | |
| } | |
| } else if (line.startsWith('NOTES:')) { | |
| notes = line.slice('NOTES:'.length).trim(); | |
| } | |
| } | |
| // Fallback: if we got nothing structured, return raw text so caller can display it | |
| if (!mappings.length && !unresolved.length) { | |
| return { | |
| mappings: [], | |
| unresolved: [], | |
| kernel_satisfied: false, | |
| notes: text.trim() || 'No structured output returned by model.', | |
| raw: text | |
| }; | |
| } | |
| return { mappings, unresolved, kernel_satisfied: kernelSatisfied, notes }; | |
| } |