How OasisProfileGenerator Creates Agent Profiles from Seed Information
OasisProfileGenerator converts raw Zep graph entities into structured OASIS-compatible agent profiles by enriching seed data with hybrid graph searches, applying LLM-based or rule-based generation strategies, and validating JSON output through multi-layer error recovery.
The OasisProfileGenerator class in the 666ghj/mirofish repository transforms sparse Zep entity nodes into fully-featured OASIS agent profiles through a robust pipeline that combines graph traversal with large language model inference. Located in backend/app/services/oasis_profile_generator.py, this component bridges raw seed information and simulation-ready personas by systematically enriching context, generating structured attributes, and ensuring deterministic fallbacks when AI services are unavailable.
Generator Initialization and Credential Management
The pipeline begins in the __init__ method (lines 80‑100) of backend/app/services/oasis_profile_generator.py, which initializes the OpenAI client using configuration values for api_key, base_url, and model_name. When a Zep API key is provided, the constructor also instantiates a Zep client (self.zep_client) to enable hybrid graph searches for supplemental context.
def __init__(self,
api_key: Optional[str] = None,
base_url: Optional[str] = None,
model_name: Optional[str] = None,
zep_api_key: Optional[str] = None,
graph_id: Optional[str] = None):
self.api_key = api_key or Config.LLM_API_KEY
self.base_url = base_url or Config.LLM_BASE_URL
self.model_name = model_name or Config.LLM_MODEL_NAME
self.client = OpenAI(api_key=self.api_key, base_url=self.base_url)
self.zep_api_key = zep_api_key or Config.ZEP_API_KEY
self.graph_id = graph_id
if self.zep_api_key:
self.zep_client = Zep(api_key=self.zep_api_key)
This initialization ensures both LLM and optional graph database connections are available for the enrichment phase.
Context Enrichment from Seed Entities
Before generating profiles, the system enriches raw seed data through the _build_entity_context method (lines 124‑166). This function aggregates the entity’s intrinsic attributes, directly-linked edges representing facts and relationships, and summaries of related nodes. For deeper context, it invokes _search_zep_for_entity (lines 86‑122) to execute parallel hybrid searches against Zep’s edge and node indices, deduplicating results to create a comprehensive context string capped at 3000 characters.
The enrichment process ensures that even sparse seed entities carry sufficient narrative detail to generate coherent agent personas, drawing from both the immediate graph neighborhood and broader semantic matches in the Zep knowledge base.
Selecting the Generation Strategy
The generate_profile_from_entity method (lines 112‑132) serves as the orchestration layer that determines whether to use AI-driven or deterministic generation. When use_llm=True, the system routes to _generate_profile_with_llm (lines 150‑197); otherwise, it falls back to _generate_profile_rule_based to ensure profile creation continues even during API outages.
if use_llm:
profile_data = self._generate_profile_with_llm(...)
else:
profile_data = self._generate_profile_rule_based(...)
This dual-path architecture guarantees that OasisProfileGenerator can create agent profiles under varying infrastructure constraints.
LLM Prompt Engineering and Robust JSON Handling
For LLM-driven generation, the system constructs specialized prompts based on entity type. Individual entities trigger _build_individual_persona_prompt (lines 176‑224), while groups or institutions invoke _build_group_persona_prompt (lines 226‑274). Both templates embed the enriched context and enforce a strict JSON schema requiring fields such as bio, persona, age, gender, mbti, country, profession, and interested_topics.
The _generate_profile_with_llm method (lines 150‑197) executes the API call with a forced JSON response format and implements progressive temperature reduction on retries (temperature=0.7 - (attempt * 0.1)). When the LLM returns truncated output (finish reason 'length'), _fix_truncated_json (lines 182‑206) attempts automatic bracket closure. For malformed JSON, _try_fix_json (lines 208‑272) extracts partial structures, repairs newline characters, and ultimately falls back to a minimal safe dictionary to prevent pipeline failure.
Assembling the OasisAgentProfile Dataclass
Whether generated by LLM or rules, the final data flows into the OasisAgentProfile dataclass constructor (lines 154‑173 in the return statement). This structure maps extracted or default values to required OASIS fields:
- Identity:
user_id,user_name,name - Narrative:
bio,persona - Platform Metrics:
karma,friend_count,follower_count,statuses_count(populated with random defaults if unspecified) - Demographics:
age,gender,mbti,country,profession,interested_topics - Provenance:
source_entity_uuid,source_entity_type
return OasisAgentProfile(
user_id=user_id,
user_name=user_name,
name=name,
bio=profile_data.get("bio", f"{entity_type}: {name}"),
persona=profile_data.get("persona", entity.summary or f"A {entity_type} named {name}."),
karma=profile_data.get("karma", random.randint(500, 5000)),
friend_count=profile_data.get("friend_count", random.randint(50, 500)),
follower_count=profile_data.get("follower_count", random.randint(100, 1000)),
statuses_count=profile_data.get("statuses_count", random.randint(100, 2000)),
age=profile_data.get("age"),
gender=profile_data.get("gender"),
mbti=profile_data.get("mbti"),
country=profile_data.get("country"),
profession=profile_data.get("profession"),
interested_topics=profile_data.get("interested_topics", []),
source_entity_uuid=entity.uuid,
source_entity_type=entity_type,
)
Batch Generation and Concurrency
For processing multiple seeds efficiently, generate_profiles_from_entities (lines 208‑285) implements a ThreadPoolExecutor to parallelize individual profile creation. This method accepts a progress_callback for real-time UI updates and supports realtime_output_path to stream interim results to disk, preventing data loss during long-running batch jobs. The parallel_count parameter controls concurrency levels, allowing operators to balance throughput against API rate limits.
Practical Implementation Examples
Generating a Single Profile
To create a profile from a specific Zep entity:
from backend.app.services.oasis_profile_generator import OasisProfileGenerator
from backend.app.services.zep_entity_reader import ZepEntityReader
entity = ZepEntityReader().read_entity(entity_uuid="1234-abcd")
generator = OasisProfileGenerator()
profile = generator.generate_profile_from_entity(
entity=entity,
user_id=42,
use_llm=True
)
print(profile.to_reddit_format())
Batch Processing with Progress Tracking
For large-scale generation:
def progress(current, total, msg):
print(f"[{current}/{total}] {msg}")
entities = ZepEntityReader().read_entities_from_graph(graph_id="my-graph")
generator = OasisProfileGenerator(zep_api_key="ZEP_KEY", graph_id="my-graph")
profiles = generator.generate_profiles_from_entities(
entities=entities,
use_llm=True,
progress_callback=progress,
parallel_count=8,
realtime_output_path="output/reddit_profiles.json",
output_platform="reddit"
)
Summary
- OasisProfileGenerator in
backend/app/services/oasis_profile_generator.pyorchestrates the transformation of Zep graph entities into OASIS-compatible agent profiles through a multi-stage pipeline. - The system enriches sparse seed information via
_build_entity_contextand hybrid Zep searches, ensuring rich narrative inputs for generation. - Dual generation strategies (LLM-based via
_generate_profile_with_llmand rule-based fallback) guarantee operational resilience, with automatic JSON repair mechanisms handling truncation and parsing errors. - Output conforms strictly to the
OasisAgentProfiledataclass structure, supporting serialization to Reddit and Twitter platform formats. - Batch operations leverage thread pools and real-time persistence to efficiently process large entity graphs while maintaining progress visibility.
Frequently Asked Questions
What input format does OasisProfileGenerator require to create agent profiles?
The generator accepts EntityNode objects from the Zep graph database, typically retrieved via ZepEntityReader. These entities contain seed information including UUIDs, types, summaries, and attribute dictionaries that serve as the foundation for profile generation.
How does OasisProfileGenerator handle LLM API failures or malformed responses?
The implementation features a multi-layer resilience strategy. If the LLM call fails or returns invalid JSON, _fix_truncated_json (lines 182‑206) and _try_fix_json (lines 208‑272) attempt automated repairs. When use_llm=False or all recovery attempts fail, the system falls back to _generate_profile_rule_based to produce deterministic profiles using templates and default values.
Can OasisProfileGenerator create profiles for organizations and groups, or only individuals?
The generator supports both entity types through specialized prompt engineering. The generate_profile_from_entity method routes individual entities to _build_individual_persona_prompt (lines 176‑224) and groups/institutions to _build_group_persona_prompt (lines 226‑274), ensuring appropriate narrative structures for each category.
What social media platforms are supported for profile export?
The OasisAgentProfile dataclass provides native serialization methods including to_reddit_format() and to_twitter_format(), generating platform-specific data structures compatible with Reddit and Twitter simulation environments, respectively.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →