feat: enhance agent identity profile with purpose and personality attributes
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -20,6 +20,6 @@ node_modules/
|
|||||||
|
|
||||||
# Accidental literal "~" directories (e.g. when a configured path contains "~" but isn't expanded)
|
# Accidental literal "~" directories (e.g. when a configured path contains "~" but isn't expanded)
|
||||||
backend/~/
|
backend/~/
|
||||||
backend/coverage.xml
|
backend/coverage.*
|
||||||
backend/.coverage
|
backend/.coverage
|
||||||
frontend/coverage
|
frontend/coverage
|
||||||
@@ -34,6 +34,9 @@ EXTRA_IDENTITY_PROFILE_FIELDS = {
|
|||||||
"verbosity": "identity_verbosity",
|
"verbosity": "identity_verbosity",
|
||||||
"output_format": "identity_output_format",
|
"output_format": "identity_output_format",
|
||||||
"update_cadence": "identity_update_cadence",
|
"update_cadence": "identity_update_cadence",
|
||||||
|
# Per-agent charter (optional). Used to give agents a "purpose in life" and a distinct vibe.
|
||||||
|
"purpose": "identity_purpose",
|
||||||
|
"personality": "identity_personality",
|
||||||
"custom_instructions": "identity_custom_instructions",
|
"custom_instructions": "identity_custom_instructions",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,16 +68,27 @@ const getBoardOptions = (boards: BoardRead[]): SearchableSelectOption[] =>
|
|||||||
label: board.name,
|
label: board.name,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const normalizeIdentityProfile = (
|
const mergeIdentityProfile = (
|
||||||
profile: IdentityProfile,
|
existing: unknown,
|
||||||
): IdentityProfile | null => {
|
patch: IdentityProfile,
|
||||||
const normalized: IdentityProfile = {
|
): Record<string, unknown> | null => {
|
||||||
role: profile.role.trim(),
|
const resolved: Record<string, unknown> =
|
||||||
communication_style: profile.communication_style.trim(),
|
existing && typeof existing === "object"
|
||||||
emoji: profile.emoji.trim(),
|
? { ...(existing as Record<string, unknown>) }
|
||||||
|
: {};
|
||||||
|
const updates: Record<string, string> = {
|
||||||
|
role: patch.role.trim(),
|
||||||
|
communication_style: patch.communication_style.trim(),
|
||||||
|
emoji: patch.emoji.trim(),
|
||||||
};
|
};
|
||||||
const hasValue = Object.values(normalized).some((value) => value.length > 0);
|
for (const [key, value] of Object.entries(updates)) {
|
||||||
return hasValue ? normalized : null;
|
if (value) {
|
||||||
|
resolved[key] = value;
|
||||||
|
} else {
|
||||||
|
delete resolved[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Object.keys(resolved).length > 0 ? resolved : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const withIdentityDefaults = (
|
const withIdentityDefaults = (
|
||||||
@@ -241,7 +252,8 @@ export default function EditAgentPage() {
|
|||||||
every: resolvedHeartbeatEvery.trim() || "10m",
|
every: resolvedHeartbeatEvery.trim() || "10m",
|
||||||
target: resolvedHeartbeatTarget,
|
target: resolvedHeartbeatTarget,
|
||||||
} as unknown as Record<string, unknown>,
|
} as unknown as Record<string, unknown>,
|
||||||
identity_profile: normalizeIdentityProfile(
|
identity_profile: mergeIdentityProfile(
|
||||||
|
loadedAgent.identity_profile,
|
||||||
resolvedIdentityProfile,
|
resolvedIdentityProfile,
|
||||||
) as unknown as Record<string, unknown> | null,
|
) as unknown as Record<string, unknown> | null,
|
||||||
soul_template: resolvedSoulTemplate.trim() || null,
|
soul_template: resolvedSoulTemplate.trim() || null,
|
||||||
|
|||||||
@@ -235,6 +235,11 @@ Body: {"depends_on_task_ids":["DEP_TASK_ID_1","DEP_TASK_ID_2"]}
|
|||||||
- When creating a new agent, always set `identity_profile.role` using real-world team roles so humans and other agents can coordinate quickly.
|
- When creating a new agent, always set `identity_profile.role` using real-world team roles so humans and other agents can coordinate quickly.
|
||||||
- Use Title Case role nouns: `Researcher`, `Analyst 1`, `Analyst 2`, `Engineer 1`, `QA`, `Reviewer`, `Scribe`.
|
- Use Title Case role nouns: `Researcher`, `Analyst 1`, `Analyst 2`, `Engineer 1`, `QA`, `Reviewer`, `Scribe`.
|
||||||
- If you create multiple agents with the same base role, number them sequentially starting at 1 (pick the next unused number by scanning the current agent list).
|
- If you create multiple agents with the same base role, number them sequentially starting at 1 (pick the next unused number by scanning the current agent list).
|
||||||
|
- When creating a new agent, always give them a lightweight "charter" so they are not a generic interchangeable worker:
|
||||||
|
- The charter must be derived from the requirements of the work you plan to delegate next (tasks, constraints, success metrics, risks). If you cannot articulate it, do **not** create the agent yet.
|
||||||
|
- Set `identity_profile.purpose` (1-2 sentences): what outcomes they own, what artifacts they should produce, and how it advances the board objective.
|
||||||
|
- Set `identity_profile.personality` (short): a distinct working style that changes decisions and tradeoffs (e.g., speed vs correctness, skeptical vs optimistic, detail vs breadth).
|
||||||
|
- Optional: set `identity_profile.custom_instructions` when you need stronger guardrails (3-8 short bullets). Examples: "always cite sources", "always propose tests", "prefer smallest change", "ask clarifying questions before coding", "do not touch prod configs".
|
||||||
Agent create (lead‑allowed):
|
Agent create (lead‑allowed):
|
||||||
POST $BASE_URL/api/v1/agent/agents
|
POST $BASE_URL/api/v1/agent/agents
|
||||||
Body example:
|
Body example:
|
||||||
@@ -243,6 +248,8 @@ Body: {"depends_on_task_ids":["DEP_TASK_ID_1","DEP_TASK_ID_2"]}
|
|||||||
"board_id": "$BOARD_ID",
|
"board_id": "$BOARD_ID",
|
||||||
"identity_profile": {
|
"identity_profile": {
|
||||||
"role": "Researcher",
|
"role": "Researcher",
|
||||||
|
"purpose": "Find authoritative sources on X and write a 10-bullet summary with links + key risks.",
|
||||||
|
"personality": "curious, skeptical, citation-happy, concise",
|
||||||
"communication_style": "concise, structured",
|
"communication_style": "concise, structured",
|
||||||
"emoji": ":brain:"
|
"emoji": ":brain:"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,3 +9,11 @@ Creature: {{ identity_role }}
|
|||||||
Vibe: {{ identity_communication_style }}
|
Vibe: {{ identity_communication_style }}
|
||||||
|
|
||||||
Emoji: {{ identity_emoji }}
|
Emoji: {{ identity_emoji }}
|
||||||
|
|
||||||
|
{% if identity_purpose %}
|
||||||
|
Purpose: {{ identity_purpose }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if identity_personality %}
|
||||||
|
Personality: {{ identity_personality }}
|
||||||
|
{% endif %}
|
||||||
|
|||||||
@@ -15,6 +15,12 @@ every message.
|
|||||||
- Role: {{ identity_role }}
|
- Role: {{ identity_role }}
|
||||||
- Communication: {{ identity_communication_style }}
|
- Communication: {{ identity_communication_style }}
|
||||||
- Emoji: {{ identity_emoji }}
|
- Emoji: {{ identity_emoji }}
|
||||||
|
{% if identity_purpose %}
|
||||||
|
- Purpose: {{ identity_purpose }}
|
||||||
|
{% endif %}
|
||||||
|
{% if identity_personality %}
|
||||||
|
- Personality: {{ identity_personality }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if board_id is defined %}
|
{% if board_id is defined %}
|
||||||
- Board: {{ board_name }}
|
- Board: {{ board_name }}
|
||||||
|
|||||||
Reference in New Issue
Block a user