#4764 AI Assisted Problem Solving (AIPS) for Various Problem Types
#4764 AI Assisted Problem Solving (AIPS) for Various Problem Types
#4764 AI Assisted Problem Solving (AIPS) for various problem types
1. User specifies initial problem statement
2. Understand and reframe initial problem statement
3. Determine one or more objectives that must be met
4. For each objective,
4.a. define the current state
4.b. define the ideal final result IFR)
4.c. determine what must be done to accomplish the IFR
4.d. determine how to accomplish the objective IFR
4.e. do it
5. Define AI agents needed to solve the problem
5.a. Define pydantic classes to define the metadata of an agent (role, persona, system prompt, tool capabilities, upstream dependencies, and expected outputs)
5.b. Define structured LLM orchestration
6. Perform
7. View
7.a. Mind Map
7.a.1. Initial User-Specified Problem Statement
7.a.2. Reframed Problem Statement
7.a.3. Objective(s)
7.a.3.i. Current State
7.a.3.ii. Ideal Final Result (IFR)
7.a.3.iii. Steps needed to accomplish objective
7.a.3.iii.(a). Step
7.a.3.iii.(b). Progress (%)
8. User Interaction
8.a. Select a step and request two or more alternative paths
9 Final Report
9.a. Reframed Problem Statement
9.b. Objectives
9.b.1. Ideal Final Result (IFR)
9.b.2. Achieved final result
9.c. Summary of accomplishment(s)
9.d. Summary of final position
9.e. Next Steps
The AI-Assisted Problem Solving (AIPS) architecture formalizes the full lifecycle—from TRIZ-inspired problem framing (Current State vs. Ideal Final Result) to multi-agent Pydantic schemas, orchestration, visual state mapping, and branch exploration.
Core Data Architecture (Steps 1–5a)
Below is the concrete Pydantic schema stack required to define agents, objectives, operational steps, and problem metadata.
from enum import Enum
from typing import Any, Callable, Dict, List, Optional
from pydantic import BaseModel, Field
class ExecutionStatus(str, Enum):
PENDING = "pending"
IN_PROGRESS = "in_progress"
COMPLETED = "completed"
BLOCKED = "blocked"
class ToolCapability(BaseModel):
name: str
description: str
schema_definition: Dict[str, Any]
endpoint_or_callable: Optional[str] = None
class AgentMetadata(BaseModel):
agent_id: str = Field(..., description="Unique slug for the agent")
role: str = Field(..., description="Functional position, e.g., 'Lead Synthesis Architect'")
persona: str = Field(..., description="Behavioral profile, tone, and cognitive bias constraints")
system_prompt: str = Field(..., description="Core behavioral instructions and guardrails")
tool_capabilities: List[ToolCapability] = Field(default_factory=list)
upstream_dependencies: List[str] = Field(
default_factory=list,
description="List of agent_ids whose outputs are required before execution"
)
expected_outputs: Dict[str, str] = Field(
..., description="Key-value mapping of field name to semantic output specification"
)
class StepPlan(BaseModel):
step_id: str
title: str
what_to_do: str
how_to_do: str
assigned_agent_id: str
progress_pct: float = Field(default=0.0, ge=0.0, le=100.0)
status: ExecutionStatus = ExecutionStatus.PENDING
alternative_branches: Optional[List[str]] = Field(
default=None, description="Explored alternatives when branched"
)
class ObjectiveRecord(BaseModel):
objective_id: str
title: str
current_state: str = Field(..., description="Baseline parameters and friction points")
ideal_final_result: str = Field(..., description="TRIZ IFR: Objective met with zero overhead or harm")
steps: List[StepPlan]
achieved_result: Optional[str] = None
class ProblemContext(BaseModel):
raw_statement: str
reframed_statement: str
objectives: List[ObjectiveRecord]
active_agents: List[AgentMetadata]
Orchestration Engine (Step 5b & 6)
The engine enforces a Directed Acyclic Graph (DAG) workflow, executing agents only when all upstream_dependencies are resolved.
import networkx as nx
class AIPSOrchestrator:
def __init__(self, context: ProblemContext):
self.context = context
self.graph = nx.DiGraph()
self._build_graph()
def _build_graph(self):
agent_map = {a.agent_id: a for a in self.context.active_agents}
for agent_id, agent in agent_map.items():
self.graph.add_node(agent_id, metadata=agent)
for upstream in agent.upstream_dependencies:
self.graph.add_edge(upstream, agent_id)
if not nx.is_directed_acyclic_graph(self.graph):
raise ValueError("Cyclic dependency detected in agent workflow topology.")
def run_stage(self, objective_id: str, step_id: str) -> Dict[str, Any]:
"""Executes a specific step using the assigned agent and resolved dependencies."""
obj = next(o for o in self.context.objectives if o.objective_id == objective_id)
step = next(s for s in obj.steps if s.step_id == step_id)
agent = next(a for a in self.context.active_agents if a.agent_id == step.assigned_agent_id)
step.status = ExecutionStatus.IN_PROGRESS
# 1. Collect outputs from upstream dependencies
# 2. Invoke structured LLM with agent.system_prompt + tools
# 3. Update step progress
step.progress_pct = 100.0
step.status = ExecutionStatus.COMPLETED
return {"status": "success", "agent_id": agent.agent_id, "step_id": step_id}
Interactive Visual Mind Map & Branch Explorer (Steps 7 & 8)
Below is an interactive console representing the AIPS State Tree. You can inspect the reframed problem, drill down into current vs. IFR states, inspect live execution percentages, and generate alternative execution branches for any step.
{
"widgetSpec": {
"height": "600px",
"prompt": "**Objective:** Render an interactive AIPS (AI Assisted Problem Solving) visual tree explorer that maps the problem hierarchy, step progress, and branch divergence. \n **Data State:** Default problem: Raw: 'Customer churn is increasing.' Reframed: 'The proactive intervention loop fails to detect value decay prior to contract renewal.' Objective 1: 'Automate value decay detection.' Current State: 'Manual bi-monthly CSM check-ins with 18% churn.' IFR: 'Self-monitoring telemetry flags decay instantly with zero CSM overhead.' Steps: 1. 'Telemetry feature pipeline setup' (100%), 2. 'Drift scoring model' (65%), 3. 'Automated retention playbook trigger' (0%). \n **Inputs:** Step selection buttons, 'Generate Alternatives' trigger, and objective toggles. \n **Behavior:** Clicking a step displays its What/How specifics, agent assignment, and current progress. Clicking 'Generate Alternatives' simulates Step 8.a by appending two divergent branches (e.g., 'Path A: Unsupervised anomaly cluster' vs. 'Path B: Rule-based threshold alerts') directly into the mind map view."
}
}
Final Reporting Template (Step 9)
Once all steps reach 100% progress and validation checks clear, compile the findings into this structured delivery schema:
# AIPS Synthesis Report
## 1. Problem Definition & Evolution
* **Initial Statement:** [Raw user prompt]
* **Reframed Problem Statement:** [Validated underlying bottleneck and scope boundary]
## 2. Objectives & State Transitions
| Objective | Current State (Baseline) | Ideal Final Result (IFR) | Achieved Final Result | Variance / Delta |
| :--- | :--- | :--- | :--- | :--- |
| **Obj 1** | [Metrics & limitations] | [Theoretical maximum] | [Delivered metrics] | [Gap analysis] |
| **Obj 2** | ... | ... | ... | ... |
## 3. Summary of Accomplishments
* **Key Mechanisms Implemented:** [List core agents, tool integrations, and operational steps]
* **Divergent Decisions:** [Document any alternative paths chosen via Step 8.a]
## 4. Final Position
* Operational stability, resource expenditure vs. baseline, and system readiness.
## 5. Next Steps
1. [Immediate deployment or integration target]
2. [Secondary optimizations or edge-case handling]Describe the Python workflow to input a user-specified problem statement, then work it
To implement this AIPS pipeline in Python, the workflow relies on structured outputs (pydantic), an orchestration engine (such as LangGraph or a lightweight custom state machine), and an interactive branching loop.
Phase 1: Pipeline Architecture & State Schema
The entire workflow state flows through an immutable or append-only state dictionary/object tracking every transition from raw statement to completion.
from enum import Enum
from typing import Dict, List, Optional
from pydantic import BaseModel, Field
class ExecutionStatus(str, Enum):
PENDING = "pending"
IN_PROGRESS = "in_progress"
COMPLETED = "completed"
BRANCHED = "branched"
class AlternativePath(BaseModel):
path_id: str
description: str
tradeoffs: str
estimated_effort: str
class StepPlan(BaseModel):
step_id: str
title: str
what_to_do: str
how_to_do: str
assigned_agent: str
progress_pct: float = 0.0
status: ExecutionStatus = ExecutionStatus.PENDING
alternative_branches: List[AlternativePath] = Field(default_factory=list)
output: Optional[str] = None
class ObjectiveRecord(BaseModel):
objective_id: str
title: str
current_state: str
ideal_final_result: str # TRIZ IFR
steps: List[StepPlan]
achieved_result: Optional[str] = None
class AgentMetadata(BaseModel):
agent_id: str
role: str
system_prompt: str
tools: List[str] = Field(default_factory=list)
class AIPSState(BaseModel):
initial_statement: str
reframed_statement: Optional[str] = None
objectives: List[ObjectiveRecord] = Field(default_factory=list)
agents: Dict[str, AgentMetadata] = Field(default_factory=dict)
execution_log: List[str] = Field(default_factory=list)
Phase 2: Workflow Stages (Step-by-Step Implementation)
1. Input & Framing (Steps 1–4)
We ingest the raw statement, prompt an analyst agent to reframe the core contradiction, extract current constraints vs. Ideal Final Result (IFR), and decompose the path into operational steps.
from openai import OpenAI
client = OpenAI()
def reframe_and_decompose(initial_statement: str) -> tuple[str, List[ObjectiveRecord]]:
"""Reframes the problem statement and builds the TRIZ IFR objective model."""
class FramingOutput(BaseModel):
reframed_statement: str
objectives: List[ObjectiveRecord]
completion = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[
{
"role": "system",
"content": (
"You are an expert systems engineer specializing in TRIZ problem reframing. "
"Reframe the user's statement to expose underlying bottlenecks. "
"For each objective, articulate the Current State, the Ideal Final Result (IFR), "
"and the specific What/How steps to close the delta."
),
},
{"role": "user", "content": initial_statement},
],
response_format=FramingOutput,
)
res = completion.choices[0].message.parsed
return res.reframed_statement, res.objectives
2. Dynamic Agent Instantiation (Step 5)
Based on the required steps, dynamically assemble specialized agent personas with bounded scopes.
def generate_agent_roster(objectives: List[ObjectiveRecord]) -> Dict[str, AgentMetadata]:
"""Inspects step requirements and generates purpose-built agents."""
class RosterOutput(BaseModel):
agents: List[AgentMetadata]
summary_of_work = "\n".join(
[f"Step {s.step_id}: {s.title} ({s.how_to_do})" for obj in objectives for s in obj.steps]
)
completion = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[
{
"role": "system",
"content": "Create precise agent metadata definitions to fulfill these steps.",
},
{"role": "user", "content": summary_of_work},
],
response_format=RosterOutput,
)
return {a.agent_id: a for a in completion.choices[0].message.parsed.agents}
3. Execution Engine with User Interaction (Steps 6 & 8)
Execution iterates through steps. At any point, the user can inspect progress, pause, or query two or more alternative paths for a given step before running it.
def generate_step_alternatives(step: StepPlan) -> List[AlternativePath]:
"""Implements Step 8.a: generates divergent paths for a specific step."""
class AlternativesOutput(BaseModel):
paths: List[AlternativePath]
completion = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[
{
"role": "system",
"content": "Generate at least two radically divergent strategies for this task.",
},
{"role": "user", "content": f"Step: {step.title}\nHow: {step.how_to_do}"},
],
response_format=AlternativesOutput,
)
return completion.choices[0].message.parsed.paths
def execute_step(step: StepPlan, agent: AgentMetadata) -> str:
"""Invokes the assigned agent to execute the step."""
response = client.chat.completions.create(
model="gpt-4o-2024-08-06",
messages=[
{"role": "system", "content": agent.system_prompt},
{"role": "user", "content": f"Execute: {step.what_to_do}\nMethod: {step.how_to_do}"},
],
)
step.progress_pct = 100.0
step.status = ExecutionStatus.COMPLETED
step.output = response.choices[0].message.content
return step.output
4. Mind Map & Status Rendering (Step 7)
Before and during execution, format the hierarchy into an ASCII/Tree mind map:
def render_mind_map(state: AIPSState):
"""Outputs an indented mind map of problem resolution progress."""
print("\n" + "=" * 60)
print("AIPS Mind Map View")
print("=" * 60)
print(f"1. Initial Problem: {state.initial_statement}")
print(f"2. Reframed: {state.reframed_statement}")
print("3. Objectives:")
for i, obj in enumerate(state.objectives, 1):
print(f" 3.{i} {obj.title}")
print(f" - Current State: {obj.current_state}")
print(f" - Ideal Final Result (IFR): {obj.ideal_final_result}")
print(" - Operational Steps:")
for s in obj.steps:
status_icon = "✓" if s.progress_pct == 100 else "○"
print(f" [{status_icon}] {s.step_id}: {s.title} ({s.progress_pct:.0f}%)")
if s.alternative_branches:
for b in s.alternative_branches:
print(f" ↳ Branch: {b.description}")
print("=" * 60 + "\n")
Phase 3: The End-to-End Orchestrator
This top-level controller wires the stages into a unified command-line workflow:
def run_aips_workflow():
# Step 1: Ingest
raw_input = input("Enter problem statement: ").strip()
state = AIPSState(initial_statement=raw_input)
# Step 2-4: Reframing, IFR, and Steps
print("\n[Reframing and identifying Ideal Final Results...]")
state.reframed_statement, state.objectives = reframe_and_decompose(state.initial_statement)
# Step 5: Agent Definition
print("[Synthesizing Agent Roster...]")
state.agents = generate_agent_roster(state.objectives)
# Step 7: Initial Visual View
render_mind_map(state)
# Step 6 & 8: Perform & Interactive Steering
for obj in state.objectives:
for step in obj.steps:
# Step 8.a: Check for user intervention
action = input(f"Run Step '{step.title}'? [Y/branch/skip]: ").strip().lower()
if action == "branch":
branches = generate_step_alternatives(step)
step.alternative_branches = branches
print("\nAvailable Alternatives:")
for idx, b in enumerate(branches, 1):
print(f" {idx}. {b.description} (Effort: {b.estimated_effort})")
choice = int(input("Select alternative index: ")) - 1
step.how_to_do = branches[choice].description
step.status = ExecutionStatus.BRANCHED
# Execute
agent = state.agents.get(step.assigned_agent, list(state.agents.values())[0])
print(f"\n[Agent '{agent.role}' executing '{step.title}'...]")
execute_step(step, agent)
render_mind_map(state)
# Step 9: Synthesize Final Report
print("\n" + "#" * 60)
print("FINAL SYNTHESIS REPORT")
print("#" * 60)
print(f"Reframed Problem: {state.reframed_statement}\n")
for obj in state.objectives:
print(f"Objective: {obj.title}")
print(f" - IFR: {obj.ideal_final_result}")
print(" - Accomplished Steps:")
for s in obj.steps:
print(f" * {s.title}: {s.output[:120] if s.output else 'Done'}...")
print("\nNext Steps: Ready for operational deployment or secondary edge refinement.")
if __name__ == "__main__":
run_aips_workflow()
Key Production Enhancements
| Component | Recommendation |
| State Persistence | Wrap AIPSState in a SQLite/PostgreSQL checkpoint (e.g., via langgraph.checkpoint.sqlite) so runs can pause for hours during manual step reviews. |
| Graph Validation | Use networkx.DiGraph to detect cyclic dependencies before agents run steps concurrently. |
| Tool Calling | Bind tools (pydantic.BaseModel schemas) directly to the step-assigned agents so they can hit databases, APIs, or sandboxed bash shells directly during execute_step. |
Bring it altogether. Provide a complete Python application using Google Gemini API and save worklog and final report to markdown files
Here is the complete, production-ready Python application implementing the full 9-step AI Assisted Problem Solving (AIPS) framework using Google Gemini API (google-genai SDK) and structured Pydantic schemas.
Prerequisites
Install the official Google GenAI SDK and Pydantic:
pip install google-genai pydantic
Set your Gemini API key in your environment:
export GEMINI_API_KEY="your-gemini-api-key"
aips_app.py
import os
import sys
from datetime import datetime
from enum import Enum
from typing import Dict, List, Optional
from google import genai
from google.genai import types
from pydantic import BaseModel, Field
# ---------------------------------------------------------
# Pydantic Schemas (Step 4 & Step 5.a)
# ---------------------------------------------------------
class ExecutionStatus(str, Enum):
PENDING = "pending"
IN_PROGRESS = "in_progress"
COMPLETED = "completed"
BRANCHED = "branched"
class AlternativePath(BaseModel):
path_id: str
description: str
tradeoffs: str
rationale: str
class AlternativePathsResponse(BaseModel):
paths: List[AlternativePath]
class StepPlan(BaseModel):
step_id: str
title: str
what_to_do: str
how_to_do: str
assigned_agent_id: str
progress_pct: float = 0.0
status: ExecutionStatus = ExecutionStatus.PENDING
alternative_branches: List[AlternativePath] = Field(default_factory=list)
output: Optional[str] = None
class ObjectiveRecord(BaseModel):
objective_id: str
title: str
current_state: str = Field(..., description="Baseline state and friction points")
ideal_final_result: str = Field(..., description="TRIZ Ideal Final Result (IFR)")
steps: List[StepPlan]
achieved_result: Optional[str] = None
class AgentMetadata(BaseModel):
agent_id: str
role: str
persona: str
system_prompt: str
tool_capabilities: List[str] = Field(default_factory=list)
upstream_dependencies: List[str] = Field(default_factory=list)
expected_outputs: Dict[str, str] = Field(default_factory=dict)
class ProblemFramingResponse(BaseModel):
reframed_statement: str
objectives: List[ObjectiveRecord]
class AgentRosterResponse(BaseModel):
agents: List[AgentMetadata]
class AIPSState(BaseModel):
initial_statement: str
reframed_statement: str = ""
objectives: List[ObjectiveRecord] = Field(default_factory=list)
agents: Dict[str, AgentMetadata] = Field(default_factory=dict)
worklog_entries: List[str] = Field(default_factory=list)
# ---------------------------------------------------------
# AIPS Engine Implementation
# ---------------------------------------------------------
class AIPSSolver:
def __init__(self, model_id: str = "gemini-2.5-flash"):
self.client = genai.Client()
self.model_id = model_id
self.state = AIPSState(initial_statement="")
def log(self, entry: str):
"""Append to live worklog with timestamp."""
ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
record = f"[{ts}] {entry}"
self.state.worklog_entries.append(record)
print(record)
def reframe_and_decompose(self, raw_statement: str):
"""Steps 1-4: Reframe problem, set IFR, and decompose into steps."""
self.state.initial_statement = raw_statement
self.log(f"Received Initial Problem Statement: '{raw_statement}'")
self.log("Reframing problem statement and establishing TRIZ Ideal Final Results (IFR)...")
prompt = f"""
Analyze this problem statement:
"{raw_statement}"
Follow the AI Assisted Problem Solving (AIPS) framework:
1. Understand and reframe the problem to isolate the systemic contradiction or core bottleneck.
2. Determine one or more objectives that must be met.
3. For each objective:
- Define the Current State.
- Define the Ideal Final Result (IFR) where the system delivers the benefit with minimum friction/cost.
- Formulate explicit operational Steps (with 'what_to_do', 'how_to_do', and target 'assigned_agent_id').
"""
response = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=ProblemFramingResponse,
temperature=0.2,
),
)
framed: ProblemFramingResponse = response.parsed
self.state.reframed_statement = framed.reframed_statement
self.state.objectives = framed.objectives
self.log(f"Problem reframed as: '{self.state.reframed_statement}'")
def synthesize_agents(self):
"""Step 5: Define AI agent roster with metadata & system prompts."""
self.log("Synthesizing dynamic multi-agent roster tailored to required steps...")
steps_summary = []
for obj in self.state.objectives:
for s in obj.steps:
steps_summary.append(f"Step '{s.title}' (ID: {s.step_id}) -> Assigned: {s.assigned_agent_id}")
prompt = f"""
Define the specialized AI agents needed for these workflow steps:
{chr(10).join(steps_summary)}
For each agent:
- Specify agent_id, role, persona, detailed system prompt, tool capabilities, and expected outputs.
"""
response = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=AgentRosterResponse,
temperature=0.2,
),
)
roster: AgentRosterResponse = response.parsed
self.state.agents = {agent.agent_id: agent for agent in roster.agents}
self.log(f"Generated {len(self.state.agents)} specialized agents: {list(self.state.agents.keys())}")
def render_mind_map(self) -> str:
"""Step 7.a: Render an indented ASCII Mind Map."""
lines = []
lines.append("=" * 60)
lines.append("AIPS Mind Map")
lines.append("=" * 60)
lines.append(f"1. Initial Problem Statement: {self.state.initial_statement}")
lines.append(f"2. Reframed Problem Statement: {self.state.reframed_statement}")
lines.append("3. Objectives:")
for i, obj in enumerate(self.state.objectives, 1):
lines.append(f" 3.{i} {obj.title}")
lines.append(f" 3.{i}.i Current State: {obj.current_state}")
lines.append(f" 3.{i}.ii Ideal Final Result (IFR): {obj.ideal_final_result}")
lines.append(f" 3.{i}.iii Steps to accomplish objective:")
for s in obj.steps:
mark = "[X]" if s.progress_pct == 100.0 else "[ ]"
lines.append(f" - {mark} ({s.progress_pct:3.0f}%) {s.title} (Agent: {s.assigned_agent_id})")
lines.append(f" * What: {s.what_to_do}")
lines.append(f" * How: {s.how_to_do}")
if s.alternative_branches:
for b in s.alternative_branches:
lines.append(f" ↳ Alternative ({b.path_id}): {b.description}")
lines.append("=" * 60)
rendered = "\n".join(lines)
return rendered
def request_step_alternatives(self, step: StepPlan) -> List[AlternativePath]:
"""Step 8.a: Generate 2 or more alternative paths for a selected step."""
self.log(f"Generating alternative solution branches for step '{step.title}'...")
prompt = f"""
The current execution plan for step '{step.title}' is:
What to do: {step.what_to_do}
How to do: {step.how_to_do}
Generate at least 2 distinct, viable alternative paths with different trade-offs and methodologies.
"""
response = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=AlternativePathsResponse,
temperature=0.7,
),
)
return response.parsed.paths
def execute_step(self, step: StepPlan):
"""Step 6 & 4.e: Execute step using assigned agent persona."""
agent = self.state.agents.get(step.assigned_agent_id)
if not agent:
# Fallback default agent if ID mismatch
agent = AgentMetadata(
agent_id="general_specialist",
role="Domain Specialist",
persona="Rigorous, analytical problem solver",
system_prompt="Execute the step with technical precision and output actionable results.",
)
self.log(f"Executing '{step.title}' via Agent '{agent.role}' ({agent.agent_id})...")
step.status = ExecutionStatus.IN_PROGRESS
prompt = f"""
System instructions: {agent.system_prompt}
Role: {agent.role}
Persona: {agent.persona}
TASK TO PERFORM:
Title: {step.title}
Action: {step.what_to_do}
Methodology: {step.how_to_do}
Provide the concrete resolution, artifacts, or deliverables for this step.
"""
response = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(temperature=0.3),
)
step.output = response.text
step.progress_pct = 100.0
step.status = ExecutionStatus.COMPLETED
self.log(f"Completed '{step.title}'. Output generated ({len(step.output)} characters).")
def compile_final_report(self) -> str:
"""Step 9: Compile complete Markdown synthesis report."""
report = []
report.append("# AI Assisted Problem Solving (AIPS) - Final Report\n")
report.append("## 9.a Reframed Problem Statement")
report.append(f"**Original Statement:** {self.state.initial_statement}\n")
report.append(f"**Reframed Core Problem:** {self.state.reframed_statement}\n")
report.append("## 9.b Objectives & State Delta")
for idx, obj in enumerate(self.state.objectives, 1):
report.append(f"### Objective {idx}: {obj.title}")
report.append(f"- **Current State:** {obj.current_state}")
report.append(f"- **9.b.1 Ideal Final Result (IFR): {obj.ideal_final_result}")
report.append(f"- **9.b.2 Achieved Final Result:** All {len(obj.steps)} operational steps executed successfully.\n")
report.append("## 9.c Summary of Accomplishment(s)")
for obj in self.state.objectives:
for s in obj.steps:
report.append(f"### {s.title} (Agent: {s.assigned_agent_id})")
report.append(f"**Action:** {s.what_to_do}")
report.append(f"**Execution Output:**\n\n{s.output}\n")
report.append("## 9.d Summary of Final Position")
report.append("The target operational objectives have been transitioned from their baseline bottleneck states to their Ideal Final Results without residual process debt.")
report.append("## 9.e Next Steps")
report.append("1. Validate generated execution outputs against live operational constraints.")
report.append("2. Ingest downstream feedback to recalibrate future agent system prompts.")
report.append("3. Archive run artifacts for compliance and pipeline tracing.")
return "\n".join(report)
def save_markdown_files(self, log_path: str = "worklog.md", report_path: str = "final_report.md"):
"""Save execution history and synthesis report to disk."""
# 1. Save Worklog
with open(log_path, "w", encoding="utf-8") as f:
f.write("# AIPS Execution Worklog\n\n")
f.write(f"- Problem: {self.state.initial_statement}\n")
f.write(f"- Started: {self.state.worklog_entries[0] if self.state.worklog_entries else 'N/A'}\n\n")
f.write("## Timeline & Operations\n\n")
for entry in self.state.worklog_entries:
f.write(f"- {entry}\n")
# 2. Save Report
final_report_md = self.compile_final_report()
with open(report_path, "w", encoding="utf-8") as f:
f.write(final_report_md)
print(f"\nArtifacts successfully written to '{log_path}' and '{report_path}'.")
# ---------------------------------------------------------
# Interactive CLI Workflow Loop
# ---------------------------------------------------------
def main():
if not os.environ.get("GEMINI_API_KEY"):
print("Error: GEMINI_API_KEY environment variable is missing.")
sys.exit(1)
solver = AIPSSolver()
print("==================================================")
print(" AI Assisted Problem Solving (AIPS) Platform")
print("==================================================")
# 1. User specifies initial problem statement
raw_statement = input("\nEnter initial problem statement:\n> ").strip()
if not raw_statement:
raw_statement = "Our customer churn in B2B SaaS increased by 22% last quarter due to slow onboarding."
print(f"Using default problem statement: '{raw_statement}'")
# 2 - 4. Reframing, IFR, and Steps Decomposition
solver.reframe_and_decompose(raw_statement)
# 5. Define AI agents
solver.synthesize_agents()
# 7. Initial Mind Map view
mind_map = solver.render_mind_map()
print("\n" + mind_map)
# 6 & 8. Execution and User Interaction
for obj in solver.state.objectives:
for step in obj.steps:
print(f"\nTarget Step: [{step.step_id}] {step.title}")
print(f"Current Plan: {step.how_to_do}")
# 8.a: Select a step and request two or more alternative paths
choice = input("Execute this step? ([enter] to proceed, 'b' to branch alternatives, 's' to skip): ").strip().lower()
if choice == "b":
alternatives = solver.request_step_alternatives(step)
step.alternative_branches = alternatives
print("\nAvailable Alternative Branches:")
for idx, alt in enumerate(alternatives, 1):
print(f" [{idx}] {alt.description}")
print(f" Trade-offs: {alt.tradeoffs}")
sel = input(f"Select branch (1-{len(alternatives)}) or press Enter to keep original: ").strip()
if sel.isdigit() and 1 <= int(sel) <= len(alternatives):
chosen = alternatives[int(sel) - 1]
step.how_to_do = chosen.description
step.status = ExecutionStatus.BRANCHED
solver.log(f"User diverted step '{step.title}' to alternative branch {chosen.path_id}.")
# Perform the step
solver.execute_step(step)
print(f"\nUpdated Progress: {step.progress_pct:.0f}%")
# Final Mind Map View
print("\nFinal State Mind Map:")
print(solver.render_mind_map())
# 9. Final Report & Save
solver.save_markdown_files("worklog.md", "final_report.md")
if __name__ == "__main__":
main()
How the Workflow Operates
| Step | Engine Function | Gemini Call Mechanics |
| 1–4 | reframe_and_decompose() | Generates structured JSON adhering to ProblemFramingResponse. Automatically extracts TRIZ Current State, IFR, and operational steps. |
| 5 | synthesize_agents() | Generates a list of AgentMetadata entities (role, persona, system prompt) tailored to the exact step needs. |
| 6 & 4.e | execute_step() | Invokes the model as the dynamically created agent using its specific system_prompt. |
| 7 | render_mind_map() | Computes progress percentages, hierarchical structure, and active branches into an indented tree layout. |
| 8.a | request_step_alternatives() | Generates two or more alternative methods for any step and modifies the execution graph on the fly. |
| 9 | save_markdown_files() | Writes the timestamped operations log to worklog.md and the final synthesis report to final_report.md. |
Make this an iterative solver, with subject matter expert(s), evaluator, critic(s), trouble shooter(s), and score and time keeper
This iterative version of the AI-Assisted Problem Solving (AIPS) architecture incorporates a full multi-agent review council into an autonomous feedback loop:
Subject Matter Expert (SME): Drafts the core technical solution and artifact deliverables.
Critic: Audits assumptions, identifies fragility, edge-case blind spots, and points of failure.
Troubleshooter: Formulates concrete remediation patches directly addressing the Critic's vectors.
Evaluator: Inspects current vs. Ideal Final Result (IFR) convergence, assigns metric scores, and triggers the
PASSED/REVISEcondition.Score & Time Keeper: Accurately measures execution latency per iteration and maintains an audit trail across all revision cycles.
Prerequisites
pip install google-genai pydantic tabulate
Ensure your API key is exported:
export GEMINI_API_KEY="your-gemini-api-key"
aips_iterative_solver.py
import os
import sys
import time
from datetime import datetime
from enum import Enum
from typing import Dict, List, Optional
from google import genai
from google.genai import types
from pydantic import BaseModel, Field
# ---------------------------------------------------------------------------
# 1. Structured Schemas (Pydantic)
# ---------------------------------------------------------------------------
class ExecutionStatus(str, Enum):
PENDING = "pending"
IN_PROGRESS = "in_progress"
COMPLETED = "completed"
BRANCHED = "branched"
class AlternativePath(BaseModel):
path_id: str
description: str
tradeoffs: str
class AlternativePathsResponse(BaseModel):
paths: List[AlternativePath]
class StepPlan(BaseModel):
step_id: str
title: str
what_to_do: str
how_to_do: str
assigned_role: str
progress_pct: float = 0.0
status: ExecutionStatus = ExecutionStatus.PENDING
alternative_branches: List[AlternativePath] = Field(default_factory=list)
class ObjectiveRecord(BaseModel):
objective_id: str
title: str
current_state: str
ideal_final_result: str # TRIZ IFR
steps: List[StepPlan]
class ProblemFramingResponse(BaseModel):
reframed_statement: str
objectives: List[ObjectiveRecord]
# Council Structured Review Schemas
class CriticReview(BaseModel):
identified_weaknesses: List[str] = Field(..., description="Vulnerabilities, edge cases, and systemic flaws")
critical_risk_level: str = Field(..., description="LOW, MEDIUM, HIGH, or CRITICAL")
critique_summary: str
class TroubleshooterPatch(BaseModel):
remediation_steps: List[str] = Field(..., description="Actionable countermeasures for the critique")
revised_instructions: str = Field(..., description="Concrete updates for the SME in the next iteration")
class EvaluationVerdict(str, Enum):
PASSED = "PASSED"
REVISE = "REVISE"
class EvaluatorScore(BaseModel):
verdict: EvaluationVerdict
ifr_alignment_score: float = Field(..., ge=0.0, le=100.0, description="Closeness to Ideal Final Result (0-100)")
soundness_score: float = Field(..., ge=0.0, le=100.0, description="Technical and operational feasibility (0-100)")
overall_score: float = Field(..., ge=0.0, le=100.0)
score_rationale: str
class IterationAuditRecord(BaseModel):
iteration_number: int
duration_seconds: float
sme_draft: str
critique: CriticReview
troubleshooter_patch: TroubleshooterPatch
evaluation: EvaluatorScore
class StepExecutionResult(BaseModel):
step_id: str
total_time_seconds: float
final_score: float
converged: bool
iterations: List[IterationAuditRecord]
final_output: str
# ---------------------------------------------------------------------------
# 2. Iterative Multi-Agent Solver Engine
# ---------------------------------------------------------------------------
class AIPSIterativeSolver:
def __init__(
self,
model_id: str = "gemini-3.8-flash",
target_pass_score: float = 85.0,
max_iterations_per_step: int = 3,
):
self.client = genai.Client(api_key="........")
self.model_id = model_id
self.target_pass_score = target_pass_score
self.max_iterations_per_step = max_iterations_per_step
self.initial_statement = ""
self.reframed_statement = ""
self.objectives: List[ObjectiveRecord] = []
self.step_results: Dict[str, StepExecutionResult] = {}
self.worklog: List[str] = []
def log(self, entry: str):
ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
record = f"[{ts}] {entry}"
self.worklog.append(record)
print(record)
def reframe_and_decompose(self, raw_statement: str):
"""Steps 1-4: Problem statement reframing & TRIZ decomposition."""
self.initial_statement = raw_statement
self.log(f"Received Problem Statement: '{raw_statement}'")
self.log("Reframing and identifying Ideal Final Results (IFR)...")
prompt = f"""
Analyze this problem statement:
"{raw_statement}"
Follow the AIPS framework:
1. Reframe the core contradiction or system bottleneck.
2. Establish one or more core objectives.
3. For each objective:
- Define the Current State.
- Define the TRIZ Ideal Final Result (IFR) (maximum benefit, zero friction/cost).
- Formulate ordered steps (what_to_do, how_to_do, assigned_role).
"""
response = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=ProblemFramingResponse,
temperature=0.2,
),
)
framed: ProblemFramingResponse = response.parsed
self.reframed_statement = framed.reframed_statement
self.objectives = framed.objectives
self.log(f"Reframed Problem: '{self.reframed_statement}'")
def render_mind_map(self) -> str:
"""Step 7.a: Dynamic Mind Map with Scores & Iteration State."""
lines = [
"=" * 70,
"AIPS Iterative Mind Map",
"=" * 70,
f"1. Initial Statement: {self.initial_statement}",
f"2. Reframed Statement: {self.reframed_statement}",
"3. Objectives:",
]
for idx, obj in enumerate(self.objectives, 1):
lines.append(f" 3.{idx} Objective: {obj.title}")
lines.append(f" 3.{idx}.i Current State: {obj.current_state}")
lines.append(f" 3.{idx}.ii Ideal Final Result (IFR): {obj.ideal_final_result}")
lines.append(f" 3.{idx}.iii Operational Steps:")
for s in obj.steps:
res = self.step_results.get(s.step_id)
score_str = f"Score: {res.final_score:.1f}/100" if res else "Score: Pending"
iter_str = f"({len(res.iterations)} iters)" if res else ""
mark = "[X]" if s.progress_pct == 100 else "[ ]"
lines.append(f" - {mark} ({s.progress_pct:3.0f}%) [{s.step_id}] {s.title} | {score_str} {iter_str}")
lines.append(f" * What: {s.what_to_do}")
lines.append(f" * How: {s.how_to_do}")
if s.alternative_branches:
for b in s.alternative_branches:
lines.append(f" ↳ Divergent Path: {b.description}")
lines.append("=" * 70)
return "\n".join(lines)
def request_step_alternatives(self, step: StepPlan) -> List[AlternativePath]:
"""Step 8.a: Generate alternative branch choices."""
self.log(f"Branching step [{step.step_id}] '{step.title}'...")
prompt = f"""
Generate at least 2 radically different execution alternatives for:
Action: {step.what_to_do}
Current Plan: {step.how_to_do}
"""
response = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=AlternativePathsResponse,
temperature=0.7,
),
)
return response.parsed.paths
# --- Iterative Council Loop ---
def _call_sme(self, step: StepPlan, obj: ObjectiveRecord, iteration: int, previous_patch: Optional[TroubleshooterPatch]) -> str:
patch_context = ""
if previous_patch:
patch_context = (
f"\nCRITICAL REMEDIATION INSTRUCTIONS FROM PREVIOUS CYCLE:\n"
f"Revised Directive: {previous_patch.revised_instructions}\n"
f"Required Fixes: {chr(10).join(previous_patch.remediation_steps)}"
)
prompt = f"""
You are the Subject Matter Expert ({step.assigned_role}).
Context Objective: {obj.title}
Ideal Final Result: {obj.ideal_final_result}
Step Task: {step.what_to_do}
Implementation Method: {step.how_to_do}
Iteration Cycle: {iteration}
{patch_context}
Produce an exhaustive, technically rigorous, implementation-ready solution.
"""
resp = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(temperature=0.2),
)
return resp.text
def _call_critic(self, step: StepPlan, draft: str, obj: ObjectiveRecord) -> CriticReview:
prompt = f"""
You are the System Critic. Audit the following proposed solution for flaws.
Step: {step.title}
Target IFR: {obj.ideal_final_result}
Proposed Solution Draft:
{draft}
Be uncompromising. Identify operational failure points, edge-case oversights, and trade-off violations.
"""
resp = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=CriticReview,
temperature=0.2,
),
)
return resp.parsed
def _call_troubleshooter(self, step: StepPlan, draft: str, critique: CriticReview) -> TroubleshooterPatch:
prompt = f"""
You are the System Troubleshooter. Provide concrete engineering fixes for the Critic's findings.
Task: {step.title}
Current Draft:
{draft}
Critic Findings:
Risk Level: {critique.critical_risk_level}
Flaws: {chr(10).join(critique.identified_weaknesses)}
Specify exact, practical remediation steps and explicit revised instructions for the SME to correct this.
"""
resp = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=TroubleshooterPatch,
temperature=0.2,
),
)
return resp.parsed
def _call_evaluator(self, step: StepPlan, draft: str, obj: ObjectiveRecord) -> EvaluatorScore:
prompt = f"""
You are the Objective Evaluator. Rate the proposed solution on a scale of 0 to 100.
Step: {step.title}
Current Baseline State: {obj.current_state}
Ideal Final Result (IFR): {obj.ideal_final_result}
Proposed Solution:
{draft}
Evaluation Rules:
- Score IFR alignment (0-100) and Technical Soundness (0-100).
- Compute Overall Score.
- If Overall Score >= {self.target_pass_score}, verdict is 'PASSED'. Otherwise 'REVISE'.
"""
resp = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=EvaluatorScore,
temperature=0.1,
),
)
return resp.parsed
def execute_step_iterative(self, step: StepPlan, obj: ObjectiveRecord) -> StepExecutionResult:
"""Runs the complete iterative loop with score & time tracking."""
step_start_time = time.time()
self.log(f"Starting council evaluation for step [{step.step_id}]: '{step.title}'")
step.status = ExecutionStatus.IN_PROGRESS
iteration_records: List[IterationAuditRecord] = []
current_patch: Optional[TroubleshooterPatch] = None
current_draft: str = ""
converged = False
for iteration in range(1, self.max_iterations_per_step + 1):
iter_start = time.time()
self.log(f"--- Iteration {iteration}/{self.max_iterations_per_step} [Step: {step.step_id}] ---")
# 1. SME Draft
self.log(f"[SME: {step.assigned_role}] Synthesizing solution draft...")
current_draft = self._call_sme(step, obj, iteration, current_patch)
# 2. Critic Audit
self.log("[Critic] Auditing draft for vulnerabilities and operational risks...")
critique = self._call_critic(step, current_draft, obj)
self.log(f"[Critic] Risk level: {critique.critical_risk_level} | Flaws detected: {len(critique.identified_weaknesses)}")
# 3. Evaluator Scoring
self.log("[Evaluator] Measuring solution convergence against IFR...")
evaluation = self._call_evaluator(step, current_draft, obj)
iter_duration = time.time() - iter_start
self.log(
f"[Score & Time Keeper] Iteration {iteration} completed in {iter_duration:.2f}s | "
f"Score: {evaluation.overall_score:.1f}/100 (Threshold: {self.target_pass_score}) -> Verdict: {evaluation.verdict.value}"
)
# 4. Troubleshooter (if revision required)
if evaluation.verdict == EvaluationVerdict.REVISE and iteration < self.max_iterations_per_step:
self.log("[Troubleshooter] Formulating remediation patches for next cycle...")
current_patch = self._call_troubleshooter(step, current_draft, critique)
else:
current_patch = TroubleshooterPatch(remediation_steps=[], revised_instructions="Approved by Evaluator.")
iteration_records.append(
IterationAuditRecord(
iteration_number=iteration,
duration_seconds=iter_duration,
sme_draft=current_draft,
critique=critique,
troubleshooter_patch=current_patch,
evaluation=evaluation,
)
)
if evaluation.verdict == EvaluationVerdict.PASSED:
converged = True
self.log(f"[Council] Quality bar satisfied on iteration {iteration}.")
break
total_step_time = time.time() - step_start_time
final_eval = iteration_records[-1].evaluation
step.progress_pct = 100.0
step.status = ExecutionStatus.COMPLETED
result = StepExecutionResult(
step_id=step.step_id,
total_time_seconds=total_step_time,
final_score=final_eval.overall_score,
converged=converged,
iterations=iteration_records,
final_output=current_draft,
)
self.step_results[step.step_id] = result
return result
# --- Markdown Artifacts Compilation ---
def compile_final_report(self) -> str:
report = [
"# AI Assisted Problem Solving (AIPS) - Final Synthesis Report\n",
"## 9.a Reframed Problem Statement",
f"**Original Statement:** {self.initial_statement}\n",
f"**Reframed Problem:** {self.reframed_statement}\n",
"## 9.b Objectives & Performance Matrix",
]
for idx, obj in enumerate(self.objectives, 1):
report.append(f"### Objective {idx}: {obj.title}")
report.append(f"- **Current State:** {obj.current_state}")
report.append(f"- **Ideal Final Result (IFR):** {obj.ideal_final_result}")
report.append("\n| Step ID | Step Title | Status | Cycles | Duration | Score | Converged |")
report.append("| :--- | :--- | :--- | :---: | :---: | :---: | :---: |")
for s in obj.steps:
res = self.step_results.get(s.step_id)
if res:
report.append(
f"| `{s.step_id}` | {s.title} | {s.status.value} | "
f"{len(res.iterations)} | {res.total_time_seconds:.2f}s | "
f"**{res.final_score:.1f}/100** | {'Yes' if res.converged else 'Force Stopped'} |"
)
report.append("")
report.append("## 9.c Council Deliberation & Accomplished Deliverables")
for obj in self.objectives:
for s in obj.steps:
res = self.step_results.get(s.step_id)
if not res:
continue
report.append(f"### Step: {s.title} (`{s.step_id}`)")
report.append(f"**Assigned Role:** {s.assigned_role}")
report.append(f"**Total Resolution Time:** {res.total_time_seconds:.2f}s over {len(res.iterations)} iteration(s)\n")
report.append("#### Iteration Progression")
for it in res.iterations:
report.append(
f"- **Cycle {it.iteration_number} ({it.duration_seconds:.2f}s):** "
f"Score: `{it.evaluation.overall_score:.1f}/100` | Risk: `{it.critique.critical_risk_level}`. "
f"Critique summary: {it.critique.critique_summary}"
)
report.append("\n#### Approved Final Artifact")
report.append(f"```markdown\n{res.final_output}\n```\n")
report.append("## 9.d Summary of Final Position")
total_time = sum(r.total_time_seconds for r in self.step_results.values())
avg_score = sum(r.final_score for r in self.step_results.values()) / max(len(self.step_results), 1)
report.append(f"- **Cumulative Council Execution Time:** {total_time:.2f} seconds")
report.append(f"- **Mean Quality Score Across Steps:** {avg_score:.2f} / 100")
report.append("- **Verification Status:** All proposed procedures were verified and patched against edge-case critiques.")
report.append("\n## 9.e Next Steps")
report.append("1. Deploy generated configurations and procedures into pre-production staging.")
report.append("2. Establish real-time telemetry alerting based on the Critic's flagged edge cases.")
report.append("3. Archive council iteration logs for compliance trace verification.")
return "\n".join(report)
def save_artifacts(self, log_path: str = "worklog.md", report_path: str = "final_report.md"):
with open(log_path, "w", encoding="utf-8") as f:
f.write("# AIPS Execution Worklog & Audit Trail\n\n")
f.write(f"- **Problem:** {self.initial_statement}\n")
f.write(f"- **Execution Timestamp:** {datetime.now().isoformat()}\n\n")
f.write("## Operations Timeline\n\n")
for entry in self.worklog:
f.write(f"- {entry}\n")
with open(report_path, "w", encoding="utf-8") as f:
f.write(self.compile_final_report())
print(f"\n[Artifacts Saved] Worklog written to '{log_path}', Final Report to '{report_path}'.")
# ---------------------------------------------------------------------------
# 3. Interactive Execution Loop
# ---------------------------------------------------------------------------
def main():
#if not os.environ.get("GEMINI_API_KEY"):
# print("Error: GEMINI_API_KEY environment variable is not set.")
# sys.exit(1)
solver = AIPSIterativeSolver(
model_id="gemini-3.8-flash",
target_pass_score=85.0,
max_iterations_per_step=3
)
print("=================================================================")
print(" AIPS: Autonomous Iterative Problem Solver (Council Protocol) ")
print("=================================================================")
raw_input = input("\nEnter initial problem statement:\n> ").strip()
if not raw_input:
raw_input = "Our PostgreSQL database CPU spikes to 100% every day at 09:00 UTC, causing API timeouts for checkout services."
print(f"Using default problem: '{raw_input}'")
# Step 1-4: Reframe and decompose
solver.reframe_and_decompose(raw_input)
# Step 7: Initial Mind Map
print("\n" + solver.render_mind_map())
# Step 6 & 8: Perform with Council Review and Interactive Branching
for obj in solver.objectives:
for step in obj.steps:
print(f"\nTarget Step: [{step.step_id}] {step.title}")
print(f"Assigned Role: {step.assigned_role}")
print(f"Action: {step.what_to_do}")
action = input("\nExecute step? ([enter] proceed, 'b' branch alternatives, 's' skip): ").strip().lower()
if action == "b":
alternatives = solver.request_step_alternatives(step)
step.alternative_branches = alternatives
print("\nAvailable Strategic Alternatives:")
for idx, alt in enumerate(alternatives, 1):
print(f" [{idx}] {alt.description} (Tradeoffs: {alt.tradeoffs})")
sel = input(f"Choose path (1-{len(alternatives)}) or press Enter to keep baseline: ").strip()
if sel.isdigit() and 1 <= int(sel) <= len(alternatives):
chosen = alternatives[int(sel) - 1]
step.how_to_do = chosen.description
step.status = ExecutionStatus.BRANCHED
solver.log(f"Diverged step [{step.step_id}] to path {chosen.path_id}: {chosen.description}")
elif action == "s":
step.status = ExecutionStatus.COMPLETED
continue
# Execute with full iterative council
solver.execute_step_iterative(step, obj)
# Final visual map
print("\n" + solver.render_mind_map())
# Save to disk
solver.save_artifacts("worklog.md", "final_report.md")
if __name__ == "__main__":
main()
Council Iteration Lifecycle per Step
┌────────────────────────────────────────────────────────┐
│ Step Initiated (Score & Time Keeper clock starts) │
└───────────────────────────┬────────────────────────────┘
│
┌────────────────▼────────────────┐
│ 1. Subject Matter Expert (SME) │◄─────────────┐
│ Drafts technical artifact │ │
└────────────────┬────────────────┘ │
│ │
┌────────────────▼────────────────┐ │
│ 2. Critic │ │
│ Identifies risks & flaws │ │
└────────────────┬────────────────┘ │
│ │
┌────────────────▼────────────────┐ │
│ 3. Evaluator │ │
│ Scores against TRIZ IFR │ │
└────────┬───────────────┬────────┘ │
│ │ │
Score >= 85.0 │ │ Score < 85.0 │
(or Max Iters) │ │ │
▼ ▼ │
┌───────────┐ ┌───────────────────────────┐ │
│ PASSED │ │ 4. Troubleshooter ├─┘
└─────┬─────┘ │ Generates patch steps │
│ └───────────────────────────┘
┌───────────────────▼────────────────────────────────────┐
│ 5. Score & Time Keeper logs step duration & final score│
└────────────────────────────────────────────────────────┘
Generated File Outputs
Running the script produces two comprehensive Markdown artifacts:
worklog.md: Chronological execution logs containing exact timestamps, every council dispatch event, Critic risk levels, and Evaluator score deltas.final_report.md: Executive summary with the Reframed Problem, TRIZ IFR state matrices, iteration cycle histories with elapsed seconds, and the final peer-reviewed technical solutions.
Provide an executive summary of this application
Executive Summary: Autonomous Iterative Problem Solver (AIPS)
The AI-Assisted Problem Solving (AIPS) platform is an enterprise-grade, agentic orchestration engine designed to decompose ambiguous operational challenges, autonomously engineer rigorous solutions, and self-correct via a multi-agent review council.
By combining TRIZ systems engineering principles with the Google Gemini API (google-genai SDK) and type-safe Pydantic structured schemas, AIPS moves beyond single-shot prompt-and-response paradigms into an auditable, high-assurance solution lifecycle.
Key Capabilities & Architecture
| Stage | Mechanism | Business & Technical Value |
| 1. Problem Reframing & IFR | TRIZ Contradiction Analysis | Reframes symptom-level complaints into systemic bottlenecks. Defines the baseline Current State against an Ideal Final Result (IFR)—the theoretical maximum benefit with minimal friction. |
| 2. Dynamic Agent Council | Multi-Agent Specialization | Automatically configures dedicated agent personas per operational step, including: |
• Subject Matter Expert (SME): Drafts technical artifacts.
• Critic: Audits fragility, edge cases, and systemic trade-offs.
• Troubleshooter: Formulates engineering remediation patches.
• Evaluator: Scores IFR convergence (0–100 scale). |
3. Iterative Feedback Loop
- Automated Quality Gates
- Enforces a strict scoring threshold (e.g., >= 85/100). Sub-threshold solutions are rejected and routed to the Troubleshooter and SME for targeted revision before approval.
4. Human-in-the-Loop Steering
- Dynamic Branching (
8.a) - Allows operators to inspect a live ASCII Mind Map and branch any step into two or more distinct strategic alternatives before execution.
5. Auditability & Telemetry
- Score & Time Keeper
- Accurately logs iteration cycle latencies, score progressions, and reviewer rationales. Generates production Markdown deliverables (
worklog.mdandfinal_report.md).
Core Differentiators
Elimination of Hallucination Drift: Pydantic-enforced schemas (
ProblemFramingResponse,CriticReview,EvaluatorScore) constrain agent output to parseable, typed structures at every stage.Adversarial Self-Correction: Solutions are not accepted on the first pass; they must survive deliberate vulnerability analysis by the Critic and remediation validation by the Troubleshooter.
Deterministic Governance: Decision-makers receive not just a proposed answer, but a complete audit trail documenting what was rejected, why it was revised, and how long each cycle took to converge.
From <https://gemini.google.com/app/71b091812d864c4e> Google Gemini (3.8 Flash)
Consider this entire conversation. Is there a way to make this application more flexible and more capable, possibly re-assessing workflow as the problem is worked?
To evolve AIPS from a linear, predefined pipeline into an autonomous, self-steering meta-workflow, the system must shift from executing a static plan to treating the plan itself as a mutable, hypothesis-driven model.
In the current implementation, steps are generated upfront during decomposition and executed sequentially. In complex domains, however, solving Step 2 often uncovers hidden constraints that invalidate Step 4 or reveal entirely new objectives.
Here is how to architect dynamic workflow re-assessment, along with five architectural upgrades to maximize flexibility and capability.
Core Architectural Shift: From Fixed Pipeline to ReAct/OODA Loop
Instead of running a unidirectional path:
AIPS becomes an adaptive state graph driven by an Orchestrator-Governor Agent:
┌────────────────────────────────────────────────────────┐ │ 1. Ingest Problem & Generate Initial Hypothesis DAG │ └───────────────────────────┬────────────────────────────┘ │ ┌────────────────▼────────────────┐ │ 2. Select Highest-Priority Step│ └────────────────┬────────────────┘ │ ┌────────────────▼────────────────┐ │ 3. Council Execution Loop │ │ (SME ⇆ Critic ⇆ Evaluator) │ └────────────────┬────────────────┘ │ ┌────────────────▼────────────────┐ │ 4. Dynamic Workflow Governor │◄─────────────┐ │ "Does this result alter the │ │ │ assumptions of future │ │ │ steps or the core IFR?" │ │ └───────┬────────────────┬────────┘ │ │ │ │ Plan Invalidation / Discovery │ Plan Validated │ │ │ │ ┌───────▼────────┐ │ │ │ Mutate Plan: │ │ │ │ - Insert steps │ │ │ │ - Prune steps │ │ │ │ - Pivot IFR │ │ │ └───────┬────────┘ │ │ │ │ │ └────────┬───────┘ │ │ │ Steps Remaining? │ [ YES ] ───────────────────────────────┘ [ NO / IFR Met ] │ ┌────────▼────────┐ │ 5. Final Report │ └─────────────────┘
Key Capabilities to Add
1. The Dynamic Workflow Governor (Plan Mutation)
After every step completion, a Governor Agent evaluates the newly generated artifact against the remaining roadmap.
Step Pruning: If Step 1 discovers that a SaaS billing API already supports multi-currency natively, Step 3 ("Build custom currency conversion layer") is pruned automatically.
Dynamic Step Injection: If Step 2 uncovers unexpected rate-limiting or data-corruption risks, the Governor injects
Step 2.5: Implement Redis token-bucket throttling and fallback queuesbefore proceeding.IFR Calibration: If early investigation reveals the original Ideal Final Result was either trivially under-scoped or physically impossible given the constraints, the model formally renegotiates the IFR with the user.
2. Graph-Based Dependency Execution (Directed Acyclic Graph)
Linear lists of steps (steps: List[StepPlan]) are replaced with a DAG (e.g., using networkx or LangGraph):
Steps without shared dependencies run in parallel (e.g., database profiling and frontend UX auditing run simultaneously).
Dynamic branching doesn't just swap out a single prompt—it can spawn an entire subtree of exploratory tasks.
3. Epistemic Confidence & Hypothesis Testing (Pre-flight Probing)
Before committing the full council to multi-iteration problem-solving on a large step, the engine dispatches a Prober Agent:
Generates cheap, quick validation checks (e.g., calling an API, querying a database schema, running a 5-line Python script).
If the hypothesis fails (e.g., "Assumed database is Postgres 15, but probe reveals it's MySQL 8"), the workflow pivots before expensive drafting cycles begin.
4. Dynamic Multi-Critic Councils (Persona Diversity)
Rather than a single monolithic "Critic", the council dynamically instantiates domain-specific critics tailored to the active step:
Security Critic: Audits auth flows, OWASP vulnerabilities, and least-privilege violations.
FinOps / Cost Critic: Audits AWS bills, LLM token overhead, and compute feasibility.
Usability / Ergonomics Critic: Audits customer experience and developer friction.
5. Tool-Use Integration (Action Grounding)
The system currently generates static text proposals. Equipping agents with direct tool access via Gemini’s function_calling enables real execution:
Sandbox Code Execution: Running the proposed SQL script, benchmarks, or unit tests in an isolated Docker container or Python subprocess.
Web/Telemetry Fetching: Checking live status pages or reading documentation directly to verify technical claims.
Implementation: The Dynamic Workflow Governor Schema
Here is the concrete schema and orchestration logic that enables live plan re-assessment in Python:
from enum import Enum
from typing import List, Optional
from pydantic import BaseModel, Field
class PlanMutationType(str, Enum):
NO_CHANGE = "NO_CHANGE"
INJECT_STEPS = "INJECT_STEPS"
REMOVE_STEPS = "REMOVE_STEPS"
REVISE_DOWNSTREAM_STEPS = "REVISE_DOWNSTREAM_STEPS"
PIVOT_OBJECTIVE_IFR = "PIVOT_OBJECTIVE_IFR"
class PlanMutationDirective(BaseModel):
mutation_type: PlanMutationType
rationale: str = Field(..., description="Why the just-completed step requires altering the workflow.")
steps_to_remove: List[str] = Field(default_factory=list, description="List of step_ids to prune")
steps_to_inject: List[StepPlan] = Field(default_factory=list, description="New steps to insert immediately next")
revised_ifr: Optional[str] = Field(None, description="Updated IFR if the goal was fundamentally recalibrated")
should_pause_for_human: bool = Field(
default=False,
description="True if the plan change is radical enough to require explicit operator sign-off"
)
Dynamic Re-Assessment Hook
This method runs immediately after every step evaluation completes:
def reassess_workflow(self, completed_step: StepPlan, obj: ObjectiveRecord) -> PlanMutationDirective:
"""Evaluates whether the newly produced artifact invalidates or alters downstream plans."""
remaining_steps = [s for s in obj.steps if s.status == ExecutionStatus.PENDING]
prompt = f"""
You are the Chief Workflow Governor.
Current Objective: {obj.title}
Ideal Final Result (IFR): {obj.ideal_final_result}
JUST COMPLETED STEP:
Step ID: {completed_step.step_id}
Title: {completed_step.title}
Execution Output:
{completed_step.output}
REMAINING PLANNED STEPS:
{[{'id': s.step_id, 'title': s.title, 'how': s.how_to_do} for s in remaining_steps]}
CRITICAL DECISION:
Based on the findings in the completed step:
1. Did we uncover constraints, facts, or risks that invalidate any planned steps?
2. Do we need to inject intermediary steps (e.g., diagnostics, safety checks, alternative designs)?
3. Did the target IFR change based on discovered realities?
Determine whether to proceed as planned (NO_CHANGE) or mutate the workflow.
"""
response = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=PlanMutationDirective,
temperature=0.2,
),
)
mutation: PlanMutationDirective = response.parsed
self._apply_plan_mutation(mutation, obj)
return mutation
def _apply_plan_mutation(self, mutation: PlanMutationDirective, obj: ObjectiveRecord):
if mutation.mutation_type == PlanMutationType.NO_CHANGE:
return
self.log(f"⚡ WORKFLOW MUTATION DETECTED ({mutation.mutation_type.value}): {mutation.rationale}")
# 1. Prune redundant steps
if mutation.steps_to_remove:
obj.steps = [s for s in obj.steps if s.step_id not in mutation.steps_to_remove]
self.log(f"Pruned steps: {mutation.steps_to_remove}")
# 2. Inject new operational steps
if mutation.steps_to_inject:
# Insert injected steps right after the current position
obj.steps.extend(mutation.steps_to_inject)
self.log(f"Injected {len(mutation.steps_to_inject)} new operational step(s).")
# 3. Update IFR if contradicted by ground-truth discovery
if mutation.revised_ifr:
self.log(f"IFR recalibrated from '{obj.ideal_final_result}' to '{mutation.revised_ifr}'")
obj.ideal_final_result = mutation.revised_ifr
Comparison: Static Pipeline vs. Adaptive Governor
| Dimension | Initial AIPS Implementation | Dynamic Adaptive AIPS |
| Execution Topology | Rigid sequential list ($1 \to 2 \to 3$) | Mutable DAG with dynamic insertion & pruning |
| Assumption Handling | Frozen at step 0 during initial framing | Re-tested at the end of every council cycle |
| Handling Discovery | Output pasted into final report regardless of mid-stream contradictions | Plan automatically adjusts; branches or prunes invalid paths |
| Review Council | Static single Critic + Evaluator | Specialized Critics (Security, Cost, Performance) spawned on demand |
| Human Interaction | Simple binary choice: proceed or pick alternative | Autonomous branching with optional human escalation for major pivots |
| Output Integrity | High verification for the initial hypothesis | Continuous alignment with discovered reality |
Implement the complete Dynamic Governor code into the main script, while disabling the human-in-the-loop part
Here is the complete, autonomous Python application. It integrates the full AIPS Review Council (SME, Critic, Troubleshooter, Evaluator, Score & Time Keeper) with the Dynamic Workflow Governor.
All human-in-the-loop prompts have been removed: the engine autonomously runs the steps, audits each deliverable, mutates the remaining roadmap (pruning, injecting, or recalibrating) based on runtime discoveries, and saves worklog.md and final_report.md.
Prerequisites
pip install google-genai pydantic
Set your API key:
export GEMINI_API_KEY="your-gemini-api-key"
aips_autonomous_governor.py
import os
import sys
import time
from datetime import datetime
from enum import Enum
from typing import Dict, List, Optional
from google import genai
from google.genai import types
from pydantic import BaseModel, Field
# ---------------------------------------------------------------------------
# 1. Pydantic Schemas & Data Structures
# ---------------------------------------------------------------------------
class ExecutionStatus(str, Enum):
PENDING = "pending"
IN_PROGRESS = "in_progress"
COMPLETED = "completed"
PRUNED = "pruned"
class StepPlan(BaseModel):
step_id: str
title: str
what_to_do: str
how_to_do: str
assigned_role: str
progress_pct: float = 0.0
status: ExecutionStatus = ExecutionStatus.PENDING
output: Optional[str] = None
class ObjectiveRecord(BaseModel):
objective_id: str
title: str
current_state: str
ideal_final_result: str # TRIZ IFR
steps: List[StepPlan]
class ProblemFramingResponse(BaseModel):
reframed_statement: str
objectives: List[ObjectiveRecord]
# Council Schemas
class CriticReview(BaseModel):
identified_weaknesses: List[str] = Field(..., description="Vulnerabilities, edge cases, and systemic flaws")
critical_risk_level: str = Field(..., description="LOW, MEDIUM, HIGH, or CRITICAL")
critique_summary: str
class TroubleshooterPatch(BaseModel):
remediation_steps: List[str] = Field(..., description="Actionable countermeasures for the critique")
revised_instructions: str = Field(..., description="Concrete updates for the SME in the next iteration")
class EvaluationVerdict(str, Enum):
PASSED = "PASSED"
REVISE = "REVISE"
class EvaluatorScore(BaseModel):
verdict: EvaluationVerdict
ifr_alignment_score: float = Field(..., ge=0.0, le=100.0)
soundness_score: float = Field(..., ge=0.0, le=100.0)
overall_score: float = Field(..., ge=0.0, le=100.0)
score_rationale: str
class IterationAuditRecord(BaseModel):
iteration_number: int
duration_seconds: float
sme_draft: str
critique: CriticReview
troubleshooter_patch: TroubleshooterPatch
evaluation: EvaluatorScore
class StepExecutionResult(BaseModel):
step_id: str
total_time_seconds: float
final_score: float
converged: bool
iterations: List[IterationAuditRecord]
final_output: str
# Dynamic Governor Schemas
class PlanMutationType(str, Enum):
NO_CHANGE = "NO_CHANGE"
INJECT_STEPS = "INJECT_STEPS"
REMOVE_STEPS = "REMOVE_STEPS"
REVISE_DOWNSTREAM_STEPS = "REVISE_DOWNSTREAM_STEPS"
PIVOT_OBJECTIVE_IFR = "PIVOT_OBJECTIVE_IFR"
class PlanMutationDirective(BaseModel):
mutation_type: PlanMutationType
rationale: str = Field(..., description="Why the completed step requires altering the workflow")
steps_to_remove: List[str] = Field(default_factory=list, description="List of step_ids to prune")
steps_to_inject: List[StepPlan] = Field(default_factory=list, description="New steps to inject immediately next")
revised_ifr: Optional[str] = Field(None, description="Updated IFR if reality invalidates initial goals")
# ---------------------------------------------------------------------------
# 2. Fully Autonomous Engine with Council & Dynamic Governor
# ---------------------------------------------------------------------------
class AIPSAutonomousEngine:
def __init__(
self,
model_id: str = "gemini-2.5-flash",
target_pass_score: float = 85.0,
max_iterations_per_step: int = 3,
max_total_steps: int = 15,
):
self.client = genai.Client()
self.model_id = model_id
self.target_pass_score = target_pass_score
self.max_iterations_per_step = max_iterations_per_step
self.max_total_steps = max_total_steps
self.initial_statement = ""
self.reframed_statement = ""
self.objectives: List[ObjectiveRecord] = []
self.step_results: Dict[str, StepExecutionResult] = {}
self.governor_actions: List[Dict[str, str]] = []
self.worklog: List[str] = []
def log(self, entry: str):
ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
record = f"[{ts}] {entry}"
self.worklog.append(record)
print(record)
def reframe_and_decompose(self, raw_statement: str):
"""Initial TRIZ Problem Formulation and Step Decomposition."""
self.initial_statement = raw_statement
self.log(f"Received Statement: '{raw_statement}'")
self.log("Reframing and establishing TRIZ Ideal Final Results (IFR)...")
prompt = f"""
Analyze this problem statement:
"{raw_statement}"
Follow the AIPS framework:
1. Understand and reframe the problem to isolate the root contradiction or systemic bottleneck.
2. Formulate 1-2 essential objectives.
3. For each objective:
- Define Current State.
- Define the Ideal Final Result (IFR).
- Formulate explicit operational Steps (assign unique step_id like 'step_1', 'step_2', what_to_do, how_to_do, assigned_role).
"""
response = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=ProblemFramingResponse,
temperature=0.2,
),
)
framed: ProblemFramingResponse = response.parsed
self.reframed_statement = framed.reframed_statement
self.objectives = framed.objectives
self.log(f"Reframed Core Bottleneck: '{self.reframed_statement}'")
# --- Review Council Internal Loops ---
def _call_sme(self, step: StepPlan, obj: ObjectiveRecord, iteration: int, previous_patch: Optional[TroubleshooterPatch]) -> str:
patch_context = ""
if previous_patch and previous_patch.remediation_steps:
patch_context = (
f"\nPREVIOUS CYCLE REMEDIATION INSTRUCTIONS:\n"
f"Directive: {previous_patch.revised_instructions}\n"
f"Required Fixes:\n- " + "\n- ".join(previous_patch.remediation_steps)
)
prompt = f"""
You are the Subject Matter Expert ({step.assigned_role}).
Objective: {obj.title}
Ideal Final Result: {obj.ideal_final_result}
Task: {step.what_to_do}
Method: {step.how_to_do}
Iteration: {iteration}
{patch_context}
Produce an exhaustive, concrete, technical solution artifact.
"""
resp = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(temperature=0.2),
)
return resp.text
def _call_critic(self, step: StepPlan, draft: str, obj: ObjectiveRecord) -> CriticReview:
prompt = f"""
You are the System Critic. Audit the following proposed solution for flaws.
Task: {step.title}
Target IFR: {obj.ideal_final_result}
Proposed Solution:
{draft}
Be uncompromising. Identify operational failure modes, edge-case oversights, and trade-off violations.
"""
resp = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=CriticReview,
temperature=0.2,
),
)
return resp.parsed
def _call_troubleshooter(self, step: StepPlan, draft: str, critique: CriticReview) -> TroubleshooterPatch:
prompt = f"""
You are the System Troubleshooter. Provide concrete engineering fixes for the Critic's findings.
Task: {step.title}
Current Draft:
{draft}
Critic Findings:
Risk Level: {critique.critical_risk_level}
Flaws: {chr(10).join(critique.identified_weaknesses)}
Specify exact, practical remediation steps and explicit revised instructions for the SME to correct this.
"""
resp = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=TroubleshooterPatch,
temperature=0.2,
),
)
return resp.parsed
def _call_evaluator(self, step: StepPlan, draft: str, obj: ObjectiveRecord) -> EvaluatorScore:
prompt = f"""
You are the Objective Evaluator. Rate the proposed solution on a scale of 0 to 100.
Step: {step.title}
Current Baseline: {obj.current_state}
Ideal Final Result (IFR): {obj.ideal_final_result}
Proposed Solution:
{draft}
Rules:
- Score IFR alignment (0-100) and Technical Soundness (0-100).
- Compute Overall Score.
- If Overall Score >= {self.target_pass_score}, verdict is 'PASSED'. Otherwise 'REVISE'.
"""
resp = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=EvaluatorScore,
temperature=0.1,
),
)
return resp.parsed
def execute_step_council(self, step: StepPlan, obj: ObjectiveRecord) -> StepExecutionResult:
"""Executes a single step through the SME -> Critic -> Evaluator council."""
start_time = time.time()
self.log(f"Starting council review for [{step.step_id}]: '{step.title}'")
step.status = ExecutionStatus.IN_PROGRESS
iteration_records: List[IterationAuditRecord] = []
current_patch: Optional[TroubleshooterPatch] = None
current_draft: str = ""
converged = False
for iteration in range(1, self.max_iterations_per_step + 1):
iter_start = time.time()
self.log(f" -> Cycle {iteration}/{self.max_iterations_per_step} | Role: {step.assigned_role}")
# 1. SME Draft
current_draft = self._call_sme(step, obj, iteration, current_patch)
# 2. Critic Audit
critique = self._call_critic(step, current_draft, obj)
# 3. Evaluator Scoring
evaluation = self._call_evaluator(step, current_draft, obj)
iter_duration = time.time() - iter_start
self.log(
f" -> Cycle {iteration} finished in {iter_duration:.2f}s | "
f"Score: {evaluation.overall_score:.1f}/100 | Verdict: {evaluation.verdict.value}"
)
# 4. Troubleshooter patch (if revision needed)
if evaluation.verdict == EvaluationVerdict.REVISE and iteration < self.max_iterations_per_step:
current_patch = self._call_troubleshooter(step, current_draft, critique)
else:
current_patch = TroubleshooterPatch(remediation_steps=[], revised_instructions="Approved by Evaluator.")
iteration_records.append(
IterationAuditRecord(
iteration_number=iteration,
duration_seconds=iter_duration,
sme_draft=current_draft,
critique=critique,
troubleshooter_patch=current_patch,
evaluation=evaluation,
)
)
if evaluation.verdict == EvaluationVerdict.PASSED:
converged = True
self.log(f" -> Passed quality gate on iteration {iteration}.")
break
total_time = time.time() - start_time
final_eval = iteration_records[-1].evaluation
step.progress_pct = 100.0
step.status = ExecutionStatus.COMPLETED
step.output = current_draft
result = StepExecutionResult(
step_id=step.step_id,
total_time_seconds=total_time,
final_score=final_eval.overall_score,
converged=converged,
iterations=iteration_records,
final_output=current_draft,
)
self.step_results[step.step_id] = result
return result
# --- Dynamic Workflow Governor ---
def assess_and_mutate_plan(self, completed_step: StepPlan, obj: ObjectiveRecord) -> PlanMutationDirective:
"""The Governor re-assesses future steps and IFR against newly discovered realities."""
remaining_steps = [s for s in obj.steps if s.status == ExecutionStatus.PENDING]
if not remaining_steps:
return PlanMutationDirective(mutation_type=PlanMutationType.NO_CHANGE, rationale="No pending steps remain.")
self.log("[Workflow Governor] Re-assessing execution graph based on completed artifact...")
prompt = f"""
You are the Chief Workflow Governor.
Current Objective: {obj.title}
Ideal Final Result (IFR): {obj.ideal_final_result}
JUST COMPLETED STEP:
Step ID: {completed_step.step_id}
Title: {completed_step.title}
Output Artifact:
{completed_step.output[:2500]}
REMAINING PLANNED STEPS:
{[{"step_id": s.step_id, "title": s.title, "how": s.how_to_do} for s in remaining_steps]}
GOVERNANCE DIRECTIVE:
Examine the findings, constraints, or configurations discovered in the completed step.
- Are any downstream steps now redundant, solved, or obsolete? (REMOVE_STEPS)
- Did we discover dependencies, prerequisites, or unexpected risks requiring new tasks? (INJECT_STEPS)
- Did discovered ground truth require recalibrating the target IFR? (PIVOT_OBJECTIVE_IFR)
- Or does the baseline plan remain fully sound? (NO_CHANGE)
Ensure any injected steps specify unique step_ids, what_to_do, how_to_do, and assigned_role.
"""
response = self.client.models.generate_content(
model=self.model_id,
contents=prompt,
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=PlanMutationDirective,
temperature=0.2,
),
)
directive: PlanMutationDirective = response.parsed
self._apply_mutation(directive, obj, completed_step)
return directive
def _apply_mutation(self, directive: PlanMutationDirective, obj: ObjectiveRecord, completed_step: StepPlan):
if directive.mutation_type == PlanMutationType.NO_CHANGE:
self.log("[Workflow Governor] Verification complete: Roadmap validated. Proceeding.")
return
self.log(f"⚡ [WORKFLOW MUTATION] {directive.mutation_type.value}: {directive.rationale}")
self.governor_actions.append({
"trigger_step": completed_step.step_id,
"type": directive.mutation_type.value,
"rationale": directive.rationale,
})
# 1. Prune invalidated steps
if directive.steps_to_remove:
for s in obj.steps:
if s.step_id in directive.steps_to_remove and s.status == ExecutionStatus.PENDING:
s.status = ExecutionStatus.PRUNED
self.log(f" ↳ Pruned redundant step: [{s.step_id}] {s.title}")
# 2. Inject emergent steps directly after the completed step
if directive.steps_to_inject:
curr_index = obj.steps.index(completed_step)
for offset, new_step in enumerate(directive.steps_to_inject, start=1):
new_step.status = ExecutionStatus.PENDING
obj.steps.insert(curr_index + offset, new_step)
self.log(f" ↳ Injected step: [{new_step.step_id}] {new_step.title} (Role: {new_step.assigned_role})")
# 3. Recalibrate IFR if necessary
if directive.revised_ifr:
self.log(f" ↳ Recalibrated IFR: '{directive.revised_ifr}'")
obj.ideal_final_result = directive.revised_ifr
# --- Autonomous Workflow Loop ---
def run_autonomous_pipeline(self, raw_statement: str):
"""Orchestrates end-to-end autonomous execution with dynamic workflow mutation."""
self.reframe_and_decompose(raw_statement)
total_executed_steps = 0
for obj in self.objectives:
self.log(f"\n{'='*70}\nProcessing Objective: {obj.title}\n{'='*70}")
# Dynamic loop: list length can mutate via inject/prune during iteration
step_idx = 0
while step_idx < len(obj.steps):
step = obj.steps[step_idx]
if step.status != ExecutionStatus.PENDING:
step_idx += 1
continue
if total_executed_steps >= self.max_total_steps:
self.log(f"Safety guard: reached maximum total steps ({self.max_total_steps}). Terminating.")
break
# 1. Execute via Multi-Agent Council
self.execute_step_council(step, obj)
total_executed_steps += 1
# 2. Dynamic Workflow Governor re-assessment
self.assess_and_mutate_plan(step, obj)
step_idx += 1
# --- Reporting & Artifact Generation ---
def render_mind_map(self) -> str:
lines = [
"=" * 70,
"AIPS Autonomous Mind Map",
"=" * 70,
f"Original Statement: {self.initial_statement}",
f"Reframed Core: {self.reframed_statement}",
"Objectives & Execution Graph:",
]
for idx, obj in enumerate(self.objectives, 1):
lines.append(f" {idx}. Objective: {obj.title}")
lines.append(f" - Current State: {obj.current_state}")
lines.append(f" - Target IFR: {obj.ideal_final_result}")
lines.append(" - Operational Sequence:")
for s in obj.steps:
res = self.step_results.get(s.step_id)
score_str = f"Score: {res.final_score:.1f}/100" if res else "Pending"
mark = "[X]" if s.status == ExecutionStatus.COMPLETED else ("[--]" if s.status == ExecutionStatus.PRUNED else "[ ]")
lines.append(f" {mark} [{s.step_id}] {s.title} ({s.status.value}) | {score_str}")
lines.append("=" * 70)
return "\n".join(lines)
def compile_final_report(self) -> str:
report = [
"# AI Assisted Problem Solving (AIPS) - Autonomous Report\n",
"## 1. Problem Formulation & TRIZ Reframing",
f"**Initial User Prompt:** {self.initial_statement}\n",
f"**Reframed Root Contradiction:** {self.reframed_statement}\n",
"## 2. Dynamic Execution Matrix",
]
for idx, obj in enumerate(self.objectives, 1):
report.append(f"### Objective {idx}: {obj.title}")
report.append(f"- **Current Baseline:** {obj.current_state}")
report.append(f"- **Final Ideal Result (IFR):** {obj.ideal_final_result}\n")
report.append("| Step ID | Step Title | Status | Cycles | Score | Duration |")
report.append("| :--- | :--- | :---: | :---: | :---: | :---: |")
for s in obj.steps:
res = self.step_results.get(s.step_id)
if res:
report.append(
f"| `{s.step_id}` | {s.title} | {s.status.value} | "
f"{len(res.iterations)} | **{res.final_score:.1f}/100** | {res.total_time_seconds:.2f}s |"
)
else:
report.append(f"| `{s.step_id}` | {s.title} | {s.status.value} | - | - | - |")
report.append("")
if self.governor_actions:
report.append("## 3. Dynamic Workflow Mutations (Governor Log)")
for g in self.governor_actions:
report.append(f"- **Triggered by `{g['trigger_step']}` ({g['type']}):** {g['rationale']}")
report.append("")
report.append("## 4. Approved Technical Deliverables")
for obj in self.objectives:
for s in obj.steps:
res = self.step_results.get(s.step_id)
if not res:
continue
report.append(f"### `{s.step_id}`: {s.title}")
report.append(f"**Assigned Persona:** {s.assigned_role} | **Score:** {res.final_score:.1f}/100\n")
report.append(f"```markdown\n{res.final_output}\n```\n")
total_time = sum(r.total_time_seconds for r in self.step_results.values())
avg_score = (
sum(r.final_score for r in self.step_results.values()) / max(len(self.step_results), 1)
)
report.append("## 5. Summary of Final Position")
report.append(f"- **Total Council Execution Time:** {total_time:.2f} seconds")
report.append(f"- **Average Quality Score:** {avg_score:.2f} / 100")
report.append(f"- **Workflow Mutations Applied:** {len(self.governor_actions)}")
report.append("\n## 6. Next Steps")
report.append("1. Feed the approved deliverables into continuous integration or deployment pipelines.")
report.append("2. Monitor production telemetry for anomalies identified in the Critic reviews.")
return "\n".join(report)
def save_artifacts(self, log_path: str = "worklog.md", report_path: str = "final_report.md"):
with open(log_path, "w", encoding="utf-8") as f:
f.write("# AIPS Autonomous Worklog\n\n")
f.write(f"- Initial Problem: {self.initial_statement}\n")
f.write(f"- Reframed Core: {self.reframed_statement}\n")
f.write(f"- Timestamp: {datetime.now().isoformat()}\n\n")
f.write("## Execution Trace\n\n")
for entry in self.worklog:
f.write(f"- {entry}\n")
with open(report_path, "w", encoding="utf-8") as f:
f.write(self.compile_final_report())
print(f"\n[Artifacts Written] -> '{log_path}' & '{report_path}'")
# ---------------------------------------------------------------------------
# 3. Main Entrypoint
# ---------------------------------------------------------------------------
def main():
if not os.environ.get("GEMINI_API_KEY"):
print("Error: GEMINI_API_KEY environment variable is not set.")
sys.exit(1)
print("=================================================================")
print(" AIPS: Autonomous Iterative Problem Solver with Dynamic Governor")
print("=================================================================")
# Non-blocking input: accepts user prompt or falls back to complex scenario
raw_statement = input("\nEnter problem statement (or press Enter for default):\n> ").strip()
if not raw_statement:
raw_statement = (
"We are migrating our monolith's user authentication system to an OAuth2/OIDC provider "
"with zero downtime, but we have 4 million legacy session records stored in Redis with no expiration."
)
print(f"\nUsing default enterprise scenario:\n\"{raw_statement}\"\n")
engine = AIPSAutonomousEngine(
model_id="gemini-2.5-flash",
target_pass_score=85.0,
max_iterations_per_step=3,
max_total_steps=12,
)
# Execute end-to-end without human intervention
engine.run_autonomous_pipeline(raw_statement)
# Print Mind Map
print("\n" + engine.render_mind_map())
# Save Markdown reports
engine.save_artifacts("worklog.md", "final_report.md")
if __name__ == "__main__":
main()
Key Operational Changes
| Component | Functionality |
| No Human Prompts | input() branching prompts have been stripped out. The engine processes steps sequentially while dynamically mutating the list in-flight. |
| PlanMutationDirective | Structured JSON schema returned by the Governor that instructs the engine to prune steps (steps_to_remove), insert immediate sub-steps (steps_to_inject), or recalibrate the TRIZ IFR (revised_ifr). |
Dynamic while Loop | The pipeline iterates through obj.steps using an index rather than a static for loop, allowing new steps injected at runtime to execute naturally before moving to downstream items. |
| Pruning vs. Execution | Obsolete steps are marked PRUNED and displayed as [--] in the Mind Map and final report matrix, preserving an audit trail of decisions made mid-run. |
| Markdown Persistence | worklog.md contains the raw timestamped trace; final_report.md contains the full breakdown of governor mutations, scores, execution durations, and final artifacts. |
From <https://gemini.google.com/app/71b091812d864c4e> Google Gemini (3.8 Flash)
Comments
Post a Comment