feat(ai): add per-character AI model assignment and identity profiles

Implements deterministic model resolution (column → env map → pool →
default) and adds AI identity fields to characters. Migration backfills
existing rows with deterministic defaults. Controller uses resolved model
and identity block in system prompts for contextual conversations.
This commit is contained in:
2026-10-31 18:35:57 -03:00
parent 59963de995
commit 81be63b4c3
7 changed files with 354 additions and 13 deletions
+19 -1
View File
@@ -17,7 +17,8 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
* ticker mutates needs and job progress continuously while nobody is online.
*/
#[Fillable([
'user_id', 'city_id', 'name', 'skin', 'hair', 'shirt',
'user_id', 'city_id', 'name', 'ai_model', 'ai_age', 'ai_gender',
'ai_personality', 'ai_bio', 'skin', 'hair', 'shirt',
'pos_x', 'pos_y', 'pos_z', 'money', 'energy', 'hunger', 'thirst', 'health',
'state', 'job_id', 'house_id', 'education', 'exercise_count', 'is_online', 'last_tick_at',
'hospitalized_until', 'face', 'beard', 'accessory', 'ride_kind', 'ride_until',
@@ -27,6 +28,20 @@ class Character extends Model
/** @use HasFactory<CharacterFactory, $this> */
use HasFactory;
/**
* Default personality pool for characters created without one.
*
* @var list<string>
*/
public const AI_PERSONALITIES = [
'Extrovertido e curioso, adora puxar conversa com quem passa.',
'Tranquilo e observador, fala pouco mas escuta tudo com atenção.',
'Bem-humorado e espirituoso, brinca com todo mundo por perto.',
'Sério e direto, vai ao ponto sem rodeios.',
'Gentil e prestativo, sempre oferece ajuda antes de perguntarem.',
'Aventureiro e barulhento, vive contando histórias da cidade.',
];
public const STATE_AWAKE = 'awake';
public const STATE_SLEEPING = 'sleeping';
@@ -176,6 +191,8 @@ class Character extends Model
'user_id' => $user->id,
'city_id' => $city->id,
'name' => $firstName,
'ai_age' => random_int(18, 68),
'ai_personality' => self::AI_PERSONALITIES[array_rand(self::AI_PERSONALITIES)],
'skin' => random_int(1, 4),
'hair' => random_int(1, 4),
'shirt' => random_int(1, 5),
@@ -220,6 +237,7 @@ class Character extends Model
protected function casts(): array
{
return [
'ai_age' => 'integer',
'pos_x' => 'float',
'pos_y' => 'float',
'pos_z' => 'float',