Summary
praisonaiagents builds a single, model-agnostic system prompt and advertises a fixed coding tool-set to every model. Different model families (GPT, Claude, Gemini, and reasoning variants) differ materially in how they parse tool schemas, follow output/formatting instructions, and succeed with different file-edit formats. A single prompt + single tool shape is a quality ceiling for a multi-provider SDK. This proposes an opt-in, protocol-driven "runtime profile" registry that maps a model family to a system-prompt profile and a preferred edit-tool format, with today's behaviour as the default profile.
Current behaviour
src/praisonai-agents/praisonaiagents/agent/chat_mixin.py — _build_system_prompt(tools) composes one prompt (role/goal/backstory/rules/memory) used verbatim for every model. There is no per-family variation.
src/praisonai-agents/praisonaiagents/toolsets.py (the coding toolset, ~line 270) always advertises the same edit_file + apply_patch + write_file set regardless of the active model.
src/praisonai-agents/praisonaiagents/llm/llm.py — the only model-specific branching is narrow (prompt-cache control for Anthropic, a Gemini prompt tweak). There is no first-class notion of a per-family prompt/tool profile.
- No
prompt_profile / model_profile registry exists anywhere in agent/, llm/, or config/ (grep is empty).
Net effect: prompt wording and edit-tool selection cannot be tuned per model without editing core code, and the SDK cannot ship best-practice defaults per family.
Desired behaviour
- A lightweight registry maps a model family (resolved from the model id/provider) to a RuntimeProfile: an optional system-prompt template/segment overrides and a preferred edit-tool format (e.g. patch-oriented vs string-replace vs whole-file), plus room for family-specific knobs.
_build_system_prompt and tool materialisation consult the resolved profile; when no profile matches, behaviour is identical to today (fully backward compatible).
- Profiles are overridable by users at all layers (see 3-way surface) and extendable by third parties via an entry-point group, consistent with the existing registry pattern.
Layer placement
- Primary layer: core (
praisonaiagents)
- Why not core: n/a — this is core: it changes how the agent runtime assembles the system prompt and selects built-in edit tools, the heart of the run loop.
- Why not wrapper: the wrapper cannot influence per-turn prompt assembly or tool materialisation; it only passes config down. It should merely expose the setting.
- Why not tools: individual tools do not (and should not) decide which prompt or which edit format the runtime uses; that is a runtime-level decision spanning multiple tools.
- Why not plugins: lifecycle hooks fire around a run but do not own baseline system-prompt construction or the built-in edit-tool set; a policy plugin could tweak text but cannot cleanly switch the advertised edit-tool format per model.
- Secondary touch (optional): wrapper — surface
agent.profile/--profile-model and a config key; docs.
- 3-way surface (CLI + YAML + Python): yes —
Agent(runtime_profile=...) in Python, agent.profile: in .praisonai/config.yaml, and a --profile-style flag for praisonai run.
Proposed approach
- Add
praisonaiagents/runtime/profiles.py with a RuntimeProfileProtocol and a thread-safe RuntimeProfileRegistry (mirroring runtime/registry.py and tools/registry.py), including entry-point discovery (praisonaiagents.runtime_profiles).
- Resolve the family from the model id/provider (reuse existing model/provider resolution) and look up a profile; fall back to a
default profile that reproduces current output exactly.
- Have
_build_system_prompt apply profile prompt overrides (segment-level, so caching and rules/memory injection are preserved) and have tool materialisation honour the profile's preferred edit-tool format.
- Ship a small set of sensible built-in profiles; keep them data-driven so tuning does not require code changes.
Resolution sketch
runtime/profiles.py: RuntimeProfileProtocol, RuntimeProfile dataclass (system_prompt_overrides, preferred_edit_format, extras), register_profile/resolve_profile/list_profiles.
agent/chat_mixin.py::_build_system_prompt: after composing the base prompt, apply resolve_profile(model).apply(...); unchanged when profile is default.
- Tool materialisation /
toolsets.py: choose edit tool by preferred_edit_format.
Agent.__init__: accept runtime_profile (bool/str/dict/Profile), consistent with the existing config-object convention.
Severity
Medium — no correctness regression today, but it caps output quality/reliability across providers and forces core edits to tune per-model behaviour, which matters for a production, multi-provider SDK.
Validation
- Traced: single
_build_system_prompt in agent/chat_mixin.py; fixed coding toolset in toolsets.py; only cache/Gemini branching in llm/llm.py; no profile registry present.
- Real agentic test:
agent.start("<real coding task>") on two different model families should show the family-appropriate prompt profile and edit format being selected (and identical-to-today output when the default profile is active).
- Backward compatibility: with no profile configured, generated prompts and advertised tools are byte-for-byte unchanged.
Summary
praisonaiagentsbuilds a single, model-agnostic system prompt and advertises a fixed coding tool-set to every model. Different model families (GPT, Claude, Gemini, and reasoning variants) differ materially in how they parse tool schemas, follow output/formatting instructions, and succeed with different file-edit formats. A single prompt + single tool shape is a quality ceiling for a multi-provider SDK. This proposes an opt-in, protocol-driven "runtime profile" registry that maps a model family to a system-prompt profile and a preferred edit-tool format, with today's behaviour as the default profile.Current behaviour
src/praisonai-agents/praisonaiagents/agent/chat_mixin.py—_build_system_prompt(tools)composes one prompt (role/goal/backstory/rules/memory) used verbatim for every model. There is no per-family variation.src/praisonai-agents/praisonaiagents/toolsets.py(thecodingtoolset, ~line 270) always advertises the sameedit_file+apply_patch+write_fileset regardless of the active model.src/praisonai-agents/praisonaiagents/llm/llm.py— the only model-specific branching is narrow (prompt-cache control for Anthropic, a Gemini prompt tweak). There is no first-class notion of a per-family prompt/tool profile.prompt_profile/model_profileregistry exists anywhere inagent/,llm/, orconfig/(grep is empty).Net effect: prompt wording and edit-tool selection cannot be tuned per model without editing core code, and the SDK cannot ship best-practice defaults per family.
Desired behaviour
_build_system_promptand tool materialisation consult the resolved profile; when no profile matches, behaviour is identical to today (fully backward compatible).Layer placement
praisonaiagents)agent.profile/--profile-modeland a config key; docs.Agent(runtime_profile=...)in Python,agent.profile:in.praisonai/config.yaml, and a--profile-style flag forpraisonai run.Proposed approach
praisonaiagents/runtime/profiles.pywith aRuntimeProfileProtocoland a thread-safeRuntimeProfileRegistry(mirroringruntime/registry.pyandtools/registry.py), including entry-point discovery (praisonaiagents.runtime_profiles).defaultprofile that reproduces current output exactly._build_system_promptapply profile prompt overrides (segment-level, so caching and rules/memory injection are preserved) and have tool materialisation honour the profile's preferred edit-tool format.Resolution sketch
runtime/profiles.py:RuntimeProfileProtocol,RuntimeProfiledataclass (system_prompt_overrides,preferred_edit_format,extras),register_profile/resolve_profile/list_profiles.agent/chat_mixin.py::_build_system_prompt: after composing the base prompt, applyresolve_profile(model).apply(...); unchanged when profile isdefault.toolsets.py: choose edit tool bypreferred_edit_format.Agent.__init__: acceptruntime_profile(bool/str/dict/Profile), consistent with the existing config-object convention.Severity
Medium — no correctness regression today, but it caps output quality/reliability across providers and forces core edits to tune per-model behaviour, which matters for a production, multi-provider SDK.
Validation
_build_system_promptinagent/chat_mixin.py; fixed coding toolset intoolsets.py; only cache/Gemini branching inllm/llm.py; no profile registry present.agent.start("<real coding task>")on two different model families should show the family-appropriate prompt profile and edit format being selected (and identical-to-today output when thedefaultprofile is active).