feat: add TraitsTab component for managing agent traits
Some checks failed
CI / build-and-test (push) Failing after -32m5s

- Implemented TraitsTab.svelte to handle CRUD operations for agent traits.
- Integrated grid for displaying traits with context menu actions for add, edit, and delete.
- Added trait instruction editing functionality with a dedicated editor.
- Updated AdminShell to include PersonasPage for navigation.
- Enhanced AppSidebar with a new entry for Personas.
- Extended ShellPage type to include 'personas'.
- Defined new types for AgentPersona, AgentPart, and AgentTrait in types.ts.
This commit is contained in:
2026-05-05 14:51:58 +02:00
parent e285a03639
commit 9230f39cb6
48 changed files with 6979 additions and 2240 deletions

View File

@@ -11,7 +11,8 @@ RELEASE_REMOTE ?= origin
VERSION_TAG ?= $(shell git describe --tags --exact-match 2>/dev/null || echo dev)
COMMIT_SHA ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
BUILD_DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
RELSPEC ?= $(shell command -v relspec 2>/dev/null || echo $(HOME)/go/bin/relspec)
#RELSPEC ?= $(shell command -v relspec 2>/dev/null || echo $(HOME)/go/bin/relspec)
RELSPEC = /home/hein/dev/relspecgo/build/relspec
SCHEMA_FILES := $(sort $(wildcard schema/*.dbml))
MERGE_TARGET_TMP := $(CURDIR)/.cache/schema.merge-target.dbml
GENERATED_SCHEMA_MIGRATION := migrations/020_generated_schema.sql

View File

@@ -0,0 +1,20 @@
Completed personas UI reachability and fixed the missing backend ResolveSpec registrations that blocked it.
- Added Personas navigation/page wiring in the Svelte admin shell.
- Added a personas overview page with tabs for personas, parts, and traits.
- Expanded the persona inspector to load linked parts, traits, skills, guardrails, and arc state.
- Found that `/api/rs/public/agent_parts` and related persona routes were missing because `internal/app/resolvespec_admin.go` manually whitelists ResolveSpec models.
- Registered persona-related ResolveSpec models: `agent_personas`, `agent_parts`, `agent_traits`, persona join tables, arc tables, and `persona_arc`.
- Allowed ResolveSpec mutations for `agent_personas`, `agent_parts`, and `agent_traits`.
- Verified the `internal/app` package still compiles with `env GOCACHE=/tmp/amcs-go-cache go test -run '^$' ./internal/app`.
Follow-up:
- Automated ResolveSpec model registration generation with `relspec templ`.
- Added `scripts/templates/resolvespec_models.tmpl`.
- Updated `scripts/generate-models.sh` to generate `internal/app/resolvespec_models_generated.go`.
- Removed the handwritten `resolveSpecModels()` from `internal/app/resolvespec_admin.go`.
- Extended `scripts/patch-generated-models.sh` to fix current relspec output quirks:
- incorrect `persona_arc` primary-key cast
- unused `resolvespec_common` imports in join-table models
- Added focused tests covering persona entity presence and persona mutation allowlisting.

View File

@@ -0,0 +1,15 @@
Fixed the Gitea build break caused by `go:embed` requiring `internal/app/ui/dist` to exist in a clean checkout.
Changes made:
- Added `internal/app/ui/dist/placeholder.txt` so the embedded UI directory is always present in source control.
- Updated `internal/mcpserver/server_test.go` to derive expected tool names from `BuildToolCatalog()` instead of a stale hard-coded list.
- Removed stale maintenance tool entries from `internal/mcpserver/server.go` because those tools are not currently registered.
Verification:
- `env GOCACHE=/tmp/go-build go test ./internal/mcpserver -run TestNewListsAllRegisteredTools -v` passes.
- A broader `go test ./internal/app ./cmd/amcs-server` compile check was started, but it did not finish before this log entry was written.
Migration follow-up:
- Fixed `migrations/020_generated_schema.sql` after PostgreSQL failed with `operator does not exist: name[] = text[]`.
- Root cause: `pg_attribute.attname` is type `name`, so `ARRAY(SELECT a.attname ...)` produced `name[]`, which was compared against `text[]` literals.
- Updated each repeated primary-key introspection block to use `SELECT a.attname::text`, keeping the existing `ARRAY[]::text[]` and `ARRAY['id']` / `ARRAY['persona_id']` comparisons valid.

View File

@@ -9,7 +9,6 @@ import (
"github.com/bitechdev/ResolveSpec/pkg/resolvespec"
"github.com/uptrace/bunrouter"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
"git.warky.dev/wdevs/amcs/internal/store"
)
@@ -84,6 +83,21 @@ func registerResolveSpecGuards(rs *resolvespec.Handler) {
"update": {},
"delete": {},
},
"agent_personas": {
"create": {},
"update": {},
"delete": {},
},
"agent_parts": {
"create": {},
"update": {},
"delete": {},
},
"agent_traits": {
"create": {},
"update": {},
"delete": {},
},
"agent_skills": {
"create": {},
"update": {},
@@ -133,40 +147,3 @@ type resolveSpecModel struct {
entity string
model any
}
func resolveSpecModels() []resolveSpecModel {
//This must be generated with relspec to include all models
//Use the relspec command with template generation. It supprot templ.
return []resolveSpecModel{
// {schema: "public", entity: "activities", model: generatedmodels.ModelPublicActivities{}},
{schema: "public", entity: "agent_guardrails", model: generatedmodels.ModelPublicAgentGuardrails{}},
{schema: "public", entity: "agent_skills", model: generatedmodels.ModelPublicAgentSkills{}},
{schema: "public", entity: "chat_histories", model: generatedmodels.ModelPublicChatHistories{}},
// {schema: "public", entity: "contact_interactions", model: generatedmodels.ModelPublicContactInteractions{}},
{schema: "public", entity: "embeddings", model: generatedmodels.ModelPublicEmbeddings{}},
// {schema: "public", entity: "family_members", model: generatedmodels.ModelPublicFamilyMembers{}},
// {schema: "public", entity: "household_items", model: generatedmodels.ModelPublicHouseholdItems{}},
// {schema: "public", entity: "household_vendors", model: generatedmodels.ModelPublicHouseholdVendors{}},
// {schema: "public", entity: "important_dates", model: generatedmodels.ModelPublicImportantDates{}},
{schema: "public", entity: "learnings", model: generatedmodels.ModelPublicLearnings{}},
// {schema: "public", entity: "maintenance_logs", model: generatedmodels.ModelPublicMaintenanceLogs{}},
// {schema: "public", entity: "maintenance_tasks", model: generatedmodels.ModelPublicMaintenanceTasks{}},
// {schema: "public", entity: "meal_plans", model: generatedmodels.ModelPublicMealPlans{}},
// {schema: "public", entity: "opportunities", model: generatedmodels.ModelPublicOpportunities{}},
{schema: "public", entity: "plan_dependencies", model: generatedmodels.ModelPublicPlanDependencies{}},
{schema: "public", entity: "plan_guardrails", model: generatedmodels.ModelPublicPlanGuardrails{}},
{schema: "public", entity: "plan_related_plans", model: generatedmodels.ModelPublicPlanRelatedPlans{}},
{schema: "public", entity: "plan_skills", model: generatedmodels.ModelPublicPlanSkills{}},
{schema: "public", entity: "plans", model: generatedmodels.ModelPublicPlans{}},
// {schema: "public", entity: "professional_contacts", model: generatedmodels.ModelPublicProfessionalContacts{}},
{schema: "public", entity: "project_guardrails", model: generatedmodels.ModelPublicProjectGuardrails{}},
{schema: "public", entity: "project_skills", model: generatedmodels.ModelPublicProjectSkills{}},
{schema: "public", entity: "projects", model: generatedmodels.ModelPublicProjects{}},
// {schema: "public", entity: "recipes", model: generatedmodels.ModelPublicRecipes{}},
// {schema: "public", entity: "shopping_lists", model: generatedmodels.ModelPublicShoppingLists{}},
{schema: "public", entity: "stored_files", model: generatedmodels.ModelPublicStoredFiles{}},
{schema: "public", entity: "thought_links", model: generatedmodels.ModelPublicThoughtLinks{}},
{schema: "public", entity: "thoughts", model: generatedmodels.ModelPublicThoughts{}},
{schema: "public", entity: "tool_annotations", model: generatedmodels.ModelPublicToolAnnotations{}},
}
}

View File

@@ -80,6 +80,15 @@ func TestResolveSpecGuardAllowsSupportedMutations(t *testing.T) {
{name: "agent_guardrails create", entity: "agent_guardrails", operation: "create"},
{name: "agent_guardrails update", entity: "agent_guardrails", operation: "update"},
{name: "agent_guardrails delete", entity: "agent_guardrails", operation: "delete"},
{name: "agent_personas create", entity: "agent_personas", operation: "create"},
{name: "agent_personas update", entity: "agent_personas", operation: "update"},
{name: "agent_personas delete", entity: "agent_personas", operation: "delete"},
{name: "agent_parts create", entity: "agent_parts", operation: "create"},
{name: "agent_parts update", entity: "agent_parts", operation: "update"},
{name: "agent_parts delete", entity: "agent_parts", operation: "delete"},
{name: "agent_traits create", entity: "agent_traits", operation: "create"},
{name: "agent_traits update", entity: "agent_traits", operation: "update"},
{name: "agent_traits delete", entity: "agent_traits", operation: "delete"},
{name: "stored_files update", entity: "stored_files", operation: "update"},
{name: "stored_files delete", entity: "stored_files", operation: "delete"},
}
@@ -171,3 +180,27 @@ func TestResolveSpecModelsIncludeLearnings(t *testing.T) {
}
t.Fatal("resolveSpecModels() missing public.learnings")
}
func TestResolveSpecModelsIncludePersonaEntities(t *testing.T) {
models := resolveSpecModels()
required := map[string]bool{
"agent_personas": false,
"agent_parts": false,
"agent_traits": false,
}
for _, model := range models {
if model.schema != "public" {
continue
}
if _, ok := required[model.entity]; ok {
required[model.entity] = true
}
}
for entity, found := range required {
if !found {
t.Fatalf("resolveSpecModels() missing public.%s", entity)
}
}
}

View File

@@ -0,0 +1,37 @@
// Code generated by relspec templ. DO NOT EDIT.
package app
import "git.warky.dev/wdevs/amcs/internal/generatedmodels"
func resolveSpecModels() []resolveSpecModel {
return []resolveSpecModel{
{schema: "public", entity: "agent_guardrails", model: generatedmodels.ModelPublicAgentGuardrails{}},
{schema: "public", entity: "agent_parts", model: generatedmodels.ModelPublicAgentParts{}},
{schema: "public", entity: "agent_persona_guardrails", model: generatedmodels.ModelPublicAgentPersonaGuardrails{}},
{schema: "public", entity: "agent_persona_parts", model: generatedmodels.ModelPublicAgentPersonaParts{}},
{schema: "public", entity: "agent_persona_skills", model: generatedmodels.ModelPublicAgentPersonaSkills{}},
{schema: "public", entity: "agent_persona_traits", model: generatedmodels.ModelPublicAgentPersonaTraits{}},
{schema: "public", entity: "agent_personas", model: generatedmodels.ModelPublicAgentPersonas{}},
{schema: "public", entity: "agent_skills", model: generatedmodels.ModelPublicAgentSkills{}},
{schema: "public", entity: "agent_traits", model: generatedmodels.ModelPublicAgentTraits{}},
{schema: "public", entity: "arc_stage_parts", model: generatedmodels.ModelPublicArcStageParts{}},
{schema: "public", entity: "arc_stages", model: generatedmodels.ModelPublicArcStages{}},
{schema: "public", entity: "character_arcs", model: generatedmodels.ModelPublicCharacterArcs{}},
{schema: "public", entity: "chat_histories", model: generatedmodels.ModelPublicChatHistories{}},
{schema: "public", entity: "embeddings", model: generatedmodels.ModelPublicEmbeddings{}},
{schema: "public", entity: "learnings", model: generatedmodels.ModelPublicLearnings{}},
{schema: "public", entity: "persona_arc", model: generatedmodels.ModelPublicPersonaArc{}},
{schema: "public", entity: "plan_dependencies", model: generatedmodels.ModelPublicPlanDependencies{}},
{schema: "public", entity: "plan_guardrails", model: generatedmodels.ModelPublicPlanGuardrails{}},
{schema: "public", entity: "plan_related_plans", model: generatedmodels.ModelPublicPlanRelatedPlans{}},
{schema: "public", entity: "plan_skills", model: generatedmodels.ModelPublicPlanSkills{}},
{schema: "public", entity: "plans", model: generatedmodels.ModelPublicPlans{}},
{schema: "public", entity: "project_guardrails", model: generatedmodels.ModelPublicProjectGuardrails{}},
{schema: "public", entity: "project_skills", model: generatedmodels.ModelPublicProjectSkills{}},
{schema: "public", entity: "projects", model: generatedmodels.ModelPublicProjects{}},
{schema: "public", entity: "stored_files", model: generatedmodels.ModelPublicStoredFiles{}},
{schema: "public", entity: "thought_links", model: generatedmodels.ModelPublicThoughtLinks{}},
{schema: "public", entity: "thoughts", model: generatedmodels.ModelPublicThoughts{}},
{schema: "public", entity: "tool_annotations", model: generatedmodels.ModelPublicToolAnnotations{}},
}
}

2
internal/app/ui/dist/placeholder.txt vendored Normal file
View File

@@ -0,0 +1,2 @@
This placeholder keeps internal/app/ui/dist present in clean source checkouts.
The real UI bundle is generated by the frontend build into this directory.

View File

@@ -1,69 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicAgentGuardrails struct {
bun.BaseModel `bun:"table:public.agent_guardrails,alias:agent_guardrails"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
Content resolvespec_common.SqlString `bun:"content,type:text,notnull," json:"content"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Description resolvespec_common.SqlString `bun:"description,type:text,default:'',notnull," json:"description"`
GUID resolvespec_common.SqlUUID `bun:"guid,type:uuid,default:gen_random_uuid(),notnull," json:"guid"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
Severity resolvespec_common.SqlString `bun:"severity,type:text,default:'medium',notnull," json:"severity"`
Tags resolvespec_common.SqlStringArray `bun:"tags,type:text[],default:'{}',notnull," json:"tags"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelGuardrailIDPublicAgentPersonaGuardrails []*ModelPublicAgentPersonaGuardrails `bun:"rel:has-many,join:id=guardrail_id" json:"relguardrailidpublicagentpersonaguardrails,omitempty"` // Has many ModelPublicAgentPersonaGuardrails
RelGuardrailIDPublicPlanGuardrails []*ModelPublicPlanGuardrails `bun:"rel:has-many,join:id=guardrail_id" json:"relguardrailidpublicplanguardrails,omitempty"` // Has many ModelPublicPlanGuardrails
RelGuardrailIDPublicProjectGuardrails []*ModelPublicProjectGuardrails `bun:"rel:has-many,join:id=guardrail_id" json:"relguardrailidpublicprojectguardrails,omitempty"` // Has many ModelPublicProjectGuardrails
}
// TableName returns the table name for ModelPublicAgentGuardrails
func (m ModelPublicAgentGuardrails) TableName() string {
return "public.agent_guardrails"
}
// TableNameOnly returns the table name without schema for ModelPublicAgentGuardrails
func (m ModelPublicAgentGuardrails) TableNameOnly() string {
return "agent_guardrails"
}
// SchemaName returns the schema name for ModelPublicAgentGuardrails
func (m ModelPublicAgentGuardrails) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicAgentGuardrails) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicAgentGuardrails) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicAgentGuardrails) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicAgentGuardrails) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicAgentGuardrails) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicAgentGuardrails) GetPrefix() string {
return "AGG"
}

View File

@@ -1,69 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicAgentParts struct {
bun.BaseModel `bun:"table:public.agent_parts,alias:agent_parts"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
Content resolvespec_common.SqlString `bun:"content,type:text,default:'',notnull," json:"content"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Description resolvespec_common.SqlString `bun:"description,type:text,default:'',notnull," json:"description"`
GUID resolvespec_common.SqlUUID `bun:"guid,type:uuid,default:gen_random_uuid(),notnull," json:"guid"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
PartType resolvespec_common.SqlString `bun:"part_type,type:text,notnull," json:"part_type"`
Summary resolvespec_common.SqlString `bun:"summary,type:text,notnull," json:"summary"`
Tags resolvespec_common.SqlStringArray `bun:"tags,type:text[],default:'{}',notnull," json:"tags"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelPartIDPublicAgentPersonaParts []*ModelPublicAgentPersonaParts `bun:"rel:has-many,join:id=part_id" json:"relpartidpublicagentpersonaparts,omitempty"` // Has many ModelPublicAgentPersonaParts
RelPartIDPublicArcStageParts []*ModelPublicArcStageParts `bun:"rel:has-many,join:id=part_id" json:"relpartidpublicarcstageparts,omitempty"` // Has many ModelPublicArcStageParts
}
// TableName returns the table name for ModelPublicAgentParts
func (m ModelPublicAgentParts) TableName() string {
return "public.agent_parts"
}
// TableNameOnly returns the table name without schema for ModelPublicAgentParts
func (m ModelPublicAgentParts) TableNameOnly() string {
return "agent_parts"
}
// SchemaName returns the schema name for ModelPublicAgentParts
func (m ModelPublicAgentParts) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicAgentParts) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicAgentParts) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicAgentParts) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicAgentParts) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicAgentParts) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicAgentParts) GetPrefix() string {
return "APG"
}

View File

@@ -1,34 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"github.com/uptrace/bun"
)
type ModelPublicAgentPersonaGuardrails struct {
bun.BaseModel `bun:"table:public.agent_persona_guardrails,alias:agent_persona_guardrails"`
GuardrailID int64 `bun:"guardrail_id,type:bigint,notnull," json:"guardrail_id"`
PersonaID int64 `bun:"persona_id,type:bigint,notnull," json:"persona_id"`
RelGuardrailID *ModelPublicAgentGuardrails `bun:"rel:has-one,join:guardrail_id=id" json:"relguardrailid,omitempty"` // Has one ModelPublicAgentGuardrails
RelPersonaID *ModelPublicAgentPersonas `bun:"rel:has-one,join:persona_id=id" json:"relpersonaid,omitempty"` // Has one ModelPublicAgentPersonas
}
// TableName returns the table name for ModelPublicAgentPersonaGuardrails
func (m ModelPublicAgentPersonaGuardrails) TableName() string {
return "public.agent_persona_guardrails"
}
// TableNameOnly returns the table name without schema for ModelPublicAgentPersonaGuardrails
func (m ModelPublicAgentPersonaGuardrails) TableNameOnly() string {
return "agent_persona_guardrails"
}
// SchemaName returns the schema name for ModelPublicAgentPersonaGuardrails
func (m ModelPublicAgentPersonaGuardrails) SchemaName() string {
return "public"
}
// GetPrefix returns the table prefix
func (m ModelPublicAgentPersonaGuardrails) GetPrefix() string {
return "APG"
}

View File

@@ -1,36 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"github.com/uptrace/bun"
)
type ModelPublicAgentPersonaParts struct {
bun.BaseModel `bun:"table:public.agent_persona_parts,alias:agent_persona_parts"`
PartID int64 `bun:"part_id,type:bigint,notnull," json:"part_id"`
PartOrder int32 `bun:"part_order,type:int,default:0,notnull," json:"part_order"`
PersonaID int64 `bun:"persona_id,type:bigint,notnull," json:"persona_id"`
Priority int32 `bun:"priority,type:int,default:0,notnull," json:"priority"`
RelPartID *ModelPublicAgentParts `bun:"rel:has-one,join:part_id=id" json:"relpartid,omitempty"` // Has one ModelPublicAgentParts
RelPersonaID *ModelPublicAgentPersonas `bun:"rel:has-one,join:persona_id=id" json:"relpersonaid,omitempty"` // Has one ModelPublicAgentPersonas
}
// TableName returns the table name for ModelPublicAgentPersonaParts
func (m ModelPublicAgentPersonaParts) TableName() string {
return "public.agent_persona_parts"
}
// TableNameOnly returns the table name without schema for ModelPublicAgentPersonaParts
func (m ModelPublicAgentPersonaParts) TableNameOnly() string {
return "agent_persona_parts"
}
// SchemaName returns the schema name for ModelPublicAgentPersonaParts
func (m ModelPublicAgentPersonaParts) SchemaName() string {
return "public"
}
// GetPrefix returns the table prefix
func (m ModelPublicAgentPersonaParts) GetPrefix() string {
return "APP"
}

View File

@@ -1,34 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"github.com/uptrace/bun"
)
type ModelPublicAgentPersonaSkills struct {
bun.BaseModel `bun:"table:public.agent_persona_skills,alias:agent_persona_skills"`
PersonaID int64 `bun:"persona_id,type:bigint,notnull," json:"persona_id"`
SkillID int64 `bun:"skill_id,type:bigint,notnull," json:"skill_id"`
RelPersonaID *ModelPublicAgentPersonas `bun:"rel:has-one,join:persona_id=id" json:"relpersonaid,omitempty"` // Has one ModelPublicAgentPersonas
RelSkillID *ModelPublicAgentSkills `bun:"rel:has-one,join:skill_id=id" json:"relskillid,omitempty"` // Has one ModelPublicAgentSkills
}
// TableName returns the table name for ModelPublicAgentPersonaSkills
func (m ModelPublicAgentPersonaSkills) TableName() string {
return "public.agent_persona_skills"
}
// TableNameOnly returns the table name without schema for ModelPublicAgentPersonaSkills
func (m ModelPublicAgentPersonaSkills) TableNameOnly() string {
return "agent_persona_skills"
}
// SchemaName returns the schema name for ModelPublicAgentPersonaSkills
func (m ModelPublicAgentPersonaSkills) SchemaName() string {
return "public"
}
// GetPrefix returns the table prefix
func (m ModelPublicAgentPersonaSkills) GetPrefix() string {
return "APS"
}

View File

@@ -1,34 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"github.com/uptrace/bun"
)
type ModelPublicAgentPersonaTraits struct {
bun.BaseModel `bun:"table:public.agent_persona_traits,alias:agent_persona_traits"`
PersonaID int64 `bun:"persona_id,type:bigint,notnull," json:"persona_id"`
TraitID int64 `bun:"trait_id,type:bigint,notnull," json:"trait_id"`
RelPersonaID *ModelPublicAgentPersonas `bun:"rel:has-one,join:persona_id=id" json:"relpersonaid,omitempty"` // Has one ModelPublicAgentPersonas
RelTraitID *ModelPublicAgentTraits `bun:"rel:has-one,join:trait_id=id" json:"reltraitid,omitempty"` // Has one ModelPublicAgentTraits
}
// TableName returns the table name for ModelPublicAgentPersonaTraits
func (m ModelPublicAgentPersonaTraits) TableName() string {
return "public.agent_persona_traits"
}
// TableNameOnly returns the table name without schema for ModelPublicAgentPersonaTraits
func (m ModelPublicAgentPersonaTraits) TableNameOnly() string {
return "agent_persona_traits"
}
// SchemaName returns the schema name for ModelPublicAgentPersonaTraits
func (m ModelPublicAgentPersonaTraits) SchemaName() string {
return "public"
}
// GetPrefix returns the table prefix
func (m ModelPublicAgentPersonaTraits) GetPrefix() string {
return "APT"
}

View File

@@ -1,74 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicAgentPersonas struct {
bun.BaseModel `bun:"table:public.agent_personas,alias:agent_personas"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CompiledAt resolvespec_common.SqlTimeStamp `bun:"compiled_at,type:timestamptz,nullzero," json:"compiled_at"`
CompiledDetail resolvespec_common.SqlString `bun:"compiled_detail,type:text,default:'',notnull," json:"compiled_detail"`
CompiledSummary resolvespec_common.SqlString `bun:"compiled_summary,type:text,default:'',notnull," json:"compiled_summary"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Description resolvespec_common.SqlString `bun:"description,type:text,default:'',notnull," json:"description"`
Detail resolvespec_common.SqlString `bun:"detail,type:text,default:'',notnull," json:"detail"`
GUID resolvespec_common.SqlUUID `bun:"guid,type:uuid,default:gen_random_uuid(),notnull," json:"guid"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
Summary resolvespec_common.SqlString `bun:"summary,type:text,notnull," json:"summary"`
Tags resolvespec_common.SqlStringArray `bun:"tags,type:text[],default:'{}',notnull," json:"tags"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelPersonaIDPublicAgentPersonaParts []*ModelPublicAgentPersonaParts `bun:"rel:has-many,join:id=persona_id" json:"relpersonaidpublicagentpersonaparts,omitempty"` // Has many ModelPublicAgentPersonaParts
RelPersonaIDPublicAgentPersonaSkills []*ModelPublicAgentPersonaSkills `bun:"rel:has-many,join:id=persona_id" json:"relpersonaidpublicagentpersonaskills,omitempty"` // Has many ModelPublicAgentPersonaSkills
RelPersonaIDPublicAgentPersonaGuardrails []*ModelPublicAgentPersonaGuardrails `bun:"rel:has-many,join:id=persona_id" json:"relpersonaidpublicagentpersonaguardrails,omitempty"` // Has many ModelPublicAgentPersonaGuardrails
RelPersonaIDPublicAgentPersonaTraits []*ModelPublicAgentPersonaTraits `bun:"rel:has-many,join:id=persona_id" json:"relpersonaidpublicagentpersonatraits,omitempty"` // Has many ModelPublicAgentPersonaTraits
RelPersonaIDPublicPersonaArcs []*ModelPublicPersonaArc `bun:"rel:has-many,join:id=persona_id" json:"relpersonaidpublicpersonaarcs,omitempty"` // Has many ModelPublicPersonaArc
}
// TableName returns the table name for ModelPublicAgentPersonas
func (m ModelPublicAgentPersonas) TableName() string {
return "public.agent_personas"
}
// TableNameOnly returns the table name without schema for ModelPublicAgentPersonas
func (m ModelPublicAgentPersonas) TableNameOnly() string {
return "agent_personas"
}
// SchemaName returns the schema name for ModelPublicAgentPersonas
func (m ModelPublicAgentPersonas) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicAgentPersonas) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicAgentPersonas) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicAgentPersonas) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicAgentPersonas) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicAgentPersonas) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicAgentPersonas) GetPrefix() string {
return "APG"
}

View File

@@ -1,73 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicAgentSkills struct {
bun.BaseModel `bun:"table:public.agent_skills,alias:agent_skills"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
Content resolvespec_common.SqlString `bun:"content,type:text,notnull," json:"content"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Description resolvespec_common.SqlString `bun:"description,type:text,default:'',notnull," json:"description"`
DomainTags resolvespec_common.SqlStringArray `bun:"domain_tags,type:text[],default:'{}',notnull," json:"domain_tags"`
FrameworkTags resolvespec_common.SqlStringArray `bun:"framework_tags,type:text[],default:'{}',notnull," json:"framework_tags"`
GUID resolvespec_common.SqlUUID `bun:"guid,type:uuid,default:gen_random_uuid(),notnull," json:"guid"`
LanguageTags resolvespec_common.SqlStringArray `bun:"language_tags,type:text[],default:'{}',notnull," json:"language_tags"`
LibraryTags resolvespec_common.SqlStringArray `bun:"library_tags,type:text[],default:'{}',notnull," json:"library_tags"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
Tags resolvespec_common.SqlStringArray `bun:"tags,type:text[],default:'{}',notnull," json:"tags"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelSkillIDPublicAgentPersonaSkills []*ModelPublicAgentPersonaSkills `bun:"rel:has-many,join:id=skill_id" json:"relskillidpublicagentpersonaskills,omitempty"` // Has many ModelPublicAgentPersonaSkills
RelRelatedSkillIDPublicLearnings []*ModelPublicLearnings `bun:"rel:has-many,join:id=related_skill_id" json:"relrelatedskillidpubliclearnings,omitempty"` // Has many ModelPublicLearnings
RelSkillIDPublicPlanSkills []*ModelPublicPlanSkills `bun:"rel:has-many,join:id=skill_id" json:"relskillidpublicplanskills,omitempty"` // Has many ModelPublicPlanSkills
RelSkillIDPublicProjectSkills []*ModelPublicProjectSkills `bun:"rel:has-many,join:id=skill_id" json:"relskillidpublicprojectskills,omitempty"` // Has many ModelPublicProjectSkills
}
// TableName returns the table name for ModelPublicAgentSkills
func (m ModelPublicAgentSkills) TableName() string {
return "public.agent_skills"
}
// TableNameOnly returns the table name without schema for ModelPublicAgentSkills
func (m ModelPublicAgentSkills) TableNameOnly() string {
return "agent_skills"
}
// SchemaName returns the schema name for ModelPublicAgentSkills
func (m ModelPublicAgentSkills) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicAgentSkills) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicAgentSkills) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicAgentSkills) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicAgentSkills) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicAgentSkills) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicAgentSkills) GetPrefix() string {
return "ASG"
}

View File

@@ -1,67 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicAgentTraits struct {
bun.BaseModel `bun:"table:public.agent_traits,alias:agent_traits"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Description resolvespec_common.SqlString `bun:"description,type:text,default:'',notnull," json:"description"`
GUID resolvespec_common.SqlUUID `bun:"guid,type:uuid,default:gen_random_uuid(),notnull," json:"guid"`
Instruction resolvespec_common.SqlString `bun:"instruction,type:text,default:'',notnull," json:"instruction"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
Tags resolvespec_common.SqlStringArray `bun:"tags,type:text[],default:'{}',notnull," json:"tags"`
TraitType resolvespec_common.SqlString `bun:"trait_type,type:text,notnull," json:"trait_type"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelTraitIDPublicAgentPersonaTraits []*ModelPublicAgentPersonaTraits `bun:"rel:has-many,join:id=trait_id" json:"reltraitidpublicagentpersonatraits,omitempty"` // Has many ModelPublicAgentPersonaTraits
}
// TableName returns the table name for ModelPublicAgentTraits
func (m ModelPublicAgentTraits) TableName() string {
return "public.agent_traits"
}
// TableNameOnly returns the table name without schema for ModelPublicAgentTraits
func (m ModelPublicAgentTraits) TableNameOnly() string {
return "agent_traits"
}
// SchemaName returns the schema name for ModelPublicAgentTraits
func (m ModelPublicAgentTraits) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicAgentTraits) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicAgentTraits) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicAgentTraits) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicAgentTraits) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicAgentTraits) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicAgentTraits) GetPrefix() string {
return "ATG"
}

View File

@@ -1,34 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"github.com/uptrace/bun"
)
type ModelPublicArcStageParts struct {
bun.BaseModel `bun:"table:public.arc_stage_parts,alias:arc_stage_parts"`
PartID int64 `bun:"part_id,type:bigint,notnull," json:"part_id"`
StageID int64 `bun:"stage_id,type:bigint,notnull," json:"stage_id"`
RelPartID *ModelPublicAgentParts `bun:"rel:has-one,join:part_id=id" json:"relpartid,omitempty"` // Has one ModelPublicAgentParts
RelStageID *ModelPublicArcStages `bun:"rel:has-one,join:stage_id=id" json:"relstageid,omitempty"` // Has one ModelPublicArcStages
}
// TableName returns the table name for ModelPublicArcStageParts
func (m ModelPublicArcStageParts) TableName() string {
return "public.arc_stage_parts"
}
// TableNameOnly returns the table name without schema for ModelPublicArcStageParts
func (m ModelPublicArcStageParts) TableNameOnly() string {
return "arc_stage_parts"
}
// SchemaName returns the schema name for ModelPublicArcStageParts
func (m ModelPublicArcStageParts) SchemaName() string {
return "public"
}
// GetPrefix returns the table prefix
func (m ModelPublicArcStageParts) GetPrefix() string {
return "ASP"
}

View File

@@ -1,67 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicArcStages struct {
bun.BaseModel `bun:"table:public.arc_stages,alias:arc_stages"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
ArcID int64 `bun:"arc_id,type:bigint,notnull," json:"arc_id"`
Condition resolvespec_common.SqlString `bun:"condition,type:text,default:'',notnull," json:"condition"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Description resolvespec_common.SqlString `bun:"description,type:text,default:'',notnull," json:"description"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
StageOrder int32 `bun:"stage_order,type:int,default:0,notnull," json:"stage_order"`
RelArcID *ModelPublicCharacterArcs `bun:"rel:has-one,join:arc_id=id" json:"relarcid,omitempty"` // Has one ModelPublicCharacterArcs
RelStageIDPublicArcStageParts []*ModelPublicArcStageParts `bun:"rel:has-many,join:id=stage_id" json:"relstageidpublicarcstageparts,omitempty"` // Has many ModelPublicArcStageParts
RelCurrentStageIDPublicPersonaArcs []*ModelPublicPersonaArc `bun:"rel:has-many,join:id=current_stage_id" json:"relcurrentstageidpublicpersonaarcs,omitempty"` // Has many ModelPublicPersonaArc
}
// TableName returns the table name for ModelPublicArcStages
func (m ModelPublicArcStages) TableName() string {
return "public.arc_stages"
}
// TableNameOnly returns the table name without schema for ModelPublicArcStages
func (m ModelPublicArcStages) TableNameOnly() string {
return "arc_stages"
}
// SchemaName returns the schema name for ModelPublicArcStages
func (m ModelPublicArcStages) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicArcStages) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicArcStages) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicArcStages) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicArcStages) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicArcStages) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicArcStages) GetPrefix() string {
return "ASR"
}

View File

@@ -1,65 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicCharacterArcs struct {
bun.BaseModel `bun:"table:public.character_arcs,alias:character_arcs"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Description resolvespec_common.SqlString `bun:"description,type:text,default:'',notnull," json:"description"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
Summary resolvespec_common.SqlString `bun:"summary,type:text,default:'',notnull," json:"summary"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelArcIDPublicArcStages []*ModelPublicArcStages `bun:"rel:has-many,join:id=arc_id" json:"relarcidpublicarcstages,omitempty"` // Has many ModelPublicArcStages
RelArcIDPublicPersonaArcs []*ModelPublicPersonaArc `bun:"rel:has-many,join:id=arc_id" json:"relarcidpublicpersonaarcs,omitempty"` // Has many ModelPublicPersonaArc
}
// TableName returns the table name for ModelPublicCharacterArcs
func (m ModelPublicCharacterArcs) TableName() string {
return "public.character_arcs"
}
// TableNameOnly returns the table name without schema for ModelPublicCharacterArcs
func (m ModelPublicCharacterArcs) TableNameOnly() string {
return "character_arcs"
}
// SchemaName returns the schema name for ModelPublicCharacterArcs
func (m ModelPublicCharacterArcs) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicCharacterArcs) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicCharacterArcs) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicCharacterArcs) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicCharacterArcs) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicCharacterArcs) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicCharacterArcs) GetPrefix() string {
return "CAH"
}

View File

@@ -1,70 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicChatHistories struct {
bun.BaseModel `bun:"table:public.chat_histories,alias:chat_histories"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
AgentID resolvespec_common.SqlString `bun:"agent_id,type:text,nullzero," json:"agent_id"`
Channel resolvespec_common.SqlString `bun:"channel,type:text,nullzero," json:"channel"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
GUID resolvespec_common.SqlUUID `bun:"guid,type:uuid,default:gen_random_uuid(),notnull," json:"guid"`
Messages resolvespec_common.SqlJSONB `bun:"messages,type:jsonb,default:'[]',notnull," json:"messages"`
Metadata resolvespec_common.SqlJSONB `bun:"metadata,type:jsonb,default:'{}',notnull," json:"metadata"`
ProjectID resolvespec_common.SqlInt64 `bun:"project_id,type:bigint,nullzero," json:"project_id"`
SessionID resolvespec_common.SqlString `bun:"session_id,type:text,notnull," json:"session_id"`
Summary resolvespec_common.SqlString `bun:"summary,type:text,nullzero," json:"summary"`
Title resolvespec_common.SqlString `bun:"title,type:text,nullzero," json:"title"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelProjectID *ModelPublicProjects `bun:"rel:has-one,join:project_id=id" json:"relprojectid,omitempty"` // Has one ModelPublicProjects
}
// TableName returns the table name for ModelPublicChatHistories
func (m ModelPublicChatHistories) TableName() string {
return "public.chat_histories"
}
// TableNameOnly returns the table name without schema for ModelPublicChatHistories
func (m ModelPublicChatHistories) TableNameOnly() string {
return "chat_histories"
}
// SchemaName returns the schema name for ModelPublicChatHistories
func (m ModelPublicChatHistories) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicChatHistories) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicChatHistories) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicChatHistories) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicChatHistories) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicChatHistories) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicChatHistories) GetPrefix() string {
return "CHH"
}

View File

@@ -1,66 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicEmbeddings struct {
bun.BaseModel `bun:"table:public.embeddings,alias:embeddings"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),nullzero," json:"created_at"`
Dim int32 `bun:"dim,type:int,notnull," json:"dim"`
Embedding resolvespec_common.SqlVector `bun:"embedding,type:vector,notnull," json:"embedding"`
GUID resolvespec_common.SqlUUID `bun:"guid,type:uuid,default:gen_random_uuid(),notnull," json:"guid"`
Model resolvespec_common.SqlString `bun:"model,type:text,notnull,unique:uidx_embeddings_thought_id_model," json:"model"`
ThoughtID int64 `bun:"thought_id,type:bigint,notnull,unique:uidx_embeddings_thought_id_model," json:"thought_id"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),nullzero," json:"updated_at"`
RelThoughtID *ModelPublicThoughts `bun:"rel:has-one,join:thought_id=id" json:"relthoughtid,omitempty"` // Has one ModelPublicThoughts
}
// TableName returns the table name for ModelPublicEmbeddings
func (m ModelPublicEmbeddings) TableName() string {
return "public.embeddings"
}
// TableNameOnly returns the table name without schema for ModelPublicEmbeddings
func (m ModelPublicEmbeddings) TableNameOnly() string {
return "embeddings"
}
// SchemaName returns the schema name for ModelPublicEmbeddings
func (m ModelPublicEmbeddings) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicEmbeddings) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicEmbeddings) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicEmbeddings) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicEmbeddings) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicEmbeddings) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicEmbeddings) GetPrefix() string {
return "EMB"
}

View File

@@ -1,84 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicLearnings struct {
bun.BaseModel `bun:"table:public.learnings,alias:learnings"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
ActionRequired bool `bun:"action_required,type:boolean,default:false,notnull," json:"action_required"`
Area resolvespec_common.SqlString `bun:"area,type:text,default:'other',notnull," json:"area"`
Category resolvespec_common.SqlString `bun:"category,type:text,default:'insight',notnull," json:"category"`
Confidence resolvespec_common.SqlString `bun:"confidence,type:text,default:'hypothesis',notnull," json:"confidence"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Details resolvespec_common.SqlString `bun:"details,type:text,default:'',notnull," json:"details"`
DuplicateOfLearningID resolvespec_common.SqlInt64 `bun:"duplicate_of_learning_id,type:bigint,nullzero," json:"duplicate_of_learning_id"`
GUID resolvespec_common.SqlUUID `bun:"guid,type:uuid,default:gen_random_uuid(),notnull," json:"guid"`
Priority resolvespec_common.SqlString `bun:"priority,type:text,default:'medium',notnull," json:"priority"`
ProjectID resolvespec_common.SqlInt64 `bun:"project_id,type:bigint,nullzero," json:"project_id"`
RelatedSkillID resolvespec_common.SqlInt64 `bun:"related_skill_id,type:bigint,nullzero," json:"related_skill_id"`
RelatedThoughtID resolvespec_common.SqlInt64 `bun:"related_thought_id,type:bigint,nullzero," json:"related_thought_id"`
ReviewedAt resolvespec_common.SqlTimeStamp `bun:"reviewed_at,type:timestamptz,nullzero," json:"reviewed_at"`
ReviewedBy resolvespec_common.SqlString `bun:"reviewed_by,type:text,nullzero," json:"reviewed_by"`
SourceRef resolvespec_common.SqlString `bun:"source_ref,type:text,nullzero," json:"source_ref"`
SourceType resolvespec_common.SqlString `bun:"source_type,type:text,nullzero," json:"source_type"`
Status resolvespec_common.SqlString `bun:"status,type:text,default:'pending',notnull," json:"status"`
Summary resolvespec_common.SqlString `bun:"summary,type:text,notnull," json:"summary"`
SupersedesLearningID resolvespec_common.SqlInt64 `bun:"supersedes_learning_id,type:bigint,nullzero," json:"supersedes_learning_id"`
Tags resolvespec_common.SqlStringArray `bun:"tags,type:text[],default:'{}',notnull," json:"tags"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelDuplicateOfLearningID *ModelPublicLearnings `bun:"rel:has-one,join:duplicate_of_learning_id=id" json:"relduplicateoflearningid,omitempty"` // Has one ModelPublicLearnings
RelProjectID *ModelPublicProjects `bun:"rel:has-one,join:project_id=id" json:"relprojectid,omitempty"` // Has one ModelPublicProjects
RelRelatedSkillID *ModelPublicAgentSkills `bun:"rel:has-one,join:related_skill_id=id" json:"relrelatedskillid,omitempty"` // Has one ModelPublicAgentSkills
RelRelatedThoughtID *ModelPublicThoughts `bun:"rel:has-one,join:related_thought_id=id" json:"relrelatedthoughtid,omitempty"` // Has one ModelPublicThoughts
RelSupersedesLearningID *ModelPublicLearnings `bun:"rel:has-one,join:supersedes_learning_id=id" json:"relsupersedeslearningid,omitempty"` // Has one ModelPublicLearnings
}
// TableName returns the table name for ModelPublicLearnings
func (m ModelPublicLearnings) TableName() string {
return "public.learnings"
}
// TableNameOnly returns the table name without schema for ModelPublicLearnings
func (m ModelPublicLearnings) TableNameOnly() string {
return "learnings"
}
// SchemaName returns the schema name for ModelPublicLearnings
func (m ModelPublicLearnings) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicLearnings) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicLearnings) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicLearnings) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicLearnings) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicLearnings) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicLearnings) GetPrefix() string {
return "LEA"
}

View File

@@ -1,64 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicPersonaArc struct {
bun.BaseModel `bun:"table:public.persona_arc,alias:persona_arc"`
PersonaID int64 `bun:"persona_id,type:bigint,pk," json:"persona_id"`
ArcID int64 `bun:"arc_id,type:bigint,notnull," json:"arc_id"`
CurrentStageID int64 `bun:"current_stage_id,type:bigint,notnull," json:"current_stage_id"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelArcID *ModelPublicCharacterArcs `bun:"rel:has-one,join:arc_id=id" json:"relarcid,omitempty"` // Has one ModelPublicCharacterArcs
RelCurrentStageID *ModelPublicArcStages `bun:"rel:has-one,join:current_stage_id=id" json:"relcurrentstageid,omitempty"` // Has one ModelPublicArcStages
RelPersonaID *ModelPublicAgentPersonas `bun:"rel:has-one,join:persona_id=id" json:"relpersonaid,omitempty"` // Has one ModelPublicAgentPersonas
}
// TableName returns the table name for ModelPublicPersonaArc
func (m ModelPublicPersonaArc) TableName() string {
return "public.persona_arc"
}
// TableNameOnly returns the table name without schema for ModelPublicPersonaArc
func (m ModelPublicPersonaArc) TableNameOnly() string {
return "persona_arc"
}
// SchemaName returns the schema name for ModelPublicPersonaArc
func (m ModelPublicPersonaArc) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicPersonaArc) GetID() int64 {
return int64(m.PersonaID)
}
// GetIDStr returns the primary key as a string
func (m ModelPublicPersonaArc) GetIDStr() string {
return fmt.Sprintf("%d", m.PersonaID)
}
// SetID sets the primary key value
func (m ModelPublicPersonaArc) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicPersonaArc) UpdateID(newid int64) {
m.PersonaID = newid
}
// GetIDName returns the name of the primary key column
func (m ModelPublicPersonaArc) GetIDName() string {
return "persona_id"
}
// GetPrefix returns the table prefix
func (m ModelPublicPersonaArc) GetPrefix() string {
return "PAE"
}

View File

@@ -1,63 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicPlanDependencies struct {
bun.BaseModel `bun:"table:public.plan_dependencies,alias:plan_dependencies"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
DependsOnPlanID int64 `bun:"depends_on_plan_id,type:bigint,notnull,unique:uidx_plan_dependencies_plan_id_depends_on_plan_id," json:"depends_on_plan_id"`
PlanID int64 `bun:"plan_id,type:bigint,notnull,unique:uidx_plan_dependencies_plan_id_depends_on_plan_id," json:"plan_id"`
RelDependsOnPlanID *ModelPublicPlans `bun:"rel:has-one,join:depends_on_plan_id=id" json:"reldependsonplanid,omitempty"` // Has one ModelPublicPlans
RelPlanID *ModelPublicPlans `bun:"rel:has-one,join:plan_id=id" json:"relplanid,omitempty"` // Has one ModelPublicPlans
}
// TableName returns the table name for ModelPublicPlanDependencies
func (m ModelPublicPlanDependencies) TableName() string {
return "public.plan_dependencies"
}
// TableNameOnly returns the table name without schema for ModelPublicPlanDependencies
func (m ModelPublicPlanDependencies) TableNameOnly() string {
return "plan_dependencies"
}
// SchemaName returns the schema name for ModelPublicPlanDependencies
func (m ModelPublicPlanDependencies) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicPlanDependencies) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicPlanDependencies) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicPlanDependencies) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicPlanDependencies) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicPlanDependencies) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicPlanDependencies) GetPrefix() string {
return "PDL"
}

View File

@@ -1,63 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicPlanGuardrails struct {
bun.BaseModel `bun:"table:public.plan_guardrails,alias:plan_guardrails"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
GuardrailID int64 `bun:"guardrail_id,type:bigint,notnull,unique:uidx_plan_guardrails_plan_id_guardrail_id," json:"guardrail_id"`
PlanID int64 `bun:"plan_id,type:bigint,notnull,unique:uidx_plan_guardrails_plan_id_guardrail_id," json:"plan_id"`
RelGuardrailID *ModelPublicAgentGuardrails `bun:"rel:has-one,join:guardrail_id=id" json:"relguardrailid,omitempty"` // Has one ModelPublicAgentGuardrails
RelPlanID *ModelPublicPlans `bun:"rel:has-one,join:plan_id=id" json:"relplanid,omitempty"` // Has one ModelPublicPlans
}
// TableName returns the table name for ModelPublicPlanGuardrails
func (m ModelPublicPlanGuardrails) TableName() string {
return "public.plan_guardrails"
}
// TableNameOnly returns the table name without schema for ModelPublicPlanGuardrails
func (m ModelPublicPlanGuardrails) TableNameOnly() string {
return "plan_guardrails"
}
// SchemaName returns the schema name for ModelPublicPlanGuardrails
func (m ModelPublicPlanGuardrails) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicPlanGuardrails) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicPlanGuardrails) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicPlanGuardrails) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicPlanGuardrails) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicPlanGuardrails) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicPlanGuardrails) GetPrefix() string {
return "PGL"
}

View File

@@ -1,63 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicPlanRelatedPlans struct {
bun.BaseModel `bun:"table:public.plan_related_plans,alias:plan_related_plans"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
PlanAID int64 `bun:"plan_a_id,type:bigint,notnull,unique:uidx_plan_related_plans_plan_a_id_plan_b_id," json:"plan_a_id"`
PlanBID int64 `bun:"plan_b_id,type:bigint,notnull,unique:uidx_plan_related_plans_plan_a_id_plan_b_id," json:"plan_b_id"`
RelPlanAID *ModelPublicPlans `bun:"rel:has-one,join:plan_a_id=id" json:"relplanaid,omitempty"` // Has one ModelPublicPlans
RelPlanBID *ModelPublicPlans `bun:"rel:has-one,join:plan_b_id=id" json:"relplanbid,omitempty"` // Has one ModelPublicPlans
}
// TableName returns the table name for ModelPublicPlanRelatedPlans
func (m ModelPublicPlanRelatedPlans) TableName() string {
return "public.plan_related_plans"
}
// TableNameOnly returns the table name without schema for ModelPublicPlanRelatedPlans
func (m ModelPublicPlanRelatedPlans) TableNameOnly() string {
return "plan_related_plans"
}
// SchemaName returns the schema name for ModelPublicPlanRelatedPlans
func (m ModelPublicPlanRelatedPlans) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicPlanRelatedPlans) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicPlanRelatedPlans) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicPlanRelatedPlans) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicPlanRelatedPlans) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicPlanRelatedPlans) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicPlanRelatedPlans) GetPrefix() string {
return "PRP"
}

View File

@@ -1,63 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicPlanSkills struct {
bun.BaseModel `bun:"table:public.plan_skills,alias:plan_skills"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
PlanID int64 `bun:"plan_id,type:bigint,notnull,unique:uidx_plan_skills_plan_id_skill_id," json:"plan_id"`
SkillID int64 `bun:"skill_id,type:bigint,notnull,unique:uidx_plan_skills_plan_id_skill_id," json:"skill_id"`
RelPlanID *ModelPublicPlans `bun:"rel:has-one,join:plan_id=id" json:"relplanid,omitempty"` // Has one ModelPublicPlans
RelSkillID *ModelPublicAgentSkills `bun:"rel:has-one,join:skill_id=id" json:"relskillid,omitempty"` // Has one ModelPublicAgentSkills
}
// TableName returns the table name for ModelPublicPlanSkills
func (m ModelPublicPlanSkills) TableName() string {
return "public.plan_skills"
}
// TableNameOnly returns the table name without schema for ModelPublicPlanSkills
func (m ModelPublicPlanSkills) TableNameOnly() string {
return "plan_skills"
}
// SchemaName returns the schema name for ModelPublicPlanSkills
func (m ModelPublicPlanSkills) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicPlanSkills) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicPlanSkills) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicPlanSkills) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicPlanSkills) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicPlanSkills) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicPlanSkills) GetPrefix() string {
return "PSL"
}

View File

@@ -1,81 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicPlans struct {
bun.BaseModel `bun:"table:public.plans,alias:plans"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CompletedAt resolvespec_common.SqlTimeStamp `bun:"completed_at,type:timestamptz,nullzero," json:"completed_at"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Description resolvespec_common.SqlString `bun:"description,type:text,default:'',notnull," json:"description"`
DueDate resolvespec_common.SqlTimeStamp `bun:"due_date,type:timestamptz,nullzero," json:"due_date"`
GUID resolvespec_common.SqlUUID `bun:"guid,type:uuid,default:gen_random_uuid(),notnull," json:"guid"`
LastReviewedAt resolvespec_common.SqlTimeStamp `bun:"last_reviewed_at,type:timestamptz,nullzero," json:"last_reviewed_at"`
Owner resolvespec_common.SqlString `bun:"owner,type:text,nullzero," json:"owner"`
Priority resolvespec_common.SqlString `bun:"priority,type:text,default:'medium',notnull," json:"priority"` // low, medium, high, critical
ProjectID resolvespec_common.SqlInt64 `bun:"project_id,type:bigint,nullzero," json:"project_id"`
ReviewedBy resolvespec_common.SqlString `bun:"reviewed_by,type:text,nullzero," json:"reviewed_by"`
Status resolvespec_common.SqlString `bun:"status,type:text,default:'draft',notnull," json:"status"` // draft, active, blocked, completed, cancelled, superseded
SupersedesPlanID resolvespec_common.SqlInt64 `bun:"supersedes_plan_id,type:bigint,nullzero," json:"supersedes_plan_id"`
Tags resolvespec_common.SqlStringArray `bun:"tags,type:text[],default:'{}',notnull," json:"tags"`
Title resolvespec_common.SqlString `bun:"title,type:text,notnull," json:"title"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelProjectID *ModelPublicProjects `bun:"rel:has-one,join:project_id=id" json:"relprojectid,omitempty"` // Has one ModelPublicProjects
RelSupersedesPlanID *ModelPublicPlans `bun:"rel:has-one,join:supersedes_plan_id=id" json:"relsupersedesplanid,omitempty"` // Has one ModelPublicPlans
RelDependsOnPlanIDPublicPlanDependencies []*ModelPublicPlanDependencies `bun:"rel:has-many,join:id=depends_on_plan_id" json:"reldependsonplanidpublicplandependencies,omitempty"` // Has many ModelPublicPlanDependencies
RelPlanIDPublicPlanDependencies []*ModelPublicPlanDependencies `bun:"rel:has-many,join:id=plan_id" json:"relplanidpublicplandependencies,omitempty"` // Has many ModelPublicPlanDependencies
RelPlanAIDPublicPlanRelatedPlans []*ModelPublicPlanRelatedPlans `bun:"rel:has-many,join:id=plan_a_id" json:"relplanaidpublicplanrelatedplans,omitempty"` // Has many ModelPublicPlanRelatedPlans
RelPlanBIDPublicPlanRelatedPlans []*ModelPublicPlanRelatedPlans `bun:"rel:has-many,join:id=plan_b_id" json:"relplanbidpublicplanrelatedplans,omitempty"` // Has many ModelPublicPlanRelatedPlans
RelPlanIDPublicPlanSkills []*ModelPublicPlanSkills `bun:"rel:has-many,join:id=plan_id" json:"relplanidpublicplanskills,omitempty"` // Has many ModelPublicPlanSkills
RelPlanIDPublicPlanGuardrails []*ModelPublicPlanGuardrails `bun:"rel:has-many,join:id=plan_id" json:"relplanidpublicplanguardrails,omitempty"` // Has many ModelPublicPlanGuardrails
}
// TableName returns the table name for ModelPublicPlans
func (m ModelPublicPlans) TableName() string {
return "public.plans"
}
// TableNameOnly returns the table name without schema for ModelPublicPlans
func (m ModelPublicPlans) TableNameOnly() string {
return "plans"
}
// SchemaName returns the schema name for ModelPublicPlans
func (m ModelPublicPlans) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicPlans) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicPlans) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicPlans) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicPlans) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicPlans) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicPlans) GetPrefix() string {
return "PLA"
}

View File

@@ -1,63 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicProjectGuardrails struct {
bun.BaseModel `bun:"table:public.project_guardrails,alias:project_guardrails"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
GuardrailID int64 `bun:"guardrail_id,type:bigint,notnull," json:"guardrail_id"`
ProjectID int64 `bun:"project_id,type:bigint,notnull," json:"project_id"`
RelGuardrailID *ModelPublicAgentGuardrails `bun:"rel:has-one,join:guardrail_id=id" json:"relguardrailid,omitempty"` // Has one ModelPublicAgentGuardrails
RelProjectID *ModelPublicProjects `bun:"rel:has-one,join:project_id=id" json:"relprojectid,omitempty"` // Has one ModelPublicProjects
}
// TableName returns the table name for ModelPublicProjectGuardrails
func (m ModelPublicProjectGuardrails) TableName() string {
return "public.project_guardrails"
}
// TableNameOnly returns the table name without schema for ModelPublicProjectGuardrails
func (m ModelPublicProjectGuardrails) TableNameOnly() string {
return "project_guardrails"
}
// SchemaName returns the schema name for ModelPublicProjectGuardrails
func (m ModelPublicProjectGuardrails) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicProjectGuardrails) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicProjectGuardrails) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicProjectGuardrails) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicProjectGuardrails) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicProjectGuardrails) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicProjectGuardrails) GetPrefix() string {
return "PGR"
}

View File

@@ -1,63 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicProjectSkills struct {
bun.BaseModel `bun:"table:public.project_skills,alias:project_skills"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
ProjectID int64 `bun:"project_id,type:bigint,notnull," json:"project_id"`
SkillID int64 `bun:"skill_id,type:bigint,notnull," json:"skill_id"`
RelProjectID *ModelPublicProjects `bun:"rel:has-one,join:project_id=id" json:"relprojectid,omitempty"` // Has one ModelPublicProjects
RelSkillID *ModelPublicAgentSkills `bun:"rel:has-one,join:skill_id=id" json:"relskillid,omitempty"` // Has one ModelPublicAgentSkills
}
// TableName returns the table name for ModelPublicProjectSkills
func (m ModelPublicProjectSkills) TableName() string {
return "public.project_skills"
}
// TableNameOnly returns the table name without schema for ModelPublicProjectSkills
func (m ModelPublicProjectSkills) TableNameOnly() string {
return "project_skills"
}
// SchemaName returns the schema name for ModelPublicProjectSkills
func (m ModelPublicProjectSkills) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicProjectSkills) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicProjectSkills) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicProjectSkills) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicProjectSkills) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicProjectSkills) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicProjectSkills) GetPrefix() string {
return "PSR"
}

View File

@@ -1,71 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicProjects struct {
bun.BaseModel `bun:"table:public.projects,alias:projects"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),nullzero," json:"created_at"`
Description resolvespec_common.SqlString `bun:"description,type:text,nullzero," json:"description"`
GUID resolvespec_common.SqlUUID `bun:"guid,type:uuid,default:gen_random_uuid(),notnull," json:"guid"`
LastActiveAt resolvespec_common.SqlTimeStamp `bun:"last_active_at,type:timestamptz,default:now(),nullzero," json:"last_active_at"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
ThoughtCount resolvespec_common.SqlInt64 `bun:"thought_count,scanonly" json:"thought_count"`
RelProjectIDPublicThoughts []*ModelPublicThoughts `bun:"rel:has-many,join:id=project_id" json:"relprojectidpublicthoughts,omitempty"` // Has many ModelPublicThoughts
RelProjectIDPublicStoredFiles []*ModelPublicStoredFiles `bun:"rel:has-many,join:id=project_id" json:"relprojectidpublicstoredfiles,omitempty"` // Has many ModelPublicStoredFiles
RelProjectIDPublicChatHistories []*ModelPublicChatHistories `bun:"rel:has-many,join:id=project_id" json:"relprojectidpublicchathistories,omitempty"` // Has many ModelPublicChatHistories
RelProjectIDPublicLearnings []*ModelPublicLearnings `bun:"rel:has-many,join:id=project_id" json:"relprojectidpubliclearnings,omitempty"` // Has many ModelPublicLearnings
RelProjectIDPublicPlans []*ModelPublicPlans `bun:"rel:has-many,join:id=project_id" json:"relprojectidpublicplans,omitempty"` // Has many ModelPublicPlans
RelProjectIDPublicProjectSkills []*ModelPublicProjectSkills `bun:"rel:has-many,join:id=project_id" json:"relprojectidpublicprojectskills,omitempty"` // Has many ModelPublicProjectSkills
RelProjectIDPublicProjectGuardrails []*ModelPublicProjectGuardrails `bun:"rel:has-many,join:id=project_id" json:"relprojectidpublicprojectguardrails,omitempty"` // Has many ModelPublicProjectGuardrails
}
// TableName returns the table name for ModelPublicProjects
func (m ModelPublicProjects) TableName() string {
return "public.projects"
}
// TableNameOnly returns the table name without schema for ModelPublicProjects
func (m ModelPublicProjects) TableNameOnly() string {
return "projects"
}
// SchemaName returns the schema name for ModelPublicProjects
func (m ModelPublicProjects) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicProjects) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicProjects) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicProjects) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicProjects) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicProjects) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicProjects) GetPrefix() string {
return "PRO"
}

View File

@@ -1,72 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicStoredFiles struct {
bun.BaseModel `bun:"table:public.stored_files,alias:stored_files"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
Content []byte `bun:"content,type:bytea,notnull," json:"content"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Encoding resolvespec_common.SqlString `bun:"encoding,type:text,default:'base64',notnull," json:"encoding"`
GUID resolvespec_common.SqlUUID `bun:"guid,type:uuid,default:gen_random_uuid(),notnull," json:"guid"`
Kind resolvespec_common.SqlString `bun:"kind,type:text,default:'file',notnull," json:"kind"`
MediaType resolvespec_common.SqlString `bun:"media_type,type:text,notnull," json:"media_type"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
ProjectID resolvespec_common.SqlInt64 `bun:"project_id,type:bigint,nullzero," json:"project_id"`
Sha256 resolvespec_common.SqlString `bun:"sha256,type:text,notnull," json:"sha256"`
SizeBytes int64 `bun:"size_bytes,type:bigint,notnull," json:"size_bytes"`
ThoughtID resolvespec_common.SqlInt64 `bun:"thought_id,type:bigint,nullzero," json:"thought_id"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelProjectID *ModelPublicProjects `bun:"rel:has-one,join:project_id=id" json:"relprojectid,omitempty"` // Has one ModelPublicProjects
RelThoughtID *ModelPublicThoughts `bun:"rel:has-one,join:thought_id=id" json:"relthoughtid,omitempty"` // Has one ModelPublicThoughts
}
// TableName returns the table name for ModelPublicStoredFiles
func (m ModelPublicStoredFiles) TableName() string {
return "public.stored_files"
}
// TableNameOnly returns the table name without schema for ModelPublicStoredFiles
func (m ModelPublicStoredFiles) TableNameOnly() string {
return "stored_files"
}
// SchemaName returns the schema name for ModelPublicStoredFiles
func (m ModelPublicStoredFiles) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicStoredFiles) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicStoredFiles) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicStoredFiles) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicStoredFiles) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicStoredFiles) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicStoredFiles) GetPrefix() string {
return "SFT"
}

View File

@@ -1,64 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicThoughtLinks struct {
bun.BaseModel `bun:"table:public.thought_links,alias:thought_links"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),nullzero," json:"created_at"`
FromID int64 `bun:"from_id,type:bigint,notnull," json:"from_id"`
Relation resolvespec_common.SqlString `bun:"relation,type:text,notnull," json:"relation"`
ToID int64 `bun:"to_id,type:bigint,notnull," json:"to_id"`
RelFromID *ModelPublicThoughts `bun:"rel:has-one,join:from_id=id" json:"relfromid,omitempty"` // Has one ModelPublicThoughts
RelToID *ModelPublicThoughts `bun:"rel:has-one,join:to_id=id" json:"reltoid,omitempty"` // Has one ModelPublicThoughts
}
// TableName returns the table name for ModelPublicThoughtLinks
func (m ModelPublicThoughtLinks) TableName() string {
return "public.thought_links"
}
// TableNameOnly returns the table name without schema for ModelPublicThoughtLinks
func (m ModelPublicThoughtLinks) TableNameOnly() string {
return "thought_links"
}
// SchemaName returns the schema name for ModelPublicThoughtLinks
func (m ModelPublicThoughtLinks) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicThoughtLinks) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicThoughtLinks) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicThoughtLinks) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicThoughtLinks) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicThoughtLinks) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicThoughtLinks) GetPrefix() string {
return "TLH"
}

View File

@@ -1,71 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicThoughts struct {
bun.BaseModel `bun:"table:public.thoughts,alias:thoughts"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
ArchivedAt resolvespec_common.SqlTimeStamp `bun:"archived_at,type:timestamptz,nullzero," json:"archived_at"`
Content resolvespec_common.SqlString `bun:"content,type:text,notnull," json:"content"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),nullzero," json:"created_at"`
GUID resolvespec_common.SqlUUID `bun:"guid,type:uuid,default:gen_random_uuid(),notnull," json:"guid"`
Metadata resolvespec_common.SqlJSONB `bun:"metadata,type:jsonb,default:{}::jsonb,nullzero," json:"metadata"`
ProjectID resolvespec_common.SqlInt64 `bun:"project_id,type:bigint,nullzero," json:"project_id"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),nullzero," json:"updated_at"`
RelProjectID *ModelPublicProjects `bun:"rel:has-one,join:project_id=id" json:"relprojectid,omitempty"` // Has one ModelPublicProjects
RelFromIDPublicThoughtLinks []*ModelPublicThoughtLinks `bun:"rel:has-many,join:id=from_id" json:"relfromidpublicthoughtlinks,omitempty"` // Has many ModelPublicThoughtLinks
RelToIDPublicThoughtLinks []*ModelPublicThoughtLinks `bun:"rel:has-many,join:id=to_id" json:"reltoidpublicthoughtlinks,omitempty"` // Has many ModelPublicThoughtLinks
RelThoughtIDPublicEmbeddings []*ModelPublicEmbeddings `bun:"rel:has-many,join:id=thought_id" json:"relthoughtidpublicembeddings,omitempty"` // Has many ModelPublicEmbeddings
RelThoughtIDPublicStoredFiles []*ModelPublicStoredFiles `bun:"rel:has-many,join:id=thought_id" json:"relthoughtidpublicstoredfiles,omitempty"` // Has many ModelPublicStoredFiles
RelRelatedThoughtIDPublicLearnings []*ModelPublicLearnings `bun:"rel:has-many,join:id=related_thought_id" json:"relrelatedthoughtidpubliclearnings,omitempty"` // Has many ModelPublicLearnings
}
// TableName returns the table name for ModelPublicThoughts
func (m ModelPublicThoughts) TableName() string {
return "public.thoughts"
}
// TableNameOnly returns the table name without schema for ModelPublicThoughts
func (m ModelPublicThoughts) TableNameOnly() string {
return "thoughts"
}
// SchemaName returns the schema name for ModelPublicThoughts
func (m ModelPublicThoughts) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicThoughts) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicThoughts) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicThoughts) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicThoughts) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicThoughts) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicThoughts) GetPrefix() string {
return "THO"
}

View File

@@ -1,62 +0,0 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicToolAnnotations struct {
bun.BaseModel `bun:"table:public.tool_annotations,alias:tool_annotations"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Notes resolvespec_common.SqlString `bun:"notes,type:text,default:'',notnull," json:"notes"`
ToolName resolvespec_common.SqlString `bun:"tool_name,type:text,notnull," json:"tool_name"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
}
// TableName returns the table name for ModelPublicToolAnnotations
func (m ModelPublicToolAnnotations) TableName() string {
return "public.tool_annotations"
}
// TableNameOnly returns the table name without schema for ModelPublicToolAnnotations
func (m ModelPublicToolAnnotations) TableNameOnly() string {
return "tool_annotations"
}
// SchemaName returns the schema name for ModelPublicToolAnnotations
func (m ModelPublicToolAnnotations) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicToolAnnotations) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicToolAnnotations) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicToolAnnotations) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicToolAnnotations) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicToolAnnotations) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicToolAnnotations) GetPrefix() string {
return "TAO"
}

View File

@@ -748,12 +748,6 @@ func BuildToolCatalog() []tools.ToolEntry {
{Name: "reparse_thought_metadata", Description: "Re-extract and normalize metadata for stored thoughts from their content.", Category: "admin"},
{Name: "retry_failed_metadata", Description: "Retry metadata extraction for thoughts still marked pending or failed.", Category: "admin"},
// maintenance
{Name: "add_maintenance_task", Description: "Create a recurring or one-time home maintenance task.", Category: "maintenance"},
{Name: "log_maintenance", Description: "Log completed maintenance work; automatically updates the task's next due date.", Category: "maintenance"},
{Name: "get_upcoming_maintenance", Description: "List maintenance tasks due within the next N days.", Category: "maintenance"},
{Name: "search_maintenance_history", Description: "Search the maintenance log by task name, category, or date range.", Category: "maintenance"},
// skills
{Name: "add_skill", Description: "Store a reusable agent skill. Supports language_tags, library_tags, framework_tags, and domain_tags for precise retrieval.", Category: "skills"},
{Name: "remove_skill", Description: "Delete an agent skill by id.", Category: "skills"},

View File

@@ -27,68 +27,10 @@ func TestNewListsAllRegisteredTools(t *testing.T) {
}
sort.Strings(got)
want := []string{
"add_guardrail",
"add_learning",
"add_plan_dependency",
"add_plan_guardrail",
"add_plan_skill",
"add_project_guardrail",
"add_project_skill",
"add_related_plan",
"add_skill",
"annotate_tool",
"archive_thought",
"backfill_embeddings",
"capture_thought",
"create_plan",
"create_project",
"delete_chat_history",
"delete_plan",
"delete_thought",
"describe_tools",
"get_active_project",
"get_chat_history",
"get_learning",
"get_plan",
"get_project_context",
"get_thought",
"get_version_info",
"link_thoughts",
"list_chat_histories",
"list_files",
"list_guardrails",
"list_learnings",
"list_plan_guardrails",
"list_plan_skills",
"list_plans",
"list_project_guardrails",
"list_project_skills",
"list_projects",
"list_skills",
"list_thoughts",
"load_file",
"recall_context",
"related_thoughts",
"remove_guardrail",
"remove_plan_dependency",
"remove_plan_guardrail",
"remove_plan_skill",
"remove_project_guardrail",
"remove_project_skill",
"remove_related_plan",
"remove_skill",
"reparse_thought_metadata",
"retry_failed_metadata",
"save_chat_history",
"save_file",
"search_thoughts",
"set_active_project",
"summarize_thoughts",
"thought_stats",
"update_plan",
"update_thought",
"upload_file",
catalog := BuildToolCatalog()
want := make([]string, 0, len(catalog))
for _, tool := range catalog {
want = append(want, tool.Name)
}
sort.Strings(want)

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,8 @@ set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
out_dir="${repo_root}/internal/generatedmodels"
resolve_spec_models_file="${repo_root}/internal/app/resolvespec_models_generated.go"
resolve_spec_template="${repo_root}/scripts/templates/resolvespec_models.tmpl"
resolve_relspec() {
if [[ -n "${RELSPEC:-}" ]]; then
@@ -44,6 +46,12 @@ mkdir -p "${out_dir}"
--to-path "${out_dir}" \
--package generatedmodels
"${relspec_bin}" templ \
--from dbml \
--from-list "${schema_list}" \
--template "${resolve_spec_template}" \
--output "${resolve_spec_models_file}"
# relspec currently emits a few files with unused fmt imports; strip only when fmt is unused.
for file in "${out_dir}"/*.go; do
sed -i 's/fmt.Sprintf("%d", m.ID)/fmt.Sprintf("%v", m.ID)/g' "${file}"
@@ -56,3 +64,4 @@ done
bash "${repo_root}/scripts/patch-generated-models.sh"
gofmt -w "${out_dir}"/*.go
gofmt -w "${resolve_spec_models_file}"

View File

@@ -4,12 +4,18 @@ set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
models_dir="${repo_root}/internal/generatedmodels"
projects_model="${models_dir}/sql_public_projects.go"
persona_arc_model="${models_dir}/sql_public_persona_arc.go"
if [[ ! -f "${projects_model}" ]]; then
echo "generated projects model not found: ${projects_model}" >&2
exit 1
fi
if [[ ! -f "${persona_arc_model}" ]]; then
echo "generated persona arc model not found: ${persona_arc_model}" >&2
exit 1
fi
# Ensure ModelPublicProjects can scan ResolveSpec computed column "thought_count".
if ! grep -q "ThoughtCount" "${projects_model}"; then
tmp_file="$(mktemp)"
@@ -24,3 +30,12 @@ if ! grep -q "ThoughtCount" "${projects_model}"; then
mv "${tmp_file}" "${projects_model}"
fi
# relspec currently emits an incorrect int32 cast for persona_arc primary key updates.
sed -i 's/m\.PersonaID = int32(newid)/m.PersonaID = newid/' "${persona_arc_model}"
# Some join-table models import resolvespec_common without using it.
for file in "${models_dir}"/*.go; do
if ! grep -q 'resolvespec_common\.' "${file}"; then
sed -i '/^[[:space:]]*resolvespec_common "github.com\/bitechdev\/ResolveSpec\/pkg\/spectypes"$/d' "${file}"
fi
done

View File

@@ -0,0 +1,15 @@
// Code generated by relspec templ. DO NOT EDIT.
package app
import "git.warky.dev/wdevs/amcs/internal/generatedmodels"
func resolveSpecModels() []resolveSpecModel {
return []resolveSpecModel{
{{- range sortBy .Database.Schemas "Name" }}
{{- $schema := .Name }}
{{- range sortBy .Tables "Name" }}
{schema: "{{$schema}}", entity: "{{ .Name }}", model: generatedmodels.Model{{ $schema | toPascalCase }}{{ .Name | toPascalCase }}{}},
{{- end }}
{{- end }}
}
}

View File

@@ -0,0 +1,351 @@
<script lang="ts">
import {
ErrorBoundary,
FormerResolveSpecAPI,
GridlerFull,
NativeSelectCtrl,
TextInputCtrl,
type GridlerColumn,
type GridlerContextMenuItem
} from '@warkypublic/svelix';
import { adminGridTheme } from '../../gridTheme';
import { GlobalStateStore } from '../../shellState';
import type { AgentPart } from '../../types';
import FormerShell from '../shared/FormerShell.svelte';
import ContentEditorField from '../shared/ContentEditorField.svelte';
type PartForm = {
id?: string;
name: string;
part_type: string;
description: string;
summary: string;
content: string;
tags: string;
};
const PART_TYPES = [
'system', 'agent', 'soul', 'identity', 'skill', 'specialization',
'tone', 'goal', 'context', 'protocol', 'backstory', 'motivation',
'voice', 'archetype', 'flaw', 'relationship'
];
const PRIMARY_KEY = 'id';
const authToken = GlobalStateStore.getState().session.authToken ?? '';
let selectedPart = $state<AgentPart | null>(null);
let gridTotal = $state<number | null>(null);
let formOpened = $state(false);
let formRequest = $state<'insert' | 'update' | 'delete'>('insert');
let formValues = $state<PartForm>({ name: '', part_type: 'agent', description: '', summary: '', content: '', tags: '' });
let contentEditorOpened = $state(false);
let contentEditorValues = $state<{ id?: string; content: string }>({ content: '' });
let contextRow = $state<Record<string, unknown> | null>(null);
let refreshKey = $state(0);
const apiCall = $derived(FormerResolveSpecAPI({
authToken,
url: '/api/rs/public/agent_parts'
}));
const dataSourceOptions = {
url: '/api/rs',
authToken,
schema: 'public',
entity: 'agent_parts',
uniqueID: PRIMARY_KEY,
hotfields: [PRIMARY_KEY],
sort: [{ column: 'part_type', direction: 'asc' }, { column: 'name', direction: 'asc' }]
} as unknown as { url: string; authToken?: string; schema: string; entity: string; uniqueID: string; hotfields: string[] };
const columns: GridlerColumn[] = [
{ id: 'name', title: 'Name', dataKey: 'name', width: 220 },
{ id: 'part_type', title: 'Type', dataKey: 'part_type', width: 130 },
{ id: 'description', title: 'Description', dataKey: 'description', width: 260 },
{ id: 'summary', title: 'Summary', dataKey: 'summary', width: 280 },
{ id: 'tags', title: 'Tags', dataKey: 'tags', width: 160 },
{ id: 'updated_at', title: 'Updated', dataKey: 'updated_at', width: 160, format: 'datetime' }
];
const menuItems: GridlerContextMenuItem[] = [
{ id: 'add', label: 'Add' },
{ id: 'edit', label: 'Edit' },
{ id: 'edit_content', label: 'Edit Content' },
{ id: 'delete', label: 'Delete' }
];
function normalizeTags(value: unknown): string[] {
if (Array.isArray(value)) return value.map((t) => String(t).trim()).filter(Boolean);
if (typeof value !== 'string' || !value.trim()) return [];
const trimmed = value.trim();
if (trimmed.startsWith('{') && trimmed.endsWith('}')) {
return trimmed.slice(1, -1).split(',').map((t) => t.trim().replace(/^"(.*)"$/, '$1')).filter(Boolean);
}
return trimmed.split(',').map((t) => t.trim()).filter(Boolean);
}
function normalizePart(row: Record<string, unknown>): AgentPart {
return {
id: String(row.id ?? ''),
name: String(row.name ?? ''),
part_type: String(row.part_type ?? ''),
description: String(row.description ?? ''),
summary: String(row.summary ?? ''),
content: String(row.content ?? ''),
tags: normalizeTags(row.tags),
created_at: String(row.created_at ?? ''),
updated_at: String(row.updated_at ?? '')
};
}
function toForm(p: AgentPart): PartForm {
return { id: p.id, name: p.name, part_type: p.part_type, description: p.description, summary: p.summary, content: p.content, tags: p.tags.join(', ') };
}
function normalizeForFormer(data: Record<string, unknown>): PartForm {
return {
id: data.id != null ? String(data.id) : undefined,
name: String(data.name ?? ''),
part_type: String(data.part_type ?? 'agent'),
description: String(data.description ?? ''),
summary: String(data.summary ?? ''),
content: String(data.content ?? ''),
tags: normalizeTags(data.tags).join(', ')
};
}
function normalizeForm(data: PartForm): Record<string, unknown> {
return {
name: data.name.trim(),
part_type: data.part_type,
description: data.description.trim(),
summary: data.summary.trim(),
content: data.content,
tags: data.tags.split(',').map((t) => t.trim()).filter(Boolean)
};
}
function onRowClick(_row: number, rowData: Record<string, unknown> | undefined) {
selectedPart = rowData ? normalizePart(rowData) : null;
}
function onRowContextMenu(_row: number, rowData: Record<string, unknown> | undefined) {
contextRow = rowData ?? null;
}
async function onMenuItemSelect(item: GridlerContextMenuItem) {
if (item.id === 'add') {
formValues = { name: '', part_type: 'agent', description: '', summary: '', content: '', tags: '' };
formRequest = 'insert';
formOpened = true;
return;
}
if (!contextRow) return;
const part = normalizePart(contextRow);
if (item.id === 'edit_content') {
selectedPart = part;
contentEditorValues = { id: part.id, content: part.content };
contentEditorOpened = true;
return;
}
formValues = toForm(part);
formRequest = item.id === 'delete' ? 'delete' : 'update';
formOpened = true;
}
function onRowDblClick(_row: number, rowData: Record<string, unknown> | undefined) {
if (!rowData) return;
contextRow = rowData;
void onMenuItemSelect({ id: 'edit', label: 'Edit' });
}
function onGridEvent(type: string, _i?: unknown, _c?: unknown, _co?: unknown, detail?: Record<string, unknown>) {
if (type !== 'page_loaded' && type !== 'load') return;
if (typeof detail?.total === 'number') gridTotal = detail.total;
}
async function handleSaved() {
formOpened = false;
if (contextRow?.[PRIMARY_KEY]) {
const data = await apiCall('read', 'update', undefined, String(contextRow[PRIMARY_KEY])) as Record<string, unknown>;
selectedPart = normalizePart(data);
}
refreshKey += 1;
}
async function handleContentSaved() {
contentEditorOpened = false;
if (contentEditorValues.id) {
const data = await apiCall('read', 'update', undefined, contentEditorValues.id) as Record<string, unknown>;
selectedPart = normalizePart(data);
}
refreshKey += 1;
}
function formatDate(v?: string) {
return v ? new Date(v).toLocaleString() : '—';
}
</script>
<div class="space-y-4 w-full">
<div class="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
<p class="text-sm text-slate-400">
{#if gridTotal === null}Server-backed grid{:else}{gridTotal} part{gridTotal !== 1 ? 's' : ''}{/if}
</p>
<button
class="rounded-xl border border-cyan-300/30 bg-cyan-400/10 px-4 py-2 text-sm font-medium text-cyan-100 transition hover:bg-cyan-400/20"
onclick={() => { formValues = { name: '', part_type: 'agent', description: '', summary: '', content: '', tags: '' }; formRequest = 'insert'; formOpened = true; }}
>New Part</button>
</div>
<div class="flex flex-col gap-4">
<div class="rounded-2xl border border-white/10 bg-slate-950/30 p-3">
{#key refreshKey}
<ErrorBoundary namespace="PartsGridler">
<GridlerFull
{columns}
theme={adminGridTheme}
rowMarkers="number"
height={400}
width="100%"
pageSize={40}
dataSource="resolvespec"
dataSourceOptions={dataSourceOptions}
serverSideSearch={true}
searchColumns={['name', 'part_type', 'description', 'summary']}
{menuItems}
{onGridEvent}
{onRowClick}
{onRowDblClick}
{onRowContextMenu}
{onMenuItemSelect}
/>
</ErrorBoundary>
{/key}
</div>
<aside class="rounded-2xl border border-white/10 bg-slate-900/70 p-4">
<div class="flex items-start justify-between gap-3">
<h3 class="text-sm font-semibold text-white">Part Inspector</h3>
{#if selectedPart}
<button
class="text-xs text-cyan-300 hover:text-cyan-200"
onclick={() => { if (!selectedPart) return; contentEditorValues = { id: selectedPart.id, content: selectedPart.content }; contentEditorOpened = true; }}
>Edit Content</button>
{/if}
</div>
{#if !selectedPart}
<p class="mt-3 text-sm text-slate-500">Select a part row to inspect.</p>
{:else}
<div class="mt-3 space-y-3 text-sm text-slate-300">
<div class="flex items-center gap-3">
<p class="text-base font-semibold text-slate-100">{selectedPart.name}</p>
<span class="rounded-md bg-cyan-400/10 px-2 py-0.5 text-xs text-cyan-300">{selectedPart.part_type}</span>
</div>
{#if selectedPart.description}
<p><strong class="text-slate-100">Description:</strong> {selectedPart.description}</p>
{/if}
<p><strong class="text-slate-100">Updated:</strong> {formatDate(selectedPart.updated_at)}</p>
<div>
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">Tags</p>
<div class="mt-2 flex flex-wrap gap-2">
{#if selectedPart.tags.length}
{#each selectedPart.tags as tag}
<span class="rounded-md bg-white/10 px-2 py-0.5 text-xs text-slate-300">{tag}</span>
{/each}
{:else}
<span class="text-slate-500">No tags</span>
{/if}
</div>
</div>
<div>
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">Summary</p>
<pre class="mt-2 overflow-x-auto rounded-xl bg-slate-950/60 p-3 text-xs text-slate-300 whitespace-pre-wrap">{selectedPart.summary || '—'}</pre>
</div>
<div>
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">Content</p>
<pre class="mt-2 overflow-x-auto rounded-xl bg-slate-950/60 p-3 text-xs text-slate-300 whitespace-pre-wrap">{selectedPart.content || '—'}</pre>
</div>
</div>
{/if}
</aside>
</div>
</div>
<ErrorBoundary namespace="PartContentEditor">
<FormerShell
bind:opened={contentEditorOpened}
bind:values={contentEditorValues}
request="update"
title="Edit Part Content"
uniqueKeyField={PRIMARY_KEY}
width="min(96vw, 90rem)"
onAPICall={apiCall}
beforeSave={(data) => ({ content: data.content })}
afterSave={handleContentSaved}
onClose={() => { contentEditorOpened = false; }}
>
{#snippet children(state)}
<ContentEditorField
filename="part.md"
value={state.values?.content ?? ''}
onchange={(v) => state.setState('values', { ...state.values, content: v })}
/>
{/snippet}
</FormerShell>
</ErrorBoundary>
<ErrorBoundary namespace="PartsFormer">
<FormerShell
bind:opened={formOpened}
bind:values={formValues}
bind:request={formRequest}
title={formRequest === 'insert' ? 'New Part' : formRequest === 'update' ? 'Edit Part' : 'Delete Part'}
uniqueKeyField={PRIMARY_KEY}
onAPICall={apiCall}
afterGet={async (data) => normalizeForFormer(data as Record<string, unknown>)}
beforeSave={normalizeForm}
afterSave={handleSaved}
onClose={() => { formOpened = false; }}
>
{#snippet children(state)}
<TextInputCtrl
label="Name"
name="name"
required
disabled={state.request === 'delete'}
value={state.values?.name ?? ''}
onchange={(v) => state.setState('values', { ...state.values, name: v })}
/>
<NativeSelectCtrl
label="Part Type"
name="part_type"
disabled={state.request === 'delete'}
value={state.values?.part_type ?? 'agent'}
options={PART_TYPES}
onchange={(v) => state.setState('values', { ...state.values, part_type: v })}
/>
<TextInputCtrl
label="Description"
name="description"
disabled={state.request === 'delete'}
value={state.values?.description ?? ''}
onchange={(v) => state.setState('values', { ...state.values, description: v })}
/>
<TextInputCtrl
label="Tags"
name="tags"
placeholder="comma-separated"
disabled={state.request === 'delete'}
value={state.values?.tags ?? ''}
onchange={(v) => state.setState('values', { ...state.values, tags: v })}
/>
<ContentEditorField
filename="part-summary.md"
value={state.values?.summary ?? ''}
disabled={state.request === 'delete'}
onchange={(v) => state.setState('values', { ...state.values, summary: v })}
/>
{/snippet}
</FormerShell>
</ErrorBoundary>

View File

@@ -0,0 +1,51 @@
<script lang="ts">
import PartsTab from './PartsTab.svelte';
import PersonasTab from './PersonasTab.svelte';
import TraitsTab from './TraitsTab.svelte';
type PersonaSection = 'personas' | 'parts' | 'traits';
const sections: { id: PersonaSection; label: string; description: string }[] = [
{ id: 'personas', label: 'Personas', description: 'Inspect composed agent identities and compiled output.' },
{ id: 'parts', label: 'Parts', description: 'Manage reusable behavior building blocks.' },
{ id: 'traits', label: 'Traits', description: 'Curate atomic personality and behavior traits.' }
];
let currentSection = $state<PersonaSection>('personas');
</script>
<div class="space-y-5">
<section class="rounded-3xl border border-white/10 bg-[radial-gradient(circle_at_top_left,_rgba(34,211,238,0.18),_transparent_40%),linear-gradient(135deg,_rgba(15,23,42,0.96),_rgba(2,6,23,0.92))] p-6">
<p class="text-xs uppercase tracking-[0.28em] text-cyan-300">Personas</p>
<h2 class="mt-3 text-2xl font-semibold text-white">Shape how agents think, speak, and adapt.</h2>
<p class="mt-2 max-w-3xl text-sm text-slate-300">
Manage reusable parts and traits alongside the compiled personas they form. Select a persona to inspect its linked components and current arc state.
</p>
</section>
<div class="flex flex-wrap gap-3">
{#each sections as section}
<button
class={`rounded-2xl border px-4 py-3 text-left transition ${
currentSection === section.id
? 'border-cyan-300/30 bg-cyan-400/12 text-cyan-100'
: 'border-white/10 bg-white/5 text-slate-300 hover:bg-white/10'
}`}
onclick={() => {
currentSection = section.id;
}}
>
<div class="text-sm font-semibold">{section.label}</div>
<div class="mt-1 text-xs text-slate-400">{section.description}</div>
</button>
{/each}
</div>
{#if currentSection === 'personas'}
<PersonasTab />
{:else if currentSection === 'parts'}
<PartsTab />
{:else}
<TraitsTab />
{/if}
</div>

View File

@@ -0,0 +1,657 @@
<script lang="ts">
import {
ErrorBoundary,
FormerResolveSpecAPI,
GridlerFull,
TextInputCtrl,
type GridlerColumn,
type GridlerContextMenuItem
} from '@warkypublic/svelix';
import { adminGridTheme } from '../../gridTheme';
import { GlobalStateStore } from '../../shellState';
import type { AgentPersona } from '../../types';
import FormerShell from '../shared/FormerShell.svelte';
import ContentEditorField from '../shared/ContentEditorField.svelte';
type PersonaForm = {
id?: string;
name: string;
description: string;
summary: string;
detail: string;
tags: string;
};
type ManifestPart = {
name: string;
part_type: string;
description: string;
source: string;
part_order: number;
priority: number;
};
type ManifestTrait = {
name: string;
trait_type: string;
description: string;
};
type ManifestSkill = {
id: string;
name: string;
description: string;
};
type ManifestGuardrail = {
id: string;
name: string;
description: string;
severity: string;
};
type PersonaArcState = {
arc_name: string;
stage_name: string;
stage_order: number;
description: string;
condition: string;
};
type PersonaManifest = {
parts: ManifestPart[];
traits: ManifestTrait[];
skills: ManifestSkill[];
guardrails: ManifestGuardrail[];
arc: PersonaArcState | null;
};
function isDefined<T>(value: T | null): value is T {
return value !== null;
}
const PRIMARY_KEY = 'id';
const authToken = GlobalStateStore.getState().session.authToken ?? '';
let selectedPersona = $state<AgentPersona | null>(null);
let gridTotal = $state<number | null>(null);
let formOpened = $state(false);
let formRequest = $state<'insert' | 'update' | 'delete'>('insert');
let formValues = $state<PersonaForm>({ name: '', description: '', summary: '', detail: '', tags: '' });
let detailEditorOpened = $state(false);
let detailEditorValues = $state<{ id?: string; detail: string }>({ detail: '' });
let contextRow = $state<Record<string, unknown> | null>(null);
let refreshKey = $state(0);
let manifestLoading = $state(false);
let manifestError = $state('');
let manifest = $state<PersonaManifest | null>(null);
const apiCall = $derived(FormerResolveSpecAPI({
authToken,
url: '/api/rs/public/agent_personas'
}));
const dataSourceOptions = {
url: '/api/rs',
authToken,
schema: 'public',
entity: 'agent_personas',
uniqueID: PRIMARY_KEY,
hotfields: [PRIMARY_KEY],
sort: [{ column: 'created_at', direction: 'desc' }]
} as unknown as { url: string; authToken?: string; schema: string; entity: string; uniqueID: string; hotfields: string[] };
const columns: GridlerColumn[] = [
{ id: 'name', title: 'Name', dataKey: 'name', width: 220 },
{ id: 'description', title: 'Description', dataKey: 'description', width: 280 },
{ id: 'summary', title: 'Summary', dataKey: 'summary', width: 300 },
{ id: 'tags', title: 'Tags', dataKey: 'tags', width: 180 },
{ id: 'created_at', title: 'Created', dataKey: 'created_at', width: 160, format: 'datetime' },
{ id: 'updated_at', title: 'Updated', dataKey: 'updated_at', width: 160, format: 'datetime' }
];
const menuItems: GridlerContextMenuItem[] = [
{ id: 'add', label: 'Add' },
{ id: 'edit', label: 'Edit' },
{ id: 'edit_detail', label: 'Edit Detail' },
{ id: 'delete', label: 'Delete' }
];
async function rsReadMany(entity: string, options?: Record<string, unknown>) {
const res = await fetch(`/api/rs/public/${entity}`, {
method: 'POST',
headers: {
Authorization: `Bearer ${authToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
operation: 'read',
...(options ? { options } : {})
})
});
if (!res.ok) throw new Error(`Failed to load ${entity} (${res.status})`);
const body = await res.json() as { success?: boolean; data?: unknown; error?: { message?: string } };
if (!body.success) throw new Error(body.error?.message ?? `ResolveSpec request failed for ${entity}`);
return Array.isArray(body.data) ? body.data as Record<string, unknown>[] : [];
}
function normalizeTags(value: unknown): string[] {
if (Array.isArray(value)) return value.map((t) => String(t).trim()).filter(Boolean);
if (typeof value !== 'string' || !value.trim()) return [];
const trimmed = value.trim();
if (trimmed.startsWith('{') && trimmed.endsWith('}')) {
return trimmed.slice(1, -1).split(',').map((t) => t.trim().replace(/^"(.*)"$/, '$1')).filter(Boolean);
}
return trimmed.split(',').map((t) => t.trim()).filter(Boolean);
}
function normalizePersona(row: Record<string, unknown>): AgentPersona {
return {
id: String(row.id ?? ''),
name: String(row.name ?? ''),
description: String(row.description ?? ''),
summary: String(row.summary ?? ''),
detail: String(row.detail ?? ''),
compiled_summary: String(row.compiled_summary ?? ''),
compiled_detail: String(row.compiled_detail ?? ''),
compiled_at: row.compiled_at ? String(row.compiled_at) : undefined,
tags: normalizeTags(row.tags),
created_at: String(row.created_at ?? ''),
updated_at: String(row.updated_at ?? '')
};
}
function toForm(p: AgentPersona): PersonaForm {
return { id: p.id, name: p.name, description: p.description, summary: p.summary, detail: p.detail, tags: p.tags.join(', ') };
}
function normalizeForFormer(data: Record<string, unknown>): PersonaForm {
return {
id: data.id != null ? String(data.id) : undefined,
name: String(data.name ?? ''),
description: String(data.description ?? ''),
summary: String(data.summary ?? ''),
detail: String(data.detail ?? ''),
tags: normalizeTags(data.tags).join(', ')
};
}
function normalizeForm(data: PersonaForm): Record<string, unknown> {
return {
name: data.name.trim(),
description: data.description.trim(),
summary: data.summary.trim(),
detail: data.detail.trim(),
tags: data.tags.split(',').map((t) => t.trim()).filter(Boolean)
};
}
function onRowClick(_row: number, rowData: Record<string, unknown> | undefined) {
if (!rowData) {
selectedPersona = null;
manifest = null;
manifestError = '';
return;
}
const persona = normalizePersona(rowData);
selectedPersona = persona;
void loadManifest(persona);
}
function onRowContextMenu(_row: number, rowData: Record<string, unknown> | undefined) {
contextRow = rowData ?? null;
}
async function onMenuItemSelect(item: GridlerContextMenuItem) {
if (item.id === 'add') {
formValues = { name: '', description: '', summary: '', detail: '', tags: '' };
formRequest = 'insert';
formOpened = true;
return;
}
if (!contextRow) return;
const persona = normalizePersona(contextRow);
if (item.id === 'edit_detail') {
selectedPersona = persona;
void loadManifest(persona);
detailEditorValues = { id: persona.id, detail: persona.detail };
detailEditorOpened = true;
return;
}
formValues = toForm(persona);
formRequest = item.id === 'delete' ? 'delete' : 'update';
formOpened = true;
}
function onRowDblClick(_row: number, rowData: Record<string, unknown> | undefined) {
if (!rowData) return;
contextRow = rowData;
void onMenuItemSelect({ id: 'edit', label: 'Edit' });
}
function onGridEvent(type: string, _i?: unknown, _c?: unknown, _co?: unknown, detail?: Record<string, unknown>) {
if (type !== 'page_loaded' && type !== 'load') return;
if (typeof detail?.total === 'number') gridTotal = detail.total;
}
async function handleSaved() {
formOpened = false;
if (contextRow?.[PRIMARY_KEY]) {
const data = await apiCall('read', 'update', undefined, String(contextRow[PRIMARY_KEY])) as Record<string, unknown>;
const persona = normalizePersona(data);
selectedPersona = persona;
await loadManifest(persona);
}
refreshKey += 1;
}
async function handleDetailSaved() {
detailEditorOpened = false;
if (detailEditorValues.id) {
const data = await apiCall('read', 'update', undefined, detailEditorValues.id) as Record<string, unknown>;
const persona = normalizePersona(data);
selectedPersona = persona;
await loadManifest(persona);
}
refreshKey += 1;
}
async function loadManifest(persona: AgentPersona) {
manifestLoading = true;
manifestError = '';
try {
const personaID = Number.parseInt(persona.id, 10);
if (Number.isNaN(personaID)) throw new Error('Invalid persona id.');
const [partLinks, traitLinks, skillLinks, guardrailLinks, personaArcRows, allParts, allTraits, allSkills, allGuardrails, allArcs, allStages] = await Promise.all([
rsReadMany('agent_persona_parts', { filters: [{ column: 'persona_id', operator: 'eq', value: personaID }] }),
rsReadMany('agent_persona_traits', { filters: [{ column: 'persona_id', operator: 'eq', value: personaID }] }),
rsReadMany('agent_persona_skills', { filters: [{ column: 'persona_id', operator: 'eq', value: personaID }] }),
rsReadMany('agent_persona_guardrails', { filters: [{ column: 'persona_id', operator: 'eq', value: personaID }] }),
rsReadMany('persona_arc', { filters: [{ column: 'persona_id', operator: 'eq', value: personaID }] }),
rsReadMany('agent_parts', { limit: 500 }),
rsReadMany('agent_traits', { limit: 500 }),
rsReadMany('agent_skills', { limit: 500 }),
rsReadMany('agent_guardrails', { limit: 500 }),
rsReadMany('character_arcs', { limit: 500 }),
rsReadMany('arc_stages', { limit: 1000 })
]);
const partByID = new Map(allParts.map((row) => [Number(row.id), row]));
const traitByID = new Map(allTraits.map((row) => [Number(row.id), row]));
const skillByID = new Map(allSkills.map((row) => [Number(row.id), row]));
const guardrailByID = new Map(allGuardrails.map((row) => [Number(row.id), row]));
const arcByID = new Map(allArcs.map((row) => [Number(row.id), row]));
const stageByID = new Map(allStages.map((row) => [Number(row.id), row]));
const parts = partLinks
.map((link) => {
const part = partByID.get(Number(link.part_id));
if (!part) return null;
return {
name: String(part.name ?? ''),
part_type: String(part.part_type ?? ''),
description: String(part.description ?? ''),
source: 'persona',
part_order: Number(link.part_order ?? 0),
priority: Number(link.priority ?? 0)
} satisfies ManifestPart;
})
.filter(isDefined)
.sort((a, b) => a.part_order - b.part_order || b.priority - a.priority || a.name.localeCompare(b.name));
const traits = traitLinks
.map((link) => {
const trait = traitByID.get(Number(link.trait_id));
if (!trait) return null;
return {
name: String(trait.name ?? ''),
trait_type: String(trait.trait_type ?? ''),
description: String(trait.description ?? '')
} satisfies ManifestTrait;
})
.filter(isDefined)
.sort((a, b) => a.name.localeCompare(b.name));
const skills = skillLinks
.map((link) => {
const skill = skillByID.get(Number(link.skill_id));
if (!skill) return null;
return {
id: String(skill.id ?? ''),
name: String(skill.name ?? ''),
description: String(skill.description ?? '')
} satisfies ManifestSkill;
})
.filter(isDefined)
.sort((a, b) => a.name.localeCompare(b.name));
const guardrails = guardrailLinks
.map((link) => {
const guardrail = guardrailByID.get(Number(link.guardrail_id));
if (!guardrail) return null;
return {
id: String(guardrail.id ?? ''),
name: String(guardrail.name ?? ''),
description: String(guardrail.description ?? ''),
severity: String(guardrail.severity ?? 'medium')
} satisfies ManifestGuardrail;
})
.filter(isDefined)
.sort((a, b) => a.name.localeCompare(b.name));
const arcRow = personaArcRows[0];
const arc = arcRow
? (() => {
const arcEntity = arcByID.get(Number(arcRow.arc_id));
const stageEntity = stageByID.get(Number(arcRow.current_stage_id));
return {
arc_name: String(arcEntity?.name ?? ''),
stage_name: String(stageEntity?.name ?? ''),
stage_order: Number(stageEntity?.stage_order ?? 0),
description: String(stageEntity?.description ?? ''),
condition: String(stageEntity?.condition ?? '')
} satisfies PersonaArcState;
})()
: null;
manifest = { parts, traits, skills, guardrails, arc };
} catch (err) {
manifest = null;
manifestError = err instanceof Error ? err.message : 'Failed to load persona composition.';
} finally {
manifestLoading = false;
}
}
function formatDate(v?: string) {
return v ? new Date(v).toLocaleString() : '—';
}
</script>
<div class="space-y-4 w-full">
<div class="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
<div>
<h2 class="text-2xl font-semibold text-white">Personas</h2>
<p class="mt-1 text-sm text-slate-400">
{#if gridTotal === null}Server-backed grid{:else}{gridTotal} persona{gridTotal !== 1 ? 's' : ''}{/if}
</p>
</div>
<button
class="rounded-xl border border-cyan-300/30 bg-cyan-400/10 px-4 py-2 text-sm font-medium text-cyan-100 transition hover:bg-cyan-400/20"
onclick={() => { formValues = { name: '', description: '', summary: '', detail: '', tags: '' }; formRequest = 'insert'; formOpened = true; }}
>New Persona</button>
</div>
<div class="flex flex-col gap-4">
<div class="rounded-2xl border border-white/10 bg-slate-950/30 p-3">
{#key refreshKey}
<ErrorBoundary namespace="PersonasGridler">
<GridlerFull
{columns}
theme={adminGridTheme}
rowMarkers="number"
height={400}
width="100%"
pageSize={40}
dataSource="resolvespec"
dataSourceOptions={dataSourceOptions}
serverSideSearch={true}
searchColumns={['name', 'description', 'summary']}
{menuItems}
{onGridEvent}
{onRowClick}
{onRowDblClick}
{onRowContextMenu}
{onMenuItemSelect}
/>
</ErrorBoundary>
{/key}
</div>
<aside class="rounded-2xl border border-white/10 bg-slate-900/70 p-4">
<div class="flex items-start justify-between gap-3">
<h3 class="text-sm font-semibold text-white">Persona Inspector</h3>
{#if selectedPersona}
<div class="flex gap-2">
<button
class="text-xs text-cyan-300 hover:text-cyan-200"
onclick={() => { if (!selectedPersona) return; detailEditorValues = { id: selectedPersona.id, detail: selectedPersona.detail }; detailEditorOpened = true; }}
>Edit Detail</button>
</div>
{/if}
</div>
{#if !selectedPersona}
<p class="mt-3 text-sm text-slate-500">Select a persona row to inspect.</p>
{:else}
<div class="mt-3 space-y-3 text-sm text-slate-300">
<p class="text-base font-semibold text-slate-100">{selectedPersona.name}</p>
{#if selectedPersona.description}
<p><strong class="text-slate-100">Description:</strong> {selectedPersona.description}</p>
{/if}
<p><strong class="text-slate-100">Created:</strong> {formatDate(selectedPersona.created_at)}</p>
<p><strong class="text-slate-100">Updated:</strong> {formatDate(selectedPersona.updated_at)}</p>
{#if selectedPersona.compiled_at}
<p><strong class="text-slate-100">Compiled:</strong> {formatDate(selectedPersona.compiled_at)}</p>
{/if}
<div>
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">Tags</p>
<div class="mt-2 flex flex-wrap gap-2">
{#if selectedPersona.tags.length}
{#each selectedPersona.tags as tag}
<span class="rounded-md bg-white/10 px-2 py-0.5 text-xs text-slate-300">{tag}</span>
{/each}
{:else}
<span class="text-slate-500">No tags</span>
{/if}
</div>
</div>
<div>
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">Summary</p>
<pre class="mt-2 overflow-x-auto rounded-xl bg-slate-950/60 p-3 text-xs text-slate-300 whitespace-pre-wrap">{selectedPersona.summary || '—'}</pre>
</div>
<div>
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">Detail</p>
<pre class="mt-2 max-h-56 overflow-auto rounded-xl bg-slate-950/60 p-3 text-xs text-slate-300 whitespace-pre-wrap">{selectedPersona.detail || '—'}</pre>
</div>
{#if selectedPersona.compiled_summary}
<div>
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">Compiled Summary</p>
<pre class="mt-2 overflow-x-auto rounded-xl bg-slate-950/60 p-3 text-xs text-slate-300 whitespace-pre-wrap">{selectedPersona.compiled_summary}</pre>
</div>
{/if}
{#if selectedPersona.compiled_detail}
<div>
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">Compiled Detail</p>
<pre class="mt-2 max-h-64 overflow-auto rounded-xl bg-slate-950/60 p-3 text-xs text-slate-300 whitespace-pre-wrap">{selectedPersona.compiled_detail}</pre>
</div>
{/if}
<div class="rounded-2xl border border-white/10 bg-slate-950/40 p-4">
<div class="flex items-center justify-between gap-3">
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">Composition</p>
{#if manifestLoading}
<span class="text-xs text-slate-500">Loading…</span>
{/if}
</div>
{#if manifestError}
<p class="mt-3 text-sm text-rose-300">{manifestError}</p>
{:else if manifest}
<div class="mt-3 space-y-4">
<div>
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">Arc</p>
{#if manifest.arc}
<div class="mt-2 rounded-xl bg-white/5 p-3 text-sm text-slate-300">
<p class="font-medium text-slate-100">{manifest.arc.arc_name} · Stage {manifest.arc.stage_order}: {manifest.arc.stage_name}</p>
{#if manifest.arc.description}
<p class="mt-1">{manifest.arc.description}</p>
{/if}
{#if manifest.arc.condition}
<p class="mt-2 text-xs text-slate-400">Condition: {manifest.arc.condition}</p>
{/if}
</div>
{:else}
<p class="mt-2 text-sm text-slate-500">No arc assigned.</p>
{/if}
</div>
<div>
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">Parts</p>
{#if manifest.parts.length}
<div class="mt-2 space-y-2">
{#each manifest.parts as part}
<div class="rounded-xl bg-white/5 p-3 text-sm text-slate-300">
<div class="flex flex-wrap items-center gap-2">
<span class="font-medium text-slate-100">{part.name}</span>
<span class="rounded-md bg-cyan-400/10 px-2 py-0.5 text-[11px] text-cyan-300">{part.part_type}</span>
<span class="text-[11px] text-slate-500">order {part.part_order ?? 0} · priority {part.priority ?? 0}</span>
</div>
{#if part.description}
<p class="mt-1 text-xs text-slate-400">{part.description}</p>
{/if}
</div>
{/each}
</div>
{:else}
<p class="mt-2 text-sm text-slate-500">No parts linked.</p>
{/if}
</div>
<div class="grid gap-4 lg:grid-cols-3">
<div>
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">Traits</p>
{#if manifest.traits.length}
<div class="mt-2 space-y-2">
{#each manifest.traits as trait}
<div class="rounded-xl bg-white/5 p-3 text-sm text-slate-300">
<div class="flex flex-wrap items-center gap-2">
<span class="font-medium text-slate-100">{trait.name}</span>
<span class="rounded-md bg-white/10 px-2 py-0.5 text-[11px] text-slate-300">{trait.trait_type}</span>
</div>
{#if trait.description}
<p class="mt-1 text-xs text-slate-400">{trait.description}</p>
{/if}
</div>
{/each}
</div>
{:else}
<p class="mt-2 text-sm text-slate-500">No traits linked.</p>
{/if}
</div>
<div>
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">Skills</p>
{#if manifest.skills.length}
<div class="mt-2 space-y-2">
{#each manifest.skills as skill}
<div class="rounded-xl bg-white/5 p-3 text-sm text-slate-300">
<p class="font-medium text-slate-100">{skill.name}</p>
{#if skill.description}
<p class="mt-1 text-xs text-slate-400">{skill.description}</p>
{/if}
</div>
{/each}
</div>
{:else}
<p class="mt-2 text-sm text-slate-500">No skills linked.</p>
{/if}
</div>
<div>
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">Guardrails</p>
{#if manifest.guardrails.length}
<div class="mt-2 space-y-2">
{#each manifest.guardrails as guardrail}
<div class="rounded-xl bg-white/5 p-3 text-sm text-slate-300">
<div class="flex flex-wrap items-center gap-2">
<span class="font-medium text-slate-100">{guardrail.name}</span>
<span class="rounded-md bg-amber-400/10 px-2 py-0.5 text-[11px] text-amber-200">{guardrail.severity}</span>
</div>
{#if guardrail.description}
<p class="mt-1 text-xs text-slate-400">{guardrail.description}</p>
{/if}
</div>
{/each}
</div>
{:else}
<p class="mt-2 text-sm text-slate-500">No guardrails linked.</p>
{/if}
</div>
</div>
</div>
{:else}
<p class="mt-3 text-sm text-slate-500">Select a persona row to load linked parts, traits, skills, guardrails, and arc state.</p>
{/if}
</div>
</div>
{/if}
</aside>
</div>
</div>
<ErrorBoundary namespace="PersonaDetailEditor">
<FormerShell
bind:opened={detailEditorOpened}
bind:values={detailEditorValues}
request="update"
title="Edit Persona Detail"
uniqueKeyField={PRIMARY_KEY}
width="min(96vw, 90rem)"
onAPICall={apiCall}
beforeSave={(data) => ({ detail: data.detail })}
afterSave={handleDetailSaved}
onClose={() => { detailEditorOpened = false; }}
>
{#snippet children(state)}
<ContentEditorField
filename="persona-detail.md"
value={state.values?.detail ?? ''}
onchange={(v) => state.setState('values', { ...state.values, detail: v })}
/>
{/snippet}
</FormerShell>
</ErrorBoundary>
<ErrorBoundary namespace="PersonasFormer">
<FormerShell
bind:opened={formOpened}
bind:values={formValues}
bind:request={formRequest}
title={formRequest === 'insert' ? 'New Persona' : formRequest === 'update' ? 'Edit Persona' : 'Delete Persona'}
uniqueKeyField={PRIMARY_KEY}
onAPICall={apiCall}
afterGet={async (data) => normalizeForFormer(data as Record<string, unknown>)}
beforeSave={normalizeForm}
afterSave={handleSaved}
onClose={() => { formOpened = false; }}
>
{#snippet children(state)}
<TextInputCtrl
label="Name"
name="name"
required
disabled={state.request === 'delete'}
value={state.values?.name ?? ''}
onchange={(v) => state.setState('values', { ...state.values, name: v })}
/>
<TextInputCtrl
label="Description"
name="description"
disabled={state.request === 'delete'}
value={state.values?.description ?? ''}
onchange={(v) => state.setState('values', { ...state.values, description: v })}
/>
<TextInputCtrl
label="Tags"
name="tags"
placeholder="comma-separated"
disabled={state.request === 'delete'}
value={state.values?.tags ?? ''}
onchange={(v) => state.setState('values', { ...state.values, tags: v })}
/>
<ContentEditorField
filename="persona-summary.md"
value={state.values?.summary ?? ''}
disabled={state.request === 'delete'}
onchange={(v) => state.setState('values', { ...state.values, summary: v })}
/>
{/snippet}
</FormerShell>
</ErrorBoundary>

View File

@@ -0,0 +1,338 @@
<script lang="ts">
import {
ErrorBoundary,
FormerResolveSpecAPI,
GridlerFull,
NativeSelectCtrl,
TextInputCtrl,
type GridlerColumn,
type GridlerContextMenuItem
} from '@warkypublic/svelix';
import { adminGridTheme } from '../../gridTheme';
import { GlobalStateStore } from '../../shellState';
import type { AgentTrait } from '../../types';
import FormerShell from '../shared/FormerShell.svelte';
import ContentEditorField from '../shared/ContentEditorField.svelte';
type TraitForm = {
id?: string;
name: string;
trait_type: string;
description: string;
instruction: string;
tags: string;
};
const TRAIT_TYPES = ['personality', 'cognitive', 'emotional', 'social', 'behavioral'];
const PRIMARY_KEY = 'id';
const authToken = GlobalStateStore.getState().session.authToken ?? '';
let selectedTrait = $state<AgentTrait | null>(null);
let gridTotal = $state<number | null>(null);
let formOpened = $state(false);
let formRequest = $state<'insert' | 'update' | 'delete'>('insert');
let formValues = $state<TraitForm>({ name: '', trait_type: 'personality', description: '', instruction: '', tags: '' });
let instructionEditorOpened = $state(false);
let instructionEditorValues = $state<{ id?: string; instruction: string }>({ instruction: '' });
let contextRow = $state<Record<string, unknown> | null>(null);
let refreshKey = $state(0);
const apiCall = $derived(FormerResolveSpecAPI({
authToken,
url: '/api/rs/public/agent_traits'
}));
const dataSourceOptions = {
url: '/api/rs',
authToken,
schema: 'public',
entity: 'agent_traits',
uniqueID: PRIMARY_KEY,
hotfields: [PRIMARY_KEY],
sort: [{ column: 'trait_type', direction: 'asc' }, { column: 'name', direction: 'asc' }]
} as unknown as { url: string; authToken?: string; schema: string; entity: string; uniqueID: string; hotfields: string[] };
const columns: GridlerColumn[] = [
{ id: 'name', title: 'Name', dataKey: 'name', width: 220 },
{ id: 'trait_type', title: 'Type', dataKey: 'trait_type', width: 130 },
{ id: 'description', title: 'Description', dataKey: 'description', width: 300 },
{ id: 'tags', title: 'Tags', dataKey: 'tags', width: 180 },
{ id: 'updated_at', title: 'Updated', dataKey: 'updated_at', width: 160, format: 'datetime' }
];
const menuItems: GridlerContextMenuItem[] = [
{ id: 'add', label: 'Add' },
{ id: 'edit', label: 'Edit' },
{ id: 'edit_instruction', label: 'Edit Instruction' },
{ id: 'delete', label: 'Delete' }
];
function normalizeTags(value: unknown): string[] {
if (Array.isArray(value)) return value.map((t) => String(t).trim()).filter(Boolean);
if (typeof value !== 'string' || !value.trim()) return [];
const trimmed = value.trim();
if (trimmed.startsWith('{') && trimmed.endsWith('}')) {
return trimmed.slice(1, -1).split(',').map((t) => t.trim().replace(/^"(.*)"$/, '$1')).filter(Boolean);
}
return trimmed.split(',').map((t) => t.trim()).filter(Boolean);
}
function normalizeTrait(row: Record<string, unknown>): AgentTrait {
return {
id: String(row.id ?? ''),
name: String(row.name ?? ''),
trait_type: String(row.trait_type ?? ''),
description: String(row.description ?? ''),
instruction: String(row.instruction ?? ''),
tags: normalizeTags(row.tags),
created_at: String(row.created_at ?? ''),
updated_at: String(row.updated_at ?? '')
};
}
function toForm(t: AgentTrait): TraitForm {
return { id: t.id, name: t.name, trait_type: t.trait_type, description: t.description, instruction: t.instruction, tags: t.tags.join(', ') };
}
function normalizeForFormer(data: Record<string, unknown>): TraitForm {
return {
id: data.id != null ? String(data.id) : undefined,
name: String(data.name ?? ''),
trait_type: String(data.trait_type ?? 'personality'),
description: String(data.description ?? ''),
instruction: String(data.instruction ?? ''),
tags: normalizeTags(data.tags).join(', ')
};
}
function normalizeForm(data: TraitForm): Record<string, unknown> {
return {
name: data.name.trim(),
trait_type: data.trait_type,
description: data.description.trim(),
instruction: data.instruction,
tags: data.tags.split(',').map((t) => t.trim()).filter(Boolean)
};
}
function onRowClick(_row: number, rowData: Record<string, unknown> | undefined) {
selectedTrait = rowData ? normalizeTrait(rowData) : null;
}
function onRowContextMenu(_row: number, rowData: Record<string, unknown> | undefined) {
contextRow = rowData ?? null;
}
async function onMenuItemSelect(item: GridlerContextMenuItem) {
if (item.id === 'add') {
formValues = { name: '', trait_type: 'personality', description: '', instruction: '', tags: '' };
formRequest = 'insert';
formOpened = true;
return;
}
if (!contextRow) return;
const trait = normalizeTrait(contextRow);
if (item.id === 'edit_instruction') {
selectedTrait = trait;
instructionEditorValues = { id: trait.id, instruction: trait.instruction };
instructionEditorOpened = true;
return;
}
formValues = toForm(trait);
formRequest = item.id === 'delete' ? 'delete' : 'update';
formOpened = true;
}
function onRowDblClick(_row: number, rowData: Record<string, unknown> | undefined) {
if (!rowData) return;
contextRow = rowData;
void onMenuItemSelect({ id: 'edit', label: 'Edit' });
}
function onGridEvent(type: string, _i?: unknown, _c?: unknown, _co?: unknown, detail?: Record<string, unknown>) {
if (type !== 'page_loaded' && type !== 'load') return;
if (typeof detail?.total === 'number') gridTotal = detail.total;
}
async function handleSaved() {
formOpened = false;
if (contextRow?.[PRIMARY_KEY]) {
const data = await apiCall('read', 'update', undefined, String(contextRow[PRIMARY_KEY])) as Record<string, unknown>;
selectedTrait = normalizeTrait(data);
}
refreshKey += 1;
}
async function handleInstructionSaved() {
instructionEditorOpened = false;
if (instructionEditorValues.id) {
const data = await apiCall('read', 'update', undefined, instructionEditorValues.id) as Record<string, unknown>;
selectedTrait = normalizeTrait(data);
}
refreshKey += 1;
}
function formatDate(v?: string) {
return v ? new Date(v).toLocaleString() : '—';
}
</script>
<div class="space-y-4 w-full">
<div class="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
<p class="text-sm text-slate-400">
{#if gridTotal === null}Server-backed grid{:else}{gridTotal} trait{gridTotal !== 1 ? 's' : ''}{/if}
</p>
<button
class="rounded-xl border border-cyan-300/30 bg-cyan-400/10 px-4 py-2 text-sm font-medium text-cyan-100 transition hover:bg-cyan-400/20"
onclick={() => { formValues = { name: '', trait_type: 'personality', description: '', instruction: '', tags: '' }; formRequest = 'insert'; formOpened = true; }}
>New Trait</button>
</div>
<div class="flex flex-col gap-4">
<div class="rounded-2xl border border-white/10 bg-slate-950/30 p-3">
{#key refreshKey}
<ErrorBoundary namespace="TraitsGridler">
<GridlerFull
{columns}
theme={adminGridTheme}
rowMarkers="number"
height={400}
width="100%"
pageSize={40}
dataSource="resolvespec"
dataSourceOptions={dataSourceOptions}
serverSideSearch={true}
searchColumns={['name', 'trait_type', 'description']}
{menuItems}
{onGridEvent}
{onRowClick}
{onRowDblClick}
{onRowContextMenu}
{onMenuItemSelect}
/>
</ErrorBoundary>
{/key}
</div>
<aside class="rounded-2xl border border-white/10 bg-slate-900/70 p-4">
<div class="flex items-start justify-between gap-3">
<h3 class="text-sm font-semibold text-white">Trait Inspector</h3>
{#if selectedTrait}
<button
class="text-xs text-cyan-300 hover:text-cyan-200"
onclick={() => { if (!selectedTrait) return; instructionEditorValues = { id: selectedTrait.id, instruction: selectedTrait.instruction }; instructionEditorOpened = true; }}
>Edit Instruction</button>
{/if}
</div>
{#if !selectedTrait}
<p class="mt-3 text-sm text-slate-500">Select a trait row to inspect.</p>
{:else}
<div class="mt-3 space-y-3 text-sm text-slate-300">
<div class="flex items-center gap-3">
<p class="text-base font-semibold text-slate-100">{selectedTrait.name}</p>
<span class="rounded-md bg-cyan-400/10 px-2 py-0.5 text-xs text-cyan-300">{selectedTrait.trait_type}</span>
</div>
{#if selectedTrait.description}
<p><strong class="text-slate-100">Description:</strong> {selectedTrait.description}</p>
{/if}
<p><strong class="text-slate-100">Updated:</strong> {formatDate(selectedTrait.updated_at)}</p>
<div>
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">Tags</p>
<div class="mt-2 flex flex-wrap gap-2">
{#if selectedTrait.tags.length}
{#each selectedTrait.tags as tag}
<span class="rounded-md bg-white/10 px-2 py-0.5 text-xs text-slate-300">{tag}</span>
{/each}
{:else}
<span class="text-slate-500">No tags</span>
{/if}
</div>
</div>
<div>
<p class="text-xs uppercase tracking-[0.18em] text-slate-500">Instruction</p>
<pre class="mt-2 overflow-x-auto rounded-xl bg-slate-950/60 p-3 text-xs text-slate-300 whitespace-pre-wrap">{selectedTrait.instruction || '—'}</pre>
</div>
</div>
{/if}
</aside>
</div>
</div>
<ErrorBoundary namespace="TraitInstructionEditor">
<FormerShell
bind:opened={instructionEditorOpened}
bind:values={instructionEditorValues}
request="update"
title="Edit Trait Instruction"
uniqueKeyField={PRIMARY_KEY}
width="min(96vw, 90rem)"
onAPICall={apiCall}
beforeSave={(data) => ({ instruction: data.instruction })}
afterSave={handleInstructionSaved}
onClose={() => { instructionEditorOpened = false; }}
>
{#snippet children(state)}
<ContentEditorField
filename="trait-instruction.md"
value={state.values?.instruction ?? ''}
onchange={(v) => state.setState('values', { ...state.values, instruction: v })}
/>
{/snippet}
</FormerShell>
</ErrorBoundary>
<ErrorBoundary namespace="TraitsFormer">
<FormerShell
bind:opened={formOpened}
bind:values={formValues}
bind:request={formRequest}
title={formRequest === 'insert' ? 'New Trait' : formRequest === 'update' ? 'Edit Trait' : 'Delete Trait'}
uniqueKeyField={PRIMARY_KEY}
onAPICall={apiCall}
afterGet={async (data) => normalizeForFormer(data as Record<string, unknown>)}
beforeSave={normalizeForm}
afterSave={handleSaved}
onClose={() => { formOpened = false; }}
>
{#snippet children(state)}
<TextInputCtrl
label="Name"
name="name"
required
disabled={state.request === 'delete'}
value={state.values?.name ?? ''}
onchange={(v) => state.setState('values', { ...state.values, name: v })}
/>
<NativeSelectCtrl
label="Trait Type"
name="trait_type"
disabled={state.request === 'delete'}
value={state.values?.trait_type ?? 'personality'}
options={TRAIT_TYPES}
onchange={(v) => state.setState('values', { ...state.values, trait_type: v })}
/>
<TextInputCtrl
label="Description"
name="description"
disabled={state.request === 'delete'}
value={state.values?.description ?? ''}
onchange={(v) => state.setState('values', { ...state.values, description: v })}
/>
<TextInputCtrl
label="Tags"
name="tags"
placeholder="comma-separated"
disabled={state.request === 'delete'}
value={state.values?.tags ?? ''}
onchange={(v) => state.setState('values', { ...state.values, tags: v })}
/>
<ContentEditorField
filename="trait-instruction.md"
value={state.values?.instruction ?? ''}
disabled={state.request === 'delete'}
onchange={(v) => state.setState('values', { ...state.values, instruction: v })}
/>
{/snippet}
</FormerShell>
</ErrorBoundary>

View File

@@ -6,6 +6,7 @@
import PlansPage from '../plans/PlansPage.svelte';
import MaintenancePage from '../maintenance/MaintenancePage.svelte';
import DashboardPage from '../dashboard/DashboardPage.svelte';
import PersonasPage from '../personas/PersonasPage.svelte';
import ProjectsPage from '../projects/ProjectsPage.svelte';
import SkillsPage from '../skills/SkillsPage.svelte';
import ThoughtsPage from '../thoughts/ThoughtsPage.svelte';
@@ -48,6 +49,8 @@
<SkillsPage />
{:else if currentPage === 'guardrails'}
<GuardrailsPage />
{:else if currentPage === 'personas'}
<PersonasPage />
{:else if currentPage === 'files'}
<FilesPage />
{:else if currentPage === 'maintenance'}

View File

@@ -19,6 +19,7 @@
{ id: 'plans', label: 'Plans', description: 'Structured plans and workstreams.' },
{ id: 'skills', label: 'Skills', description: 'Agent skill registry.' },
{ id: 'guardrails', label: 'Guardrails', description: 'Agent guardrail registry.' },
{ id: 'personas', label: 'Personas', description: 'Compose personas from parts and traits.' },
{ id: 'files', label: 'Files', description: 'Stored file inventory.' },
{ id: 'maintenance', label: 'Maintenance', description: 'Task state and upkeep actions.' }
];

View File

@@ -56,7 +56,7 @@ export type NavItem = {
disabled?: boolean;
};
export type ShellPage = 'dashboard' | 'projects' | 'thoughts' | 'learnings' | 'plans' | 'skills' | 'guardrails' | 'files' | 'maintenance';
export type ShellPage = 'dashboard' | 'projects' | 'thoughts' | 'learnings' | 'plans' | 'skills' | 'guardrails' | 'personas' | 'files' | 'maintenance';
export type Project = {
id: string;
@@ -139,6 +139,52 @@ export type AgentGuardrail = {
updated_at: string;
};
export type AgentPersona = {
id: string;
name: string;
description: string;
summary: string;
detail: string;
compiled_summary: string;
compiled_detail: string;
compiled_at?: string;
tags: string[];
created_at: string;
updated_at: string;
};
export type AgentPart = {
id: string;
name: string;
part_type: string;
description: string;
summary: string;
content: string;
tags: string[];
created_at: string;
updated_at: string;
};
export type AgentTrait = {
id: string;
name: string;
trait_type: string;
description: string;
instruction: string;
tags: string[];
created_at: string;
updated_at: string;
};
export type CharacterArc = {
id: string;
name: string;
description: string;
summary: string;
created_at: string;
updated_at: string;
};
export type StoredFile = {
id: string;
thought_id?: string;