php-agentic/Models/WorkspaceState.php

148 lines
3.3 KiB
PHP
Raw Normal View History

2026-01-27 00:28:29 +00:00
<?php
declare(strict_types=1);
namespace Core\Mod\Agentic\Models;
2026-01-27 00:28:29 +00:00
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* Workspace State Model
*
* Key-value state storage for agent plans with typed content.
*/
class WorkspaceState extends Model
{
use HasFactory;
public const TYPE_JSON = 'json';
public const TYPE_MARKDOWN = 'markdown';
public const TYPE_CODE = 'code';
public const TYPE_REFERENCE = 'reference';
protected $fillable = [
'agent_plan_id',
'key',
'value',
'type',
'metadata',
];
protected $casts = [
'metadata' => 'array',
];
protected $attributes = [
'type' => self::TYPE_JSON,
'metadata' => '{}',
];
public function plan(): BelongsTo
{
return $this->belongsTo(AgentPlan::class, 'agent_plan_id');
}
/**
* Get typed value.
*/
public function getTypedValue(): mixed
{
return match ($this->type) {
self::TYPE_JSON => json_decode($this->value, true),
default => $this->value,
};
}
/**
* Set typed value.
*/
public function setTypedValue(mixed $value): void
{
$storedValue = match ($this->type) {
self::TYPE_JSON => json_encode($value),
default => (string) $value,
};
$this->update(['value' => $storedValue]);
}
/**
* Get or create state for a plan.
*/
public static function getOrCreate(AgentPlan $plan, string $key, mixed $default = null, string $type = self::TYPE_JSON): self
{
$state = static::where('agent_plan_id', $plan->id)
->where('key', $key)
->first();
if (! $state) {
$value = match ($type) {
self::TYPE_JSON => json_encode($default),
default => (string) ($default ?? ''),
};
$state = static::create([
'agent_plan_id' => $plan->id,
'key' => $key,
'value' => $value,
'type' => $type,
]);
}
return $state;
}
/**
* Set state value for a plan.
*/
public static function set(AgentPlan $plan, string $key, mixed $value, string $type = self::TYPE_JSON): self
{
$storedValue = match ($type) {
self::TYPE_JSON => json_encode($value),
default => (string) $value,
};
return static::updateOrCreate(
['agent_plan_id' => $plan->id, 'key' => $key],
['value' => $storedValue, 'type' => $type]
);
}
/**
* Get state value for a plan.
*/
public static function get(AgentPlan $plan, string $key, mixed $default = null): mixed
{
$state = static::where('agent_plan_id', $plan->id)
->where('key', $key)
->first();
if (! $state) {
return $default;
}
return $state->getTypedValue();
}
/**
* Scope: for plan.
*/
public function scopeForPlan($query, int $planId)
{
return $query->where('agent_plan_id', $planId);
}
/**
* Scope: by type.
*/
public function scopeByType($query, string $type)
{
return $query->where('type', $type);
}
}