Initial commit: 2125_GCE project
This commit is contained in:
Regular → Executable
+77
-583
@@ -9,111 +9,47 @@ class XICContext:
|
||||
mode: str = "chat"
|
||||
params: Dict[str, Any] = field(default_factory=dict)
|
||||
_state: Dict[str, Any] = field(default_factory=dict)
|
||||
symbolic_mode: bool = False
|
||||
glyph_contexts: list = field(default_factory=list)
|
||||
|
||||
def enqueue_chain(self, label: str):
|
||||
"""Schedule a chain/label to run next (FIFO)."""
|
||||
queue = self._state.setdefault("_chain_queue", [])
|
||||
queue.append(label)
|
||||
print(f"[XIC-QUEUE] Enqueued chain: {label}")
|
||||
|
||||
def pop_next_chain(self):
|
||||
"""Get next scheduled chain (FIFO). Returns None if queue empty."""
|
||||
queue = self._state.setdefault("_chain_queue", [])
|
||||
if queue:
|
||||
label = queue.pop(0)
|
||||
print(f"[XIC-QUEUE] Dequeued chain: {label}")
|
||||
return label
|
||||
return None
|
||||
|
||||
def jump_to(self, label: str):
|
||||
"""Immediate jump: clear queue and run label next."""
|
||||
self._state["_chain_queue"] = [label]
|
||||
print(f"[XIC-QUEUE] Jump to: {label}")
|
||||
@property
|
||||
def glyph_contexts(self) -> list:
|
||||
return self._state.get("glyph_stack", [])
|
||||
|
||||
|
||||
def op_LOAD_MODEL(ctx: XICContext, *args):
|
||||
"""LOAD_MODEL <path>: Load a .gx model file."""
|
||||
if not args:
|
||||
raise ValueError("LOAD_MODEL requires a path argument")
|
||||
model_path = args[0]
|
||||
ctx.model_path = str(model_path)
|
||||
ctx.model_path = str(args[0])
|
||||
print(f"[XIC] Model loaded: {ctx.model_path}")
|
||||
|
||||
|
||||
def op_SET_MODE(ctx: XICContext, *args):
|
||||
"""SET_MODE <mode>: Set execution mode (chat, eval, benchmark, symbolic)."""
|
||||
if not args:
|
||||
raise ValueError("SET_MODE requires a mode argument")
|
||||
ctx.mode = str(args[0])
|
||||
if ctx.mode == "symbolic":
|
||||
ctx.symbolic_mode = True
|
||||
print(f"[XIC] Mode set to: {ctx.mode}")
|
||||
|
||||
|
||||
def op_SET_PARAM(ctx: XICContext, *args):
|
||||
"""SET_PARAM <key> <value>: Set a parameter."""
|
||||
if len(args) < 2:
|
||||
raise ValueError("SET_PARAM requires key and value arguments")
|
||||
key = str(args[0])
|
||||
value = args[1]
|
||||
ctx.params[key] = value
|
||||
print(f"[XIC] Parameter {key} = {value}")
|
||||
ctx.params[str(args[0])] = args[1]
|
||||
print(f"[XIC] Parameter {args[0]} = {args[1]}")
|
||||
|
||||
|
||||
def op_RUN_PROMPT(ctx: XICContext, *args):
|
||||
"""RUN_PROMPT <prompt>: Execute prompt against loaded model or symbolic cognition.
|
||||
|
||||
Symbolic behavior (ctx.symbolic_mode=True):
|
||||
- Routes through symbolic pipeline (run_symbolic_pipeline).
|
||||
- Uses ctx.params["context"] for execution context.
|
||||
- If glyph_contexts is populated: passes glyph_ids for multi-glyph resonance
|
||||
- Stores full pipeline result in ctx._state["last_symbolic_pipeline"].
|
||||
|
||||
Compressed behavior (ctx.symbolic_mode=False):
|
||||
- Requires model_path to be set via LOAD_MODEL.
|
||||
- Routes to execute_gx() for compressed execution.
|
||||
- Stores result in ctx._state["last_result"].
|
||||
"""
|
||||
if not args:
|
||||
raise ValueError("RUN_PROMPT requires a prompt argument")
|
||||
|
||||
prompt = str(args[0])
|
||||
|
||||
if ctx.symbolic_mode:
|
||||
from glyphos.symbolic_pipeline import run_symbolic_pipeline
|
||||
|
||||
# Check for multi-glyph resonance context
|
||||
glyph_ids = None
|
||||
if ctx.glyph_contexts:
|
||||
glyph_ids = list(ctx.glyph_contexts)
|
||||
print(f"[XIC-MULTI-GLYPH] RUN_PROMPT with {len(glyph_ids)} glyphs")
|
||||
|
||||
pipeline_result = run_symbolic_pipeline(
|
||||
prompt=prompt,
|
||||
context=ctx.params.get("context"),
|
||||
glyph_ids=glyph_ids,
|
||||
)
|
||||
print(f"[XIC-SYMBOLIC] {pipeline_result.output_text}")
|
||||
ctx._state["last_symbolic_result"] = pipeline_result.output_text
|
||||
ctx._state["last_symbolic_pipeline"] = pipeline_result
|
||||
return
|
||||
|
||||
if not ctx.model_path:
|
||||
raise ValueError("No model loaded. Use LOAD_MODEL first.")
|
||||
|
||||
try:
|
||||
execution_context = execute_gx(
|
||||
ctx.model_path,
|
||||
trace=ctx.params.get("trace", False),
|
||||
profile=ctx.params.get("profile", False)
|
||||
profile=ctx.params.get("profile", False),
|
||||
)
|
||||
|
||||
print(f"[XIC] Execution complete")
|
||||
print(f"[XIC] Result: {getattr(execution_context, 'result', 'OK')}")
|
||||
ctx._state["last_result"] = execution_context
|
||||
|
||||
except ExecutionError as e:
|
||||
print(f"[XIC] Execution error: {e}")
|
||||
raise
|
||||
@@ -122,539 +58,97 @@ def op_RUN_PROMPT(ctx: XICContext, *args):
|
||||
raise
|
||||
|
||||
|
||||
def op_STREAM(ctx: XICContext, *args):
|
||||
"""STREAM <prompt>: Execute and stream output line by line.
|
||||
|
||||
Symbolic behavior (ctx.symbolic_mode=True):
|
||||
- Routes through symbolic pipeline.
|
||||
- If glyph_contexts is populated: passes glyph_ids for multi-glyph resonance
|
||||
- Streams output_text line by line with [XIC-STREAM] prefix.
|
||||
- Stores pipeline result in ctx._state["last_symbolic_pipeline"].
|
||||
|
||||
Compressed behavior (ctx.symbolic_mode=False):
|
||||
- Routes to execute_gx().
|
||||
- Streams result line by line with [XIC-STREAM] prefix.
|
||||
- Stores result in ctx._state["last_result"].
|
||||
"""
|
||||
if not args:
|
||||
raise ValueError("STREAM requires a prompt argument")
|
||||
prompt = str(args[0])
|
||||
|
||||
if ctx.symbolic_mode:
|
||||
from glyphos.symbolic_pipeline import run_symbolic_pipeline
|
||||
|
||||
# Check for multi-glyph resonance context
|
||||
glyph_ids = None
|
||||
if ctx.glyph_contexts:
|
||||
glyph_ids = list(ctx.glyph_contexts)
|
||||
print(f"[XIC-MULTI-GLYPH] STREAM with {len(glyph_ids)} glyphs")
|
||||
|
||||
pipeline_result = run_symbolic_pipeline(
|
||||
prompt=prompt,
|
||||
context=ctx.params.get("context"),
|
||||
glyph_ids=glyph_ids,
|
||||
)
|
||||
for chunk in str(pipeline_result.output_text).split("\n"):
|
||||
if chunk.strip():
|
||||
print(f"[XIC-STREAM] {chunk}")
|
||||
ctx._state["last_symbolic_result"] = pipeline_result.output_text
|
||||
ctx._state["last_symbolic_pipeline"] = pipeline_result
|
||||
return
|
||||
|
||||
if not ctx.model_path:
|
||||
raise ValueError("No model loaded. Use LOAD_MODEL first.")
|
||||
|
||||
try:
|
||||
exec_ctx = execute_gx(
|
||||
ctx.model_path,
|
||||
trace=ctx.params.get("trace", False),
|
||||
profile=ctx.params.get("profile", False),
|
||||
)
|
||||
result_text = str(getattr(exec_ctx, "result", "OK"))
|
||||
for chunk in result_text.split("\n"):
|
||||
if chunk.strip():
|
||||
print(f"[XIC-STREAM] {chunk}")
|
||||
ctx._state["last_result"] = exec_ctx
|
||||
except ExecutionError as e:
|
||||
print(f"[XIC] Execution error: {e}")
|
||||
raise
|
||||
except Exception as e:
|
||||
print(f"[XIC] Unexpected error: {e}")
|
||||
raise
|
||||
|
||||
|
||||
def op_CHAIN(ctx: XICContext, *args):
|
||||
"""CHAIN <label>: Mark start of a named chain; passes context forward."""
|
||||
if not args:
|
||||
raise ValueError("CHAIN requires a label argument")
|
||||
label = str(args[0])
|
||||
ctx.params["chain_label"] = label
|
||||
print(f"[XIC-CHAIN] Entering chain: {label}")
|
||||
|
||||
|
||||
def op_CALL_GLYPH(ctx: XICContext, *args):
|
||||
"""CALL_GLYPH <glyph_id> <payload>: Invoke glyph-aware cognition with resonance tracking.
|
||||
|
||||
Routes through symbolic pipeline with explicit glyph_id parameter.
|
||||
If glyph_contexts is populated, enables multi-glyph resonance computation.
|
||||
|
||||
Single-glyph behavior:
|
||||
- glyph_id is propagated into pipeline context for LAIN transformations
|
||||
- Stores result in ctx._state[f"glyph_{glyph_id}"]
|
||||
|
||||
Multi-glyph behavior (if glyph_contexts is non-empty):
|
||||
- Passes full glyph_ids list to symbolic pipeline
|
||||
- Computes resonance across all accumulated glyphs
|
||||
- Stores multi-glyph result in ctx._state[f"glyph_{glyph_id}"]
|
||||
- Also stores in ctx._state["last_multi_glyph_result"]
|
||||
|
||||
Stores comprehensive result with:
|
||||
- output_text: Final text from cognition
|
||||
- fused_symbol: Fused symbolic representation with glyph_ids and resonance_map
|
||||
- resonance_metrics: Extracted per-glyph resonance scores
|
||||
- global_resonance_score: Overall resonance from LAIN
|
||||
- steps: List of symbolic pipeline steps
|
||||
- multi_glyph: True if multiple glyphs were processed
|
||||
"""
|
||||
if not args:
|
||||
raise ValueError("CALL_GLYPH requires glyph_id argument")
|
||||
glyph_id = str(args[0])
|
||||
payload = str(args[1]) if len(args) > 1 else ""
|
||||
|
||||
from glyphos.symbolic_pipeline import (
|
||||
run_symbolic_pipeline,
|
||||
extract_glyph_resonances,
|
||||
format_glyph_resonance_report,
|
||||
)
|
||||
|
||||
glyph_context = dict(ctx.params.get("context", {}))
|
||||
glyph_context["glyph_id"] = glyph_id
|
||||
|
||||
# Determine if using multi-glyph resonance
|
||||
multi_glyph_ids = None
|
||||
if ctx.glyph_contexts:
|
||||
multi_glyph_ids = list(ctx.glyph_contexts)
|
||||
if glyph_id not in multi_glyph_ids:
|
||||
multi_glyph_ids.append(glyph_id)
|
||||
print(f"[XIC-MULTI-GLYPH] CALL_GLYPH using multi-glyph resonance with {len(multi_glyph_ids)} glyphs")
|
||||
is_multi = True
|
||||
else:
|
||||
is_multi = False
|
||||
|
||||
# Call pipeline with appropriate glyph parameter
|
||||
if is_multi:
|
||||
pipeline_result = run_symbolic_pipeline(
|
||||
prompt=payload,
|
||||
context=glyph_context,
|
||||
glyph_ids=multi_glyph_ids,
|
||||
)
|
||||
else:
|
||||
pipeline_result = run_symbolic_pipeline(
|
||||
prompt=payload,
|
||||
context=glyph_context,
|
||||
glyph_id=glyph_id,
|
||||
)
|
||||
|
||||
print(f"[XIC-GLYPH] {pipeline_result.output_text}")
|
||||
|
||||
# Extract resonance metrics
|
||||
resonance_metrics = extract_glyph_resonances(pipeline_result)
|
||||
global_resonance = 0.0
|
||||
if pipeline_result.fused_symbol and pipeline_result.fused_symbol.resonance_map:
|
||||
global_resonance = pipeline_result.fused_symbol.resonance_map.global_resonance_score
|
||||
|
||||
# Store comprehensive result
|
||||
result_dict = {
|
||||
"output_text": pipeline_result.output_text,
|
||||
"fused_symbol": {
|
||||
"summary": pipeline_result.fused_symbol.summary if pipeline_result.fused_symbol else None,
|
||||
"glyph_ids": pipeline_result.fused_symbol.glyph_ids if pipeline_result.fused_symbol else [],
|
||||
} if pipeline_result.fused_symbol else None,
|
||||
"resonance_metrics": resonance_metrics,
|
||||
"global_resonance_score": global_resonance,
|
||||
"steps": [{"name": s.name, "kind": s.kind, "payload": str(s.payload)[:100]}
|
||||
for s in pipeline_result.steps],
|
||||
"multi_glyph": is_multi,
|
||||
}
|
||||
|
||||
ctx._state[f"glyph_{glyph_id}"] = result_dict
|
||||
|
||||
# Also store for direct query access
|
||||
ctx._state[f"glyph_{glyph_id}_pipeline_result"] = pipeline_result
|
||||
|
||||
# Store multi-glyph result for later reference
|
||||
if is_multi:
|
||||
ctx._state["last_multi_glyph_result"] = result_dict
|
||||
|
||||
# Store telemetry
|
||||
ctx._state["last_resonance_stats"] = {
|
||||
"glyph_count": len(multi_glyph_ids),
|
||||
"global_resonance_score": global_resonance,
|
||||
"guardrails_triggered": [],
|
||||
"timestamp": __import__("time").time(),
|
||||
}
|
||||
|
||||
|
||||
def op_SET_CONTEXT(ctx: XICContext, *args):
|
||||
"""SET_CONTEXT <key> <value>: Set symbolic/cognitive context key."""
|
||||
if len(args) < 2:
|
||||
raise ValueError("SET_CONTEXT requires key and value")
|
||||
if "context" not in ctx.params:
|
||||
ctx.params["context"] = {}
|
||||
key = str(args[0])
|
||||
value = args[1]
|
||||
ctx.params["context"][key] = value
|
||||
print(f"[XIC] Context {key} = {value}")
|
||||
|
||||
|
||||
def op_LOG(ctx: XICContext, *args):
|
||||
"""LOG <message>: Structured log from XIC program."""
|
||||
message = str(args[0]) if args else ""
|
||||
print(f"[XIC-LOG] {message}")
|
||||
raise ValueError("SET_CONTEXT requires key and value arguments")
|
||||
ctx._state[str(args[0])] = args[1]
|
||||
print(f"[XIC] Context {args[0]} = {args[1]}")
|
||||
|
||||
|
||||
def op_PUSH_GLYPH_CONTEXT(ctx: XICContext, *args):
|
||||
"""PUSH_GLYPH_CONTEXT <glyph_id>: Add glyph to multi-glyph resonance context.
|
||||
|
||||
Accumulates glyph IDs for multi-glyph resonance computation. Used with
|
||||
CALL_GLYPH to enable resonance across multiple glyphs simultaneously.
|
||||
|
||||
Stores glyph_id in ctx.glyph_contexts list.
|
||||
Respects guardrails: max_resonance_glyphs (default 10).
|
||||
"""
|
||||
if not args:
|
||||
raise ValueError("PUSH_GLYPH_CONTEXT requires glyph_id argument")
|
||||
|
||||
glyph_id = str(args[0])
|
||||
|
||||
# Initialize guardrail defaults if not already set
|
||||
if "max_resonance_glyphs" not in ctx.params:
|
||||
ctx.params["max_resonance_glyphs"] = 10
|
||||
if "enable_resonance_guardrails" not in ctx.params:
|
||||
ctx.params["enable_resonance_guardrails"] = True
|
||||
|
||||
max_glyphs = ctx.params["max_resonance_glyphs"]
|
||||
enable_guardrails = ctx.params["enable_resonance_guardrails"]
|
||||
|
||||
# Check guardrails
|
||||
if enable_guardrails and len(ctx.glyph_contexts) >= max_glyphs:
|
||||
print(f"[XIC-GUARDRAIL] Resonance glyph count at limit ({max_glyphs})")
|
||||
raise ValueError("PUSH_GLYPH_CONTEXT requires a glyph argument")
|
||||
glyph_uri = str(args[0])
|
||||
stack = ctx._state.setdefault("glyph_stack", [])
|
||||
max_glyphs = ctx.params.get("max_resonance_glyphs", 10)
|
||||
guardrails = ctx.params.get("enable_resonance_guardrails", False)
|
||||
if guardrails and len(stack) >= max_glyphs:
|
||||
print(f"[XIC] Guardrail blocked glyph push: {glyph_uri} (max {max_glyphs})")
|
||||
return
|
||||
if glyph_uri not in stack:
|
||||
stack.append(glyph_uri)
|
||||
print(f"[XIC] Pushed glyph context: {glyph_uri}")
|
||||
else:
|
||||
print(f"[XIC] Duplicate glyph ignored: {glyph_uri}")
|
||||
|
||||
if glyph_id not in ctx.glyph_contexts:
|
||||
ctx.glyph_contexts.append(glyph_id)
|
||||
print(f"[XIC-MULTI-GLYPH] Pushed glyph context: {glyph_id} (total: {len(ctx.glyph_contexts)})")
|
||||
|
||||
def op_CHAIN(ctx: XICContext, *args):
|
||||
if not args:
|
||||
raise ValueError("CHAIN requires a target symbol argument")
|
||||
target = str(args[0])
|
||||
if target not in ctx._state.get("_program", {}).get("symbols", {}):
|
||||
raise ValueError(f"Unknown symbol: {target}")
|
||||
ctx._state["chain_target"] = target
|
||||
print(f"[XIC] Chaining to symbol: {target}")
|
||||
|
||||
|
||||
def op_LOG(ctx: XICContext, *args):
|
||||
if not args:
|
||||
raise ValueError("LOG requires a message argument")
|
||||
message = str(args[0])
|
||||
print(f"[XIC] LOG: {message}")
|
||||
|
||||
|
||||
def op_CLEAR_GLYPH_CONTEXT(ctx: XICContext, *args):
|
||||
"""CLEAR_GLYPH_CONTEXT: Clear accumulated glyph resonance context.
|
||||
ctx._state["glyph_stack"] = []
|
||||
print(f"[XIC] Cleared glyph context")
|
||||
|
||||
Resets the glyph context list, removing all accumulated glyph IDs.
|
||||
Use before starting a new multi-glyph analysis chain.
|
||||
"""
|
||||
count = len(ctx.glyph_contexts)
|
||||
ctx.glyph_contexts.clear()
|
||||
print(f"[XIC-MULTI-GLYPH] Cleared glyph context ({count} glyphs removed)")
|
||||
|
||||
def op_CALL_GLYPH(ctx: XICContext, *args):
|
||||
if len(args) < 2:
|
||||
raise ValueError("CALL_GLYPH requires glyph_id and prompt arguments")
|
||||
glyph_id = str(args[0])
|
||||
prompt = str(args[1])
|
||||
glyph_ids = ctx._state.get("glyph_stack", [])
|
||||
try:
|
||||
from glyphos.symbolic_pipeline import run_symbolic_pipeline
|
||||
result = run_symbolic_pipeline(
|
||||
prompt=prompt,
|
||||
glyph_id=glyph_id,
|
||||
glyph_ids=glyph_ids if glyph_ids else None,
|
||||
context=dict(ctx.params.get("context", {})),
|
||||
)
|
||||
ctx._state["last_pipeline_result"] = result
|
||||
print(f"[XIC] Glyph {glyph_id} called with prompt: {prompt[:40]}...")
|
||||
except Exception as e:
|
||||
print(f"[XIC] CALL_GLYPH error: {e}")
|
||||
|
||||
|
||||
def op_GET_GLYPH_RESONANCE(ctx: XICContext, *args):
|
||||
"""GET_GLYPH_RESONANCE <glyph_id> [metric]: Query glyph resonance metrics from previous CALL_GLYPH.
|
||||
|
||||
Retrieves resonance data stored by CALL_GLYPH and provides:
|
||||
- No metric arg: Returns formatted resonance report for the glyph
|
||||
- metric="weight" | "lineage" | "contributor" | "frequency" | "grammar": Returns specific metric for glyph
|
||||
- metric="global": Returns global resonance score
|
||||
- metric="dominant": Returns top 5 dominant glyphs by weight
|
||||
|
||||
Results are printed and stored in ctx._state["resonance_query_<glyph_id>_<metric>"]
|
||||
"""
|
||||
if not args:
|
||||
raise ValueError("GET_GLYPH_RESONANCE requires glyph_id argument")
|
||||
|
||||
glyph_id = str(args[0])
|
||||
metric = str(args[1]) if len(args) > 1 else None
|
||||
|
||||
# Try to find the stored glyph result
|
||||
glyph_key = f"glyph_{glyph_id}"
|
||||
if glyph_key not in ctx._state:
|
||||
print(f"[XIC-RESONANCE] No resonance data for glyph: {glyph_id}")
|
||||
ctx._state[f"resonance_query_{glyph_id}_notfound"] = None
|
||||
return
|
||||
|
||||
glyph_data = ctx._state[glyph_key]
|
||||
|
||||
# If we have the pipeline result object, use it to regenerate report
|
||||
pipeline_key = f"glyph_{glyph_id}_pipeline_result"
|
||||
if pipeline_key in ctx._state:
|
||||
from glyphos.symbolic_pipeline import (
|
||||
format_glyph_resonance_report,
|
||||
extract_glyph_resonances,
|
||||
get_dominant_glyphs,
|
||||
)
|
||||
pipeline_result = ctx._state[pipeline_key]
|
||||
|
||||
if metric is None or metric == "report":
|
||||
report = format_glyph_resonance_report(pipeline_result)
|
||||
print(f"[XIC-RESONANCE] Report for {glyph_id}:\n{report}")
|
||||
ctx._state[f"resonance_query_{glyph_id}_report"] = report
|
||||
elif metric == "global":
|
||||
if pipeline_result.fused_symbol:
|
||||
score = pipeline_result.fused_symbol.resonance_map.global_resonance_score
|
||||
print(f"[XIC-RESONANCE] Global resonance for {glyph_id}: {score:.3f}")
|
||||
ctx._state[f"resonance_query_{glyph_id}_global"] = score
|
||||
else:
|
||||
print(f"[XIC-RESONANCE] No fused_symbol for {glyph_id}")
|
||||
ctx._state[f"resonance_query_{glyph_id}_global"] = None
|
||||
elif metric == "dominant":
|
||||
dominant = get_dominant_glyphs(pipeline_result, n=5)
|
||||
print(f"[XIC-RESONANCE] Dominant glyphs for {glyph_id}:")
|
||||
for glyph, weight in dominant:
|
||||
print(f" {glyph}: {weight:.3f}")
|
||||
ctx._state[f"resonance_query_{glyph_id}_dominant"] = dominant
|
||||
elif metric in ["weight", "lineage", "contributor", "frequency", "grammar"]:
|
||||
resonances = extract_glyph_resonances(pipeline_result)
|
||||
if glyph_id in resonances:
|
||||
metric_val = resonances[glyph_id].get(
|
||||
metric if metric != "lineage" else "lineage_score",
|
||||
resonances[glyph_id].get(f"{metric}_score") if metric != "weight" else None
|
||||
)
|
||||
if metric == "lineage":
|
||||
metric_val = resonances[glyph_id].get("lineage_score")
|
||||
elif metric == "contributor":
|
||||
metric_val = resonances[glyph_id].get("contributor_score")
|
||||
elif metric == "frequency":
|
||||
metric_val = resonances[glyph_id].get("frequency_score")
|
||||
elif metric == "grammar":
|
||||
metric_val = resonances[glyph_id].get("grammar_score")
|
||||
|
||||
if metric_val is not None:
|
||||
print(f"[XIC-RESONANCE] {metric} for {glyph_id}: {metric_val:.3f}")
|
||||
ctx._state[f"resonance_query_{glyph_id}_{metric}"] = metric_val
|
||||
else:
|
||||
print(f"[XIC-RESONANCE] Metric '{metric}' not found for {glyph_id}")
|
||||
ctx._state[f"resonance_query_{glyph_id}_{metric}"] = None
|
||||
else:
|
||||
print(f"[XIC-RESONANCE] Glyph {glyph_id} not in resonance data")
|
||||
ctx._state[f"resonance_query_{glyph_id}_{metric}"] = None
|
||||
else:
|
||||
print(f"[XIC-RESONANCE] Unknown metric: {metric}")
|
||||
ctx._state[f"resonance_query_{glyph_id}_{metric}"] = None
|
||||
result = ctx._state.get("last_pipeline_result")
|
||||
if result and hasattr(result, 'fused_symbol') and result.fused_symbol:
|
||||
res = result.fused_symbol.resonance_map
|
||||
print(f"[XIC] Global Resonance: {res.global_resonance_score:.3f}")
|
||||
print(f"[XIC] Glyphs Engaged: {len(res.resonances)}")
|
||||
else:
|
||||
# Fallback: use stored resonance_metrics if available
|
||||
if "resonance_metrics" in glyph_data:
|
||||
resonance_metrics = glyph_data["resonance_metrics"]
|
||||
if metric is None:
|
||||
print(f"[XIC-RESONANCE] Resonance metrics for {glyph_id}:")
|
||||
for glyph, metrics_dict in resonance_metrics.items():
|
||||
print(f" {glyph}: weight={metrics_dict.get('weight', 0):.3f}")
|
||||
ctx._state[f"resonance_query_{glyph_id}_report"] = resonance_metrics
|
||||
elif metric == "global":
|
||||
score = glyph_data.get("global_resonance_score", 0.0)
|
||||
print(f"[XIC-RESONANCE] Global resonance for {glyph_id}: {score:.3f}")
|
||||
ctx._state[f"resonance_query_{glyph_id}_global"] = score
|
||||
else:
|
||||
print(f"[XIC-RESONANCE] Specific metric query requires pipeline result")
|
||||
ctx._state[f"resonance_query_{glyph_id}_{metric}"] = None
|
||||
else:
|
||||
print(f"[XIC-RESONANCE] No resonance metrics available for {glyph_id}")
|
||||
ctx._state[f"resonance_query_{glyph_id}_notfound"] = None
|
||||
print("[XIC] No resonance data available")
|
||||
|
||||
|
||||
def op_IF(ctx: XICContext, *args):
|
||||
"""IF <predicate> <then_label> [<else_label>]
|
||||
|
||||
Evaluates predicate against last symbolic result and enqueues appropriate chain.
|
||||
|
||||
Predicate examples:
|
||||
"fused.global_resonance_score > 0.8"
|
||||
"dominant_contains('glyph://entropy')"
|
||||
"""
|
||||
if len(args) < 2:
|
||||
raise ValueError("IF requires predicate and then_label")
|
||||
|
||||
from glyphos.control.predicate import eval_predicate
|
||||
|
||||
predicate = str(args[0])
|
||||
then_label = str(args[1])
|
||||
else_label = str(args[2]) if len(args) > 2 else None
|
||||
|
||||
# Extract fused symbol from last symbolic execution
|
||||
pipeline = ctx._state.get("last_symbolic_pipeline")
|
||||
fused_dict = {}
|
||||
dominant = []
|
||||
|
||||
if pipeline and hasattr(pipeline, "fused_symbol") and pipeline.fused_symbol:
|
||||
fused = pipeline.fused_symbol
|
||||
# Build dict representation for predicate evaluation
|
||||
fused_dict = {
|
||||
"global_resonance_score": fused.resonance_map.global_resonance_score if fused.resonance_map else 0.0,
|
||||
"glyph_ids": fused.glyph_ids,
|
||||
}
|
||||
# Extract dominant glyphs for helper function
|
||||
if fused.resonance_map:
|
||||
dominant = [(g, m.weight) for g, m in fused.resonance_map.get_top_glyphs(5)]
|
||||
|
||||
# Evaluate predicate
|
||||
try:
|
||||
pred_result = eval_predicate(predicate, fused_dict, dominant)
|
||||
except Exception as e:
|
||||
print(f"[XIC-CONTROL] IF predicate evaluation error: {e}")
|
||||
return
|
||||
|
||||
# Log control step
|
||||
ctx._state.setdefault("control_steps", []).append({
|
||||
"type": "if",
|
||||
"predicate": predicate,
|
||||
"result": pred_result
|
||||
})
|
||||
|
||||
# Emit symbolic step
|
||||
ctx._state.setdefault("symbolic_steps", []).append({
|
||||
"name": "if",
|
||||
"kind": "control_if",
|
||||
"payload": {"predicate": predicate, "result": pred_result}
|
||||
})
|
||||
|
||||
print(f"[XIC-CONTROL] IF {predicate} => {pred_result}")
|
||||
|
||||
# Enqueue appropriate chain
|
||||
if pred_result:
|
||||
ctx.enqueue_chain(then_label)
|
||||
elif else_label:
|
||||
ctx.enqueue_chain(else_label)
|
||||
def op_NOP(ctx: XICContext, *args):
|
||||
pass
|
||||
|
||||
|
||||
def op_MATCH(ctx: XICContext, *args):
|
||||
"""MATCH <path> <pattern> <then_label>
|
||||
|
||||
Pattern match against fused_symbol fields.
|
||||
Supports: fused.glyph_ids (checks if pattern is in list)
|
||||
"""
|
||||
if len(args) < 3:
|
||||
raise ValueError("MATCH requires path, pattern, then_label")
|
||||
|
||||
path = str(args[0]) # e.g., "fused.glyph_ids"
|
||||
pattern = str(args[1])
|
||||
then_label = str(args[2])
|
||||
|
||||
# Extract fused symbol
|
||||
pipeline = ctx._state.get("last_symbolic_pipeline")
|
||||
matched = False
|
||||
|
||||
if pipeline and hasattr(pipeline, "fused_symbol") and pipeline.fused_symbol:
|
||||
fused = pipeline.fused_symbol
|
||||
# Support fused.glyph_ids pattern matching
|
||||
if path == "fused.glyph_ids":
|
||||
matched = pattern in fused.glyph_ids
|
||||
|
||||
# Log control step
|
||||
ctx._state.setdefault("symbolic_steps", []).append({
|
||||
"name": "match",
|
||||
"kind": "control_match",
|
||||
"payload": {"path": path, "pattern": pattern, "result": matched}
|
||||
})
|
||||
|
||||
print(f"[XIC-CONTROL] MATCH {path} contains {pattern} => {matched}")
|
||||
|
||||
if matched:
|
||||
ctx.enqueue_chain(then_label)
|
||||
|
||||
|
||||
def op_LOOP(ctx: XICContext, *args):
|
||||
"""LOOP <predicate> <body_label> [max_iter]
|
||||
|
||||
Repeatedly enqueue body_label while predicate is true.
|
||||
Guarded by max_iter and max_total_steps guardrails.
|
||||
|
||||
Note: Unlike traditional loops, this schedules iterations in the queue
|
||||
for execution by the main loop. Each iteration runs the body_label.
|
||||
"""
|
||||
if len(args) < 2:
|
||||
raise ValueError("LOOP requires predicate and body_label")
|
||||
|
||||
from glyphos.control.predicate import eval_predicate
|
||||
|
||||
predicate = str(args[0])
|
||||
body_label = str(args[1])
|
||||
max_iter = int(args[2]) if len(args) > 2 else int(ctx.params.get("max_loop_iterations", 50))
|
||||
|
||||
iter_count = 0
|
||||
|
||||
while iter_count < max_iter:
|
||||
# Check global guardrail
|
||||
total_steps = int(ctx._state.get("total_steps", 0))
|
||||
max_total_steps = int(ctx.params.get("max_total_steps", 1000))
|
||||
|
||||
if total_steps >= max_total_steps:
|
||||
ctx._state.setdefault("guardrails", []).append("max_total_steps_exceeded")
|
||||
ctx._state.setdefault("symbolic_steps", []).append({
|
||||
"name": "guardrail",
|
||||
"kind": "guardrail",
|
||||
"payload": "max_total_steps_exceeded"
|
||||
})
|
||||
print(f"[XIC-CONTROL] LOOP guardrail: max_total_steps exceeded ({total_steps})")
|
||||
break
|
||||
|
||||
# Evaluate loop predicate
|
||||
pipeline = ctx._state.get("last_symbolic_pipeline")
|
||||
fused_dict = {}
|
||||
dominant = []
|
||||
|
||||
if pipeline and hasattr(pipeline, "fused_symbol") and pipeline.fused_symbol:
|
||||
fused = pipeline.fused_symbol
|
||||
fused_dict = {
|
||||
"global_resonance_score": fused.resonance_map.global_resonance_score if fused.resonance_map else 0.0,
|
||||
"glyph_ids": fused.glyph_ids,
|
||||
}
|
||||
if fused.resonance_map:
|
||||
dominant = [(g, m.weight) for g, m in fused.resonance_map.get_top_glyphs(5)]
|
||||
|
||||
try:
|
||||
should_continue = eval_predicate(predicate, fused_dict, dominant)
|
||||
except Exception as e:
|
||||
print(f"[XIC-CONTROL] LOOP predicate evaluation error: {e}")
|
||||
should_continue = False
|
||||
|
||||
if not should_continue:
|
||||
print(f"[XIC-CONTROL] LOOP condition false, exiting")
|
||||
break
|
||||
|
||||
# Schedule body execution
|
||||
ctx.enqueue_chain(body_label)
|
||||
ctx._state.setdefault("symbolic_steps", []).append({
|
||||
"name": "loop_iter",
|
||||
"kind": "control_loop",
|
||||
"payload": {"iteration": iter_count + 1, "predicate": predicate}
|
||||
})
|
||||
|
||||
print(f"[XIC-CONTROL] LOOP iteration {iter_count + 1}: enqueued {body_label}")
|
||||
iter_count += 1
|
||||
|
||||
if iter_count >= max_iter:
|
||||
ctx._state.setdefault("guardrails", []).append("max_loop_iterations_exceeded")
|
||||
ctx._state.setdefault("symbolic_steps", []).append({
|
||||
"name": "guardrail",
|
||||
"kind": "guardrail",
|
||||
"payload": "max_loop_iterations_exceeded"
|
||||
})
|
||||
print(f"[XIC-CONTROL] LOOP guardrail: max_loop_iterations exceeded ({iter_count})")
|
||||
|
||||
|
||||
# Operation dispatch table
|
||||
OP_TABLE = {
|
||||
"LOAD_MODEL": op_LOAD_MODEL,
|
||||
"SET_MODE": op_SET_MODE,
|
||||
"SET_PARAM": op_SET_PARAM,
|
||||
"SET_CONTEXT": op_SET_CONTEXT,
|
||||
"RUN_PROMPT": op_RUN_PROMPT,
|
||||
"STREAM": op_STREAM,
|
||||
"CHAIN": op_CHAIN,
|
||||
"CALL_GLYPH": op_CALL_GLYPH,
|
||||
"PUSH_GLYPH_CONTEXT": op_PUSH_GLYPH_CONTEXT,
|
||||
"LOAD_MODEL": op_LOAD_MODEL,
|
||||
"SET_MODE": op_SET_MODE,
|
||||
"SET_PARAM": op_SET_PARAM,
|
||||
"RUN_PROMPT": op_RUN_PROMPT,
|
||||
"SET_CONTEXT": op_SET_CONTEXT,
|
||||
"PUSH_GLYPH_CONTEXT": op_PUSH_GLYPH_CONTEXT,
|
||||
"CLEAR_GLYPH_CONTEXT": op_CLEAR_GLYPH_CONTEXT,
|
||||
"CALL_GLYPH": op_CALL_GLYPH,
|
||||
"GET_GLYPH_RESONANCE": op_GET_GLYPH_RESONANCE,
|
||||
"LOG": op_LOG,
|
||||
"IF": op_IF,
|
||||
"MATCH": op_MATCH,
|
||||
"LOOP": op_LOOP,
|
||||
"NOP": op_NOP,
|
||||
"CHAIN": op_CHAIN,
|
||||
"LOG": op_LOG,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user