@happyvertical/smrt-personas 0.38.19 → 0.38.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/AGENTS.md +119 -7
  2. package/dist/__smrt-register__.d.ts +2 -0
  3. package/dist/__smrt-register__.d.ts.map +1 -0
  4. package/dist/agent-persona.d.ts +161 -0
  5. package/dist/agent-persona.d.ts.map +1 -0
  6. package/dist/directive-approval.d.ts +94 -0
  7. package/dist/directive-approval.d.ts.map +1 -0
  8. package/dist/directive-principal.d.ts +56 -0
  9. package/dist/directive-principal.d.ts.map +1 -0
  10. package/dist/directive-proposal.d.ts +103 -0
  11. package/dist/directive-proposal.d.ts.map +1 -0
  12. package/dist/feedback.d.ts +127 -0
  13. package/dist/feedback.d.ts.map +1 -0
  14. package/dist/index.d.ts +11 -294
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +829 -19
  17. package/dist/index.js.map +1 -1
  18. package/dist/manifest.json +919 -3
  19. package/dist/persona-instance.d.ts +249 -0
  20. package/dist/persona-instance.d.ts.map +1 -0
  21. package/dist/persona-memory.d.ts +45 -0
  22. package/dist/persona-memory.d.ts.map +1 -0
  23. package/dist/persona-prompt.d.ts +77 -0
  24. package/dist/persona-prompt.d.ts.map +1 -0
  25. package/dist/persona-resolver.d.ts +134 -0
  26. package/dist/persona-resolver.d.ts.map +1 -0
  27. package/dist/reflection-runner.d.ts +113 -0
  28. package/dist/reflection-runner.d.ts.map +1 -0
  29. package/dist/smrt-knowledge.json +519 -11
  30. package/dist/svelte/components/DirectiveReviewQueue.svelte +185 -0
  31. package/dist/svelte/components/DirectiveReviewQueue.svelte.d.ts +15 -0
  32. package/dist/svelte/components/DirectiveReviewQueue.svelte.d.ts.map +1 -0
  33. package/dist/svelte/index.d.ts +16 -0
  34. package/dist/svelte/index.d.ts.map +1 -0
  35. package/dist/svelte/index.js +13 -0
  36. package/dist/svelte/types.d.ts +46 -0
  37. package/dist/svelte/types.d.ts.map +1 -0
  38. package/dist/svelte/types.js +39 -0
  39. package/package.json +23 -7
package/dist/index.js CHANGED
@@ -1,15 +1,51 @@
1
- import { ObjectRegistry, SmrtCollection, SmrtObject, crossPackageRef, field, getClassName, smrt } from "@happyvertical/smrt-core";
1
+ import { LearningMemory, ObjectRegistry, SmrtCollection, SmrtObject, crossPackageRef, field, foreignKey, getClassName, smrt } from "@happyvertical/smrt-core";
2
+ import { registerPermissionDefinitions } from "@happyvertical/smrt-users";
2
3
  import { TenantScoped, tenantId } from "@happyvertical/smrt-tenancy";
4
+ import { PromptOverrideCollection, PromptRegistry, definePrompt, resolvePrompt } from "@happyvertical/smrt-prompts";
5
+ import { instanceScopedSubscriber } from "@happyvertical/smrt-agents";
3
6
  //#region src/__smrt-register__.ts
4
- ObjectRegistry.registerPackageManifest(JSON.parse("{\"version\":\"1.0.0\",\"timestamp\":1783562557011,\"packageName\":\"@happyvertical/smrt-personas\",\"packageVersion\":\"0.38.19\",\"objects\":{\"@happyvertical/smrt-personas:AgentPersona\":{\"name\":\"agentpersona\",\"className\":\"AgentPersona\",\"qualifiedName\":\"@happyvertical/smrt-personas:AgentPersona\",\"collection\":\"agentpersonas\",\"filePath\":\"/home/runner/_work/smrt/smrt/packages/personas/src/agent-persona.ts\",\"packageName\":\"@happyvertical/smrt-personas\",\"fields\":{\"tenantId\":{\"type\":\"text\",\"required\":true,\"_meta\":{\"sqlType\":\"UUID\",\"__tenancy\":{\"isTenantIdField\":true,\"autoFilter\":true,\"required\":true,\"autoPopulate\":true,\"nullable\":false,\"mode\":\"required\",\"field\":\"tenantId\",\"allowSuperAdminBypass\":false}}},\"agentClass\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"name\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"contextType\":{\"type\":\"text\",\"required\":false,\"_meta\":{\"nullable\":true}},\"contextId\":{\"type\":\"text\",\"required\":false,\"_meta\":{\"nullable\":true}},\"instructions\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"allowedTools\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"runAsUserId\":{\"type\":\"crossPackageRef\",\"required\":true,\"related\":\"@happyvertical/smrt-users:User\"},\"actsAsProfileId\":{\"type\":\"crossPackageRef\",\"required\":false,\"related\":\"@happyvertical/smrt-profiles:Profile\",\"_meta\":{\"nullable\":true}},\"memoryScope\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"priority\":{\"type\":\"integer\",\"required\":false,\"default\":0},\"enabled\":{\"type\":\"boolean\",\"required\":false,\"_meta\":{}}},\"methods\":{\"getAllowedTools\":{\"name\":\"getAllowedTools\",\"async\":false,\"parameters\":[],\"returnType\":\"string[]\",\"isStatic\":false,\"isPublic\":true},\"setAllowedTools\":{\"name\":\"setAllowedTools\",\"async\":false,\"parameters\":[{\"name\":\"tools\",\"type\":\"string[]\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"agent_personas\",\"api\":{\"include\":[\"list\",\"get\",\"create\",\"update\",\"delete\"]},\"cli\":{\"include\":[\"list\",\"get\"]},\"mcp\":{\"include\":[\"list\",\"get\"]},\"conflictColumns\":[\"tenant_id\",\"agent_class\",\"name\"],\"tenantScoped\":{\"mode\":\"required\"}},\"extends\":\"SmrtObject\",\"exportName\":\"AgentPersona\",\"collectionExportName\":\"AgentPersonaCollection\",\"validationRules\":[{\"field\":\"tenantId\",\"rule\":\"required\",\"fieldType\":\"text\"},{\"field\":\"runAsUserId\",\"rule\":\"required\",\"fieldType\":\"crossPackageRef\"}],\"schema\":{\"tableName\":\"agent_personas\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"agent_personas\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"tenant_id\\\" UUID NOT NULL,\\n \\\"agent_class\\\" TEXT,\\n \\\"name\\\" TEXT DEFAULT '',\\n \\\"context_type\\\" TEXT,\\n \\\"context_id\\\" TEXT,\\n \\\"instructions\\\" TEXT,\\n \\\"allowed_tools\\\" TEXT,\\n \\\"run_as_user_id\\\" UUID NOT NULL,\\n \\\"acts_as_profile_id\\\" UUID,\\n \\\"memory_scope\\\" TEXT,\\n \\\"priority\\\" INTEGER DEFAULT 0,\\n \\\"enabled\\\" BOOLEAN\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"tenantId\",\"notNull\":true,\"unique\":false},\"agent_class\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"context_type\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"context_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"instructions\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"allowed_tools\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"run_as_user_id\":{\"type\":\"UUID\",\"referenceKind\":\"crossPackageRef\",\"notNull\":true,\"unique\":false},\"acts_as_profile_id\":{\"type\":\"UUID\",\"referenceKind\":\"crossPackageRef\",\"notNull\":false,\"unique\":false},\"memory_scope\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"priority\":{\"type\":\"INTEGER\",\"notNull\":false,\"unique\":false,\"default\":0},\"enabled\":{\"type\":\"BOOLEAN\",\"notNull\":false,\"unique\":false}},\"indexes\":[{\"name\":\"agent_personas_id_idx\",\"columns\":[\"id\"]},{\"name\":\"agent_personas_tenant_id_agent_class_idx\",\"columns\":[\"tenant_id\",\"agent_class\",\"name\"],\"unique\":true}],\"version\":\"71e955ef\"}},\"@happyvertical/smrt-personas:AgentPersonaCollection\":{\"name\":\"agentpersonacollection\",\"className\":\"AgentPersonaCollection\",\"qualifiedName\":\"@happyvertical/smrt-personas:AgentPersonaCollection\",\"collection\":\"agentpersonas\",\"filePath\":\"/home/runner/_work/smrt/smrt/packages/personas/src/agent-persona.ts\",\"packageName\":\"@happyvertical/smrt-personas\",\"fields\":{},\"methods\":{\"byTenantAndClass\":{\"name\":\"byTenantAndClass\",\"async\":true,\"parameters\":[{\"name\":\"tenantId\",\"type\":\"string\",\"optional\":false},{\"name\":\"agentClass\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<AgentPersona[]>\",\"isStatic\":false,\"isPublic\":true},\"findActive\":{\"name\":\"findActive\",\"async\":true,\"parameters\":[{\"name\":\"tenantId\",\"type\":\"string\",\"optional\":false},{\"name\":\"agentClass\",\"type\":\"string\",\"optional\":false},{\"name\":\"context\",\"type\":\"object\",\"optional\":true}],\"returnType\":\"Promise<AgentPersona[]>\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"agent_personas\"},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"AgentPersona\",\"exportName\":\"AgentPersonaCollection\",\"collectionExportName\":\"AgentPersonaCollectionCollection\",\"schema\":{\"tableName\":\"agent_personas\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"agent_personas\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"}},\"indexes\":[{\"name\":\"agent_personas_id_idx\",\"columns\":[\"id\"]},{\"name\":\"agent_personas_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"48e54c2f\"}}},\"moduleType\":\"smrt\",\"smrtDependencies\":[\"@happyvertical/smrt-agents\",\"@happyvertical/smrt-core\",\"@happyvertical/smrt-tenancy\"]}"));
7
+ ObjectRegistry.registerPackageManifest(JSON.parse("{\"version\":\"1.0.0\",\"timestamp\":1783580645734,\"packageName\":\"@happyvertical/smrt-personas\",\"packageVersion\":\"0.38.21\",\"objects\":{\"@happyvertical/smrt-personas:AgentPersona\":{\"name\":\"agentpersona\",\"className\":\"AgentPersona\",\"qualifiedName\":\"@happyvertical/smrt-personas:AgentPersona\",\"collection\":\"agentpersonas\",\"filePath\":\"/home/runner/_work/smrt/smrt/packages/personas/src/agent-persona.ts\",\"packageName\":\"@happyvertical/smrt-personas\",\"fields\":{\"tenantId\":{\"type\":\"text\",\"required\":true,\"_meta\":{\"sqlType\":\"UUID\",\"__tenancy\":{\"isTenantIdField\":true,\"autoFilter\":true,\"required\":true,\"autoPopulate\":true,\"nullable\":false,\"mode\":\"required\",\"field\":\"tenantId\",\"allowSuperAdminBypass\":false}}},\"agentClass\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"name\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"contextType\":{\"type\":\"text\",\"required\":false,\"_meta\":{\"nullable\":true}},\"contextId\":{\"type\":\"text\",\"required\":false,\"_meta\":{\"nullable\":true}},\"instructions\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"allowedTools\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"runAsUserId\":{\"type\":\"crossPackageRef\",\"required\":true,\"related\":\"@happyvertical/smrt-users:User\"},\"actsAsProfileId\":{\"type\":\"crossPackageRef\",\"required\":false,\"related\":\"@happyvertical/smrt-profiles:Profile\",\"_meta\":{\"nullable\":true}},\"memoryScope\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"priority\":{\"type\":\"integer\",\"required\":false,\"default\":0},\"enabled\":{\"type\":\"boolean\",\"required\":false,\"_meta\":{}}},\"methods\":{\"getAllowedTools\":{\"name\":\"getAllowedTools\",\"async\":false,\"parameters\":[],\"returnType\":\"string[]\",\"isStatic\":false,\"isPublic\":true},\"setAllowedTools\":{\"name\":\"setAllowedTools\",\"async\":false,\"parameters\":[{\"name\":\"tools\",\"type\":\"string[]\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"agent_personas\",\"api\":{\"include\":[\"list\",\"get\",\"create\",\"update\",\"delete\"]},\"cli\":{\"include\":[\"list\",\"get\"]},\"mcp\":{\"include\":[\"list\",\"get\"]},\"conflictColumns\":[\"tenant_id\",\"agent_class\",\"name\"],\"tenantScoped\":{\"mode\":\"required\"}},\"extends\":\"SmrtObject\",\"exportName\":\"AgentPersona\",\"collectionExportName\":\"AgentPersonaCollection\",\"validationRules\":[{\"field\":\"tenantId\",\"rule\":\"required\",\"fieldType\":\"text\"},{\"field\":\"runAsUserId\",\"rule\":\"required\",\"fieldType\":\"crossPackageRef\"}],\"schema\":{\"tableName\":\"agent_personas\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"agent_personas\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"tenant_id\\\" UUID NOT NULL,\\n \\\"agent_class\\\" TEXT,\\n \\\"name\\\" TEXT DEFAULT '',\\n \\\"context_type\\\" TEXT,\\n \\\"context_id\\\" TEXT,\\n \\\"instructions\\\" TEXT,\\n \\\"allowed_tools\\\" TEXT,\\n \\\"run_as_user_id\\\" UUID NOT NULL,\\n \\\"acts_as_profile_id\\\" UUID,\\n \\\"memory_scope\\\" TEXT,\\n \\\"priority\\\" INTEGER DEFAULT 0,\\n \\\"enabled\\\" BOOLEAN\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"tenantId\",\"notNull\":true,\"unique\":false},\"agent_class\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"context_type\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"context_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"instructions\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"allowed_tools\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"run_as_user_id\":{\"type\":\"UUID\",\"referenceKind\":\"crossPackageRef\",\"notNull\":true,\"unique\":false},\"acts_as_profile_id\":{\"type\":\"UUID\",\"referenceKind\":\"crossPackageRef\",\"notNull\":false,\"unique\":false},\"memory_scope\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"priority\":{\"type\":\"INTEGER\",\"notNull\":false,\"unique\":false,\"default\":0},\"enabled\":{\"type\":\"BOOLEAN\",\"notNull\":false,\"unique\":false}},\"indexes\":[{\"name\":\"agent_personas_id_idx\",\"columns\":[\"id\"]},{\"name\":\"agent_personas_tenant_id_agent_class_idx\",\"columns\":[\"tenant_id\",\"agent_class\",\"name\"],\"unique\":true}],\"version\":\"71e955ef\"}},\"@happyvertical/smrt-personas:AgentPersonaCollection\":{\"name\":\"agentpersonacollection\",\"className\":\"AgentPersonaCollection\",\"qualifiedName\":\"@happyvertical/smrt-personas:AgentPersonaCollection\",\"collection\":\"agentpersonas\",\"filePath\":\"/home/runner/_work/smrt/smrt/packages/personas/src/agent-persona.ts\",\"packageName\":\"@happyvertical/smrt-personas\",\"fields\":{},\"methods\":{\"byTenantAndClass\":{\"name\":\"byTenantAndClass\",\"async\":true,\"parameters\":[{\"name\":\"tenantId\",\"type\":\"string\",\"optional\":false},{\"name\":\"agentClass\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<AgentPersona[]>\",\"isStatic\":false,\"isPublic\":true},\"findActive\":{\"name\":\"findActive\",\"async\":true,\"parameters\":[{\"name\":\"tenantId\",\"type\":\"string\",\"optional\":false},{\"name\":\"agentClass\",\"type\":\"string\",\"optional\":false},{\"name\":\"context\",\"type\":\"object\",\"optional\":true}],\"returnType\":\"Promise<AgentPersona[]>\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"agent_personas\"},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"AgentPersona\",\"exportName\":\"AgentPersonaCollection\",\"collectionExportName\":\"AgentPersonaCollectionCollection\",\"schema\":{\"tableName\":\"agent_personas\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"agent_personas\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"}},\"indexes\":[{\"name\":\"agent_personas_id_idx\",\"columns\":[\"id\"]},{\"name\":\"agent_personas_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"48e54c2f\"}},\"@happyvertical/smrt-personas:DirectiveProposal\":{\"name\":\"directiveproposal\",\"className\":\"DirectiveProposal\",\"qualifiedName\":\"@happyvertical/smrt-personas:DirectiveProposal\",\"collection\":\"directiveproposals\",\"filePath\":\"/home/runner/_work/smrt/smrt/packages/personas/src/directive-proposal.ts\",\"packageName\":\"@happyvertical/smrt-personas\",\"fields\":{\"tenantId\":{\"type\":\"text\",\"required\":true,\"_meta\":{\"sqlType\":\"UUID\",\"__tenancy\":{\"isTenantIdField\":true,\"autoFilter\":true,\"required\":true,\"autoPopulate\":true,\"nullable\":false,\"mode\":\"required\",\"field\":\"tenantId\",\"allowSuperAdminBypass\":false}}},\"personaId\":{\"type\":\"foreignKey\",\"required\":true,\"related\":\"AgentPersona\",\"_meta\":{\"required\":true}},\"agentClass\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"promptKey\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"proposedInstructions\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"currentInstructions\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"rationale\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"evidence\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"status\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"fingerprint\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"confidence\":{\"type\":\"decimal\",\"required\":false,\"default\":0},\"proposedBy\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"reviewedBy\":{\"type\":\"text\",\"required\":false,\"_meta\":{\"nullable\":true}},\"reviewedAt\":{\"type\":\"datetime\",\"required\":false,\"_meta\":{\"nullable\":true}},\"reviewNote\":{\"type\":\"text\",\"required\":false,\"_meta\":{\"nullable\":true}},\"activatedOverrideId\":{\"type\":\"text\",\"required\":false,\"_meta\":{\"nullable\":true}}},\"methods\":{\"getEvidence\":{\"name\":\"getEvidence\",\"async\":false,\"parameters\":[],\"returnType\":\"DirectiveEvidence\",\"isStatic\":false,\"isPublic\":true},\"setEvidence\":{\"name\":\"setEvidence\",\"async\":false,\"parameters\":[{\"name\":\"value\",\"type\":\"DirectiveEvidence\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true},\"isPending\":{\"name\":\"isPending\",\"async\":false,\"parameters\":[],\"returnType\":\"boolean\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"directive_proposals\",\"api\":{\"include\":[\"list\",\"get\"]},\"cli\":{\"include\":[\"list\",\"get\"]},\"mcp\":{\"include\":[\"list\",\"get\"]},\"tenantScoped\":{\"mode\":\"required\"}},\"extends\":\"SmrtObject\",\"exportName\":\"DirectiveProposal\",\"collectionExportName\":\"DirectiveProposalCollection\",\"validationRules\":[{\"field\":\"tenantId\",\"rule\":\"required\",\"fieldType\":\"text\"},{\"field\":\"personaId\",\"rule\":\"required\",\"fieldType\":\"foreignKey\"}],\"schema\":{\"tableName\":\"directive_proposals\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"directive_proposals\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"tenant_id\\\" UUID NOT NULL,\\n \\\"persona_id\\\" UUID NOT NULL,\\n \\\"agent_class\\\" TEXT,\\n \\\"prompt_key\\\" TEXT,\\n \\\"proposed_instructions\\\" TEXT,\\n \\\"current_instructions\\\" TEXT,\\n \\\"rationale\\\" TEXT,\\n \\\"evidence\\\" TEXT,\\n \\\"status\\\" TEXT,\\n \\\"fingerprint\\\" TEXT,\\n \\\"confidence\\\" REAL DEFAULT 0,\\n \\\"proposed_by\\\" TEXT,\\n \\\"reviewed_by\\\" TEXT,\\n \\\"reviewed_at\\\" TIMESTAMP,\\n \\\"review_note\\\" TEXT,\\n \\\"activated_override_id\\\" TEXT\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"tenantId\",\"notNull\":true,\"unique\":false},\"persona_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":true,\"unique\":false},\"agent_class\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"prompt_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"proposed_instructions\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"current_instructions\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"rationale\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"evidence\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"status\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"fingerprint\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"confidence\":{\"type\":\"REAL\",\"notNull\":false,\"unique\":false,\"default\":0},\"proposed_by\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"reviewed_by\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"reviewed_at\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"review_note\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"activated_override_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false}},\"indexes\":[{\"name\":\"directive_proposals_id_idx\",\"columns\":[\"id\"]},{\"name\":\"directive_proposals_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"4bd9414b\"}},\"@happyvertical/smrt-personas:DirectiveProposalCollection\":{\"name\":\"directiveproposalcollection\",\"className\":\"DirectiveProposalCollection\",\"qualifiedName\":\"@happyvertical/smrt-personas:DirectiveProposalCollection\",\"collection\":\"directiveproposals\",\"filePath\":\"/home/runner/_work/smrt/smrt/packages/personas/src/directive-proposal.ts\",\"packageName\":\"@happyvertical/smrt-personas\",\"fields\":{},\"methods\":{\"pending\":{\"name\":\"pending\",\"async\":true,\"parameters\":[{\"name\":\"options\",\"type\":\"object\",\"optional\":true}],\"returnType\":\"Promise<DirectiveProposal[]>\",\"isStatic\":false,\"isPublic\":true},\"findByFingerprint\":{\"name\":\"findByFingerprint\",\"async\":true,\"parameters\":[{\"name\":\"personaId\",\"type\":\"string\",\"optional\":false},{\"name\":\"fingerprint\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<DirectiveProposal[]>\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"directive_proposals\"},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"DirectiveProposal\",\"exportName\":\"DirectiveProposalCollection\",\"collectionExportName\":\"DirectiveProposalCollectionCollection\",\"schema\":{\"tableName\":\"directive_proposals\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"directive_proposals\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"}},\"indexes\":[{\"name\":\"directive_proposals_id_idx\",\"columns\":[\"id\"]},{\"name\":\"directive_proposals_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"f9669b44\"}},\"@happyvertical/smrt-personas:Feedback\":{\"name\":\"feedback\",\"className\":\"Feedback\",\"qualifiedName\":\"@happyvertical/smrt-personas:Feedback\",\"collection\":\"feedbacks\",\"filePath\":\"/home/runner/_work/smrt/smrt/packages/personas/src/feedback.ts\",\"packageName\":\"@happyvertical/smrt-personas\",\"fields\":{\"tenantId\":{\"type\":\"text\",\"required\":false,\"_meta\":{\"sqlType\":\"UUID\",\"nullable\":true,\"__tenancy\":{\"isTenantIdField\":true,\"autoFilter\":true,\"required\":false,\"autoPopulate\":true,\"nullable\":true,\"mode\":\"optional\",\"field\":\"tenantId\",\"allowSuperAdminBypass\":false}}},\"personaId\":{\"type\":\"foreignKey\",\"required\":true,\"related\":\"AgentPersona\",\"_meta\":{\"required\":true}},\"agentClass\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"memoryScope\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"scope\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"key\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"signalType\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"source\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"correlationId\":{\"type\":\"text\",\"required\":true,\"_meta\":{\"required\":true}},\"correlationType\":{\"type\":\"text\",\"required\":false,\"_meta\":{\"nullable\":true}},\"rating\":{\"type\":\"decimal\",\"required\":false,\"_meta\":{\"nullable\":true}},\"metric\":{\"type\":\"decimal\",\"required\":false,\"_meta\":{\"nullable\":true}},\"success\":{\"type\":\"boolean\",\"required\":false,\"_meta\":{\"nullable\":true}},\"correction\":{\"type\":\"text\",\"required\":false,\"_meta\":{\"nullable\":true}},\"comment\":{\"type\":\"text\",\"required\":false,\"_meta\":{\"nullable\":true}},\"actorId\":{\"type\":\"text\",\"required\":false,\"_meta\":{\"nullable\":true}},\"metadata\":{\"type\":\"text\",\"required\":false,\"_meta\":{}},\"reinforcedAt\":{\"type\":\"datetime\",\"required\":false,\"_meta\":{\"nullable\":true}}},\"methods\":{\"isHuman\":{\"name\":\"isHuman\",\"async\":false,\"parameters\":[],\"returnType\":\"boolean\",\"isStatic\":false,\"isPublic\":true},\"getMetadata\":{\"name\":\"getMetadata\",\"async\":false,\"parameters\":[],\"returnType\":\"Record<string>\",\"isStatic\":false,\"isPublic\":true},\"setMetadata\":{\"name\":\"setMetadata\",\"async\":false,\"parameters\":[{\"name\":\"value\",\"type\":\"Record<string>\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true},\"updateMetadata\":{\"name\":\"updateMetadata\",\"async\":false,\"parameters\":[{\"name\":\"patch\",\"type\":\"Record<string>\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true},\"getCorrectionValue\":{\"name\":\"getCorrectionValue\",\"async\":false,\"parameters\":[],\"returnType\":\"string | undefined\",\"isStatic\":false,\"isPublic\":true},\"toLearningOutcome\":{\"name\":\"toLearningOutcome\",\"async\":false,\"parameters\":[{\"name\":\"options\",\"type\":\"FeedbackOutcomeOptions\",\"optional\":true}],\"returnType\":\"LearningOutcome | null\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"agent_feedback\",\"api\":{\"include\":[\"list\",\"get\",\"create\"]},\"cli\":{\"include\":[\"list\",\"get\"]},\"mcp\":{\"include\":[\"list\",\"get\"]},\"tenantScoped\":{\"mode\":\"optional\"}},\"extends\":\"SmrtObject\",\"exportName\":\"Feedback\",\"collectionExportName\":\"FeedbackCollection\",\"validationRules\":[{\"field\":\"personaId\",\"rule\":\"required\",\"fieldType\":\"foreignKey\"},{\"field\":\"correlationId\",\"rule\":\"required\",\"fieldType\":\"text\"}],\"schema\":{\"tableName\":\"agent_feedback\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"agent_feedback\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"tenant_id\\\" UUID,\\n \\\"persona_id\\\" UUID NOT NULL,\\n \\\"agent_class\\\" TEXT,\\n \\\"memory_scope\\\" TEXT,\\n \\\"scope\\\" TEXT,\\n \\\"key\\\" TEXT,\\n \\\"signal_type\\\" TEXT,\\n \\\"source\\\" TEXT,\\n \\\"correlation_id\\\" TEXT NOT NULL,\\n \\\"correlation_type\\\" TEXT,\\n \\\"rating\\\" REAL,\\n \\\"metric\\\" REAL,\\n \\\"success\\\" BOOLEAN,\\n \\\"correction\\\" TEXT,\\n \\\"comment\\\" TEXT,\\n \\\"actor_id\\\" TEXT,\\n \\\"metadata\\\" TEXT,\\n \\\"reinforced_at\\\" TIMESTAMP\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"tenantId\",\"notNull\":false,\"unique\":false},\"persona_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":true,\"unique\":false},\"agent_class\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"memory_scope\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"scope\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"signal_type\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"source\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"correlation_id\":{\"type\":\"TEXT\",\"notNull\":true,\"unique\":false},\"correlation_type\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"rating\":{\"type\":\"REAL\",\"notNull\":false,\"unique\":false},\"metric\":{\"type\":\"REAL\",\"notNull\":false,\"unique\":false},\"success\":{\"type\":\"BOOLEAN\",\"notNull\":false,\"unique\":false},\"correction\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"comment\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"actor_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"metadata\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"reinforced_at\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false}},\"indexes\":[{\"name\":\"agent_feedback_id_idx\",\"columns\":[\"id\"]},{\"name\":\"agent_feedback_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"65f8e99e\"}},\"@happyvertical/smrt-personas:FeedbackCollection\":{\"name\":\"feedbackcollection\",\"className\":\"FeedbackCollection\",\"qualifiedName\":\"@happyvertical/smrt-personas:FeedbackCollection\",\"collection\":\"feedbacks\",\"filePath\":\"/home/runner/_work/smrt/smrt/packages/personas/src/feedback.ts\",\"packageName\":\"@happyvertical/smrt-personas\",\"fields\":{},\"methods\":{\"forPersona\":{\"name\":\"forPersona\",\"async\":true,\"parameters\":[{\"name\":\"personaId\",\"type\":\"string\",\"optional\":false},{\"name\":\"options\",\"type\":\"object\",\"optional\":true}],\"returnType\":\"Promise<Feedback[]>\",\"isStatic\":false,\"isPublic\":true},\"forScope\":{\"name\":\"forScope\",\"async\":true,\"parameters\":[{\"name\":\"memoryScope\",\"type\":\"string\",\"optional\":false},{\"name\":\"options\",\"type\":\"object\",\"optional\":true}],\"returnType\":\"Promise<Feedback[]>\",\"isStatic\":false,\"isPublic\":true},\"byCorrelation\":{\"name\":\"byCorrelation\",\"async\":true,\"parameters\":[{\"name\":\"correlationId\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<Feedback[]>\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"agent_feedback\"},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"Feedback\",\"exportName\":\"FeedbackCollection\",\"collectionExportName\":\"FeedbackCollectionCollection\",\"schema\":{\"tableName\":\"agent_feedback\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"agent_feedback\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"}},\"indexes\":[{\"name\":\"agent_feedback_id_idx\",\"columns\":[\"id\"]},{\"name\":\"agent_feedback_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"c8bb487d\"}}},\"moduleType\":\"smrt\",\"smrtDependencies\":[\"@happyvertical/smrt-agents\",\"@happyvertical/smrt-core\",\"@happyvertical/smrt-prompts\",\"@happyvertical/smrt-tenancy\",\"@happyvertical/smrt-users\"]}"));
8
+ //#endregion
9
+ //#region src/directive-principal.ts
10
+ var ACTIVATE_DIRECTIVE_PERMISSION = "personas.activate-directive";
11
+ var DIRECTIVE_ACTIVATION_PERMISSION_DEF = {
12
+ slug: ACTIVATE_DIRECTIVE_PERMISSION,
13
+ category: "personas",
14
+ name: "Activate Persona Directive",
15
+ description: "Approve, edit, or reject a proposed edit to a persona's instructions and activate the persona-scoped prompt override"
16
+ };
17
+ function principalFromPermissions(permissions, options = {}) {
18
+ const granted = new Set(permissions);
19
+ return {
20
+ id: options.id,
21
+ tenantId: options.tenantId,
22
+ can: (slug) => granted.has(slug)
23
+ };
24
+ }
25
+ async function resolveDirectivePrincipal(options) {
26
+ const { permissions } = await options.resolver.resolvePermissions(options.userId, options.tenantId);
27
+ return principalFromPermissions(permissions, {
28
+ id: options.userId,
29
+ tenantId: options.tenantId
30
+ });
31
+ }
32
+ var personaPermissionsRegistered = false;
33
+ function registerPersonaPermissions() {
34
+ return registerPermissionDefinitions([DIRECTIVE_ACTIVATION_PERMISSION_DEF]);
35
+ }
36
+ function ensurePersonaPermissionsRegistered() {
37
+ if (personaPermissionsRegistered) return;
38
+ personaPermissionsRegistered = true;
39
+ registerPersonaPermissions();
40
+ }
5
41
  //#endregion
6
42
  //#region src/agent-persona.ts
7
- var __defProp = Object.defineProperty;
8
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
- var __decorateClass = (decorators, target, key, kind) => {
10
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
43
+ var __defProp$2 = Object.defineProperty;
44
+ var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
45
+ var __decorateClass$2 = (decorators, target, key, kind) => {
46
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
11
47
  for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
12
- if (kind && result) __defProp(target, key, result);
48
+ if (kind && result) __defProp$2(target, key, result);
13
49
  return result;
14
50
  };
15
51
  function canonicalAgentClass(name) {
@@ -68,23 +104,23 @@ var AgentPersona = class extends SmrtObject {
68
104
  this.allowedTools = JSON.stringify(tools ?? []);
69
105
  }
70
106
  };
71
- __decorateClass([tenantId()], AgentPersona.prototype, "tenantId", 2);
72
- __decorateClass([field({ type: "text" })], AgentPersona.prototype, "agentClass", 2);
73
- __decorateClass([field({
107
+ __decorateClass$2([tenantId()], AgentPersona.prototype, "tenantId", 2);
108
+ __decorateClass$2([field({ type: "text" })], AgentPersona.prototype, "agentClass", 2);
109
+ __decorateClass$2([field({
74
110
  type: "text",
75
111
  nullable: true
76
112
  })], AgentPersona.prototype, "contextType", 2);
77
- __decorateClass([field({
113
+ __decorateClass$2([field({
78
114
  type: "text",
79
115
  nullable: true
80
116
  })], AgentPersona.prototype, "contextId", 2);
81
- __decorateClass([field({ type: "text" })], AgentPersona.prototype, "instructions", 2);
82
- __decorateClass([field({ type: "text" })], AgentPersona.prototype, "allowedTools", 2);
83
- __decorateClass([crossPackageRef("@happyvertical/smrt-users:User", { required: true })], AgentPersona.prototype, "runAsUserId", 2);
84
- __decorateClass([crossPackageRef("@happyvertical/smrt-profiles:Profile", { nullable: true })], AgentPersona.prototype, "actsAsProfileId", 2);
85
- __decorateClass([field({ type: "text" })], AgentPersona.prototype, "memoryScope", 2);
86
- __decorateClass([field({ type: "boolean" })], AgentPersona.prototype, "enabled", 2);
87
- AgentPersona = __decorateClass([TenantScoped({ mode: "required" }), smrt({
117
+ __decorateClass$2([field({ type: "text" })], AgentPersona.prototype, "instructions", 2);
118
+ __decorateClass$2([field({ type: "text" })], AgentPersona.prototype, "allowedTools", 2);
119
+ __decorateClass$2([crossPackageRef("@happyvertical/smrt-users:User", { required: true })], AgentPersona.prototype, "runAsUserId", 2);
120
+ __decorateClass$2([crossPackageRef("@happyvertical/smrt-profiles:Profile", { nullable: true })], AgentPersona.prototype, "actsAsProfileId", 2);
121
+ __decorateClass$2([field({ type: "text" })], AgentPersona.prototype, "memoryScope", 2);
122
+ __decorateClass$2([field({ type: "boolean" })], AgentPersona.prototype, "enabled", 2);
123
+ AgentPersona = __decorateClass$2([TenantScoped({ mode: "required" }), smrt({
88
124
  tableName: "agent_personas",
89
125
  api: { include: [
90
126
  "list",
@@ -167,6 +203,654 @@ function sortByPriorityThenName(personas) {
167
203
  });
168
204
  }
169
205
  //#endregion
206
+ //#region src/directive-proposal.ts
207
+ var __defProp$1 = Object.defineProperty;
208
+ var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
209
+ var __decorateClass$1 = (decorators, target, key, kind) => {
210
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
211
+ for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
212
+ if (kind && result) __defProp$1(target, key, result);
213
+ return result;
214
+ };
215
+ function computeDirectiveFingerprint(personaId, promptKey, proposedInstructions) {
216
+ const input = `${personaId} ${promptKey} ${proposedInstructions}`;
217
+ let hash = 2166136261;
218
+ for (let i = 0; i < input.length; i++) {
219
+ hash ^= input.charCodeAt(i);
220
+ hash = Math.imul(hash, 16777619) >>> 0;
221
+ }
222
+ return hash.toString(16).padStart(8, "0");
223
+ }
224
+ function parseEvidence(raw) {
225
+ if (typeof raw !== "string" || raw.length === 0) return raw && typeof raw === "object" ? raw : {};
226
+ try {
227
+ const parsed = JSON.parse(raw);
228
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
229
+ } catch {
230
+ return {};
231
+ }
232
+ }
233
+ var DirectiveProposal = class extends SmrtObject {
234
+ tenantId = "";
235
+ personaId = "";
236
+ agentClass = "";
237
+ promptKey = "";
238
+ proposedInstructions = "";
239
+ currentInstructions = "";
240
+ rationale = "";
241
+ evidence = "{}";
242
+ status = "pending";
243
+ fingerprint = "";
244
+ /** Aggregate confidence in the proposal, in `[0, 1]`. */
245
+ confidence = 0;
246
+ proposedBy = "";
247
+ reviewedBy = null;
248
+ reviewedAt = null;
249
+ reviewNote = null;
250
+ activatedOverrideId = null;
251
+ /** Parse {@link evidence}, tolerating malformed JSON. */
252
+ getEvidence() {
253
+ return parseEvidence(this.evidence);
254
+ }
255
+ /** Replace {@link evidence}. */
256
+ setEvidence(value) {
257
+ this.evidence = JSON.stringify(value ?? {});
258
+ }
259
+ /** Whether the proposal is still awaiting review. */
260
+ isPending() {
261
+ return this.status === "pending";
262
+ }
263
+ };
264
+ __decorateClass$1([tenantId()], DirectiveProposal.prototype, "tenantId", 2);
265
+ __decorateClass$1([foreignKey("AgentPersona", { required: true })], DirectiveProposal.prototype, "personaId", 2);
266
+ __decorateClass$1([field({ type: "text" })], DirectiveProposal.prototype, "agentClass", 2);
267
+ __decorateClass$1([field({ type: "text" })], DirectiveProposal.prototype, "promptKey", 2);
268
+ __decorateClass$1([field({ type: "text" })], DirectiveProposal.prototype, "proposedInstructions", 2);
269
+ __decorateClass$1([field({ type: "text" })], DirectiveProposal.prototype, "currentInstructions", 2);
270
+ __decorateClass$1([field({ type: "text" })], DirectiveProposal.prototype, "rationale", 2);
271
+ __decorateClass$1([field({ type: "text" })], DirectiveProposal.prototype, "evidence", 2);
272
+ __decorateClass$1([field({ type: "text" })], DirectiveProposal.prototype, "status", 2);
273
+ __decorateClass$1([field({ type: "text" })], DirectiveProposal.prototype, "fingerprint", 2);
274
+ __decorateClass$1([field({ type: "text" })], DirectiveProposal.prototype, "proposedBy", 2);
275
+ __decorateClass$1([field({
276
+ type: "text",
277
+ nullable: true
278
+ })], DirectiveProposal.prototype, "reviewedBy", 2);
279
+ __decorateClass$1([field({
280
+ type: "datetime",
281
+ nullable: true
282
+ })], DirectiveProposal.prototype, "reviewedAt", 2);
283
+ __decorateClass$1([field({
284
+ type: "text",
285
+ nullable: true
286
+ })], DirectiveProposal.prototype, "reviewNote", 2);
287
+ __decorateClass$1([field({
288
+ type: "text",
289
+ nullable: true
290
+ })], DirectiveProposal.prototype, "activatedOverrideId", 2);
291
+ DirectiveProposal = __decorateClass$1([TenantScoped({ mode: "required" }), smrt({
292
+ tableName: "directive_proposals",
293
+ api: { include: ["list", "get"] },
294
+ cli: { include: ["list", "get"] },
295
+ mcp: { include: ["list", "get"] }
296
+ })], DirectiveProposal);
297
+ var DirectiveProposalCollection = class extends SmrtCollection {
298
+ static _itemClass = DirectiveProposal;
299
+ /**
300
+ * The review queue: pending proposals, oldest first. Optionally scoped to a
301
+ * persona.
302
+ */
303
+ async pending(options = {}) {
304
+ const where = { status: "pending" };
305
+ if (options.personaId) where.personaId = options.personaId;
306
+ return this.list({
307
+ where,
308
+ orderBy: "created_at ASC",
309
+ limit: options.limit
310
+ });
311
+ }
312
+ /**
313
+ * Existing proposals for a persona carrying a given fingerprint, in any
314
+ * status — used to avoid re-surfacing an already-seen (e.g. rejected) rewrite.
315
+ */
316
+ async findByFingerprint(personaId, fingerprint) {
317
+ return this.list({ where: {
318
+ personaId,
319
+ fingerprint
320
+ } });
321
+ }
322
+ };
323
+ //#endregion
324
+ //#region src/feedback.ts
325
+ var __defProp = Object.defineProperty;
326
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
327
+ var __decorateClass = (decorators, target, key, kind) => {
328
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
329
+ for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
330
+ if (kind && result) __defProp(target, key, result);
331
+ return result;
332
+ };
333
+ var HUMAN_SIGNAL_TYPES = [
334
+ "accept",
335
+ "reject",
336
+ "correction",
337
+ "rating"
338
+ ];
339
+ function feedbackSourceFor(signal) {
340
+ return HUMAN_SIGNAL_TYPES.includes(signal) ? "human" : "autonomous";
341
+ }
342
+ function parseJsonObject(raw) {
343
+ if (typeof raw !== "string" || raw.length === 0) return raw && typeof raw === "object" ? raw : {};
344
+ try {
345
+ const parsed = JSON.parse(raw);
346
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
347
+ } catch {
348
+ return {};
349
+ }
350
+ }
351
+ var Feedback = class extends SmrtObject {
352
+ tenantId = null;
353
+ personaId = "";
354
+ agentClass = "";
355
+ memoryScope = "";
356
+ scope = "";
357
+ key = "";
358
+ signalType = "outcome";
359
+ source = "autonomous";
360
+ correlationId = "";
361
+ correlationType = null;
362
+ rating = null;
363
+ metric = null;
364
+ success = null;
365
+ correction = null;
366
+ comment = null;
367
+ actorId = null;
368
+ metadata = "{}";
369
+ reinforcedAt = null;
370
+ /** Whether this is a human-authored signal. */
371
+ isHuman() {
372
+ return this.source === "human";
373
+ }
374
+ /** Parse {@link metadata}, tolerating malformed JSON. */
375
+ getMetadata() {
376
+ return parseJsonObject(this.metadata);
377
+ }
378
+ /** Replace {@link metadata}. */
379
+ setMetadata(value) {
380
+ this.metadata = JSON.stringify(value ?? {});
381
+ }
382
+ /** Shallow-merge into {@link metadata}. */
383
+ updateMetadata(patch) {
384
+ this.setMetadata({
385
+ ...this.getMetadata(),
386
+ ...patch
387
+ });
388
+ }
389
+ /**
390
+ * The strategy value a `correction` signal should persist into memory, so a
391
+ * regenerated (corrected) strategy supersedes the one that was judged wrong.
392
+ * `undefined` for non-correction signals (reinforce confidence only).
393
+ */
394
+ getCorrectionValue() {
395
+ return this.signalType === "correction" && this.correction != null ? this.correction : void 0;
396
+ }
397
+ /**
398
+ * Map this signal onto a {@link LearningOutcome} for reinforcement, or `null`
399
+ * when the signal carries no reinforcement value:
400
+ *
401
+ * - `accept` → success; `reject` / `correction` → failure.
402
+ * - `outcome` → the recorded boolean `success`.
403
+ * - `metric` → the recorded `metric` (positive → success).
404
+ * - `rating` → `{ metric: rating - ratingNeutral }`.
405
+ */
406
+ toLearningOutcome(options = {}) {
407
+ switch (this.signalType) {
408
+ case "accept": return { success: true };
409
+ case "reject":
410
+ case "correction": return {
411
+ success: false,
412
+ error: this.comment ?? void 0
413
+ };
414
+ case "outcome": return this.success == null ? null : { success: this.success };
415
+ case "metric": return this.metric == null ? null : { metric: this.metric };
416
+ case "rating":
417
+ if (this.rating == null) return null;
418
+ return { metric: this.rating - (options.ratingNeutral ?? 0) };
419
+ default: return null;
420
+ }
421
+ }
422
+ };
423
+ __decorateClass([tenantId({ nullable: true })], Feedback.prototype, "tenantId", 2);
424
+ __decorateClass([foreignKey("AgentPersona", { required: true })], Feedback.prototype, "personaId", 2);
425
+ __decorateClass([field({ type: "text" })], Feedback.prototype, "agentClass", 2);
426
+ __decorateClass([field({ type: "text" })], Feedback.prototype, "memoryScope", 2);
427
+ __decorateClass([field({ type: "text" })], Feedback.prototype, "scope", 2);
428
+ __decorateClass([field({ type: "text" })], Feedback.prototype, "key", 2);
429
+ __decorateClass([field({ type: "text" })], Feedback.prototype, "signalType", 2);
430
+ __decorateClass([field({ type: "text" })], Feedback.prototype, "source", 2);
431
+ __decorateClass([field({
432
+ type: "text",
433
+ required: true
434
+ })], Feedback.prototype, "correlationId", 2);
435
+ __decorateClass([field({
436
+ type: "text",
437
+ nullable: true
438
+ })], Feedback.prototype, "correlationType", 2);
439
+ __decorateClass([field({
440
+ type: "decimal",
441
+ nullable: true
442
+ })], Feedback.prototype, "rating", 2);
443
+ __decorateClass([field({
444
+ type: "decimal",
445
+ nullable: true
446
+ })], Feedback.prototype, "metric", 2);
447
+ __decorateClass([field({
448
+ type: "boolean",
449
+ nullable: true
450
+ })], Feedback.prototype, "success", 2);
451
+ __decorateClass([field({
452
+ type: "text",
453
+ nullable: true
454
+ })], Feedback.prototype, "correction", 2);
455
+ __decorateClass([field({
456
+ type: "text",
457
+ nullable: true
458
+ })], Feedback.prototype, "comment", 2);
459
+ __decorateClass([field({
460
+ type: "text",
461
+ nullable: true
462
+ })], Feedback.prototype, "actorId", 2);
463
+ __decorateClass([field({ type: "text" })], Feedback.prototype, "metadata", 2);
464
+ __decorateClass([field({
465
+ type: "datetime",
466
+ nullable: true
467
+ })], Feedback.prototype, "reinforcedAt", 2);
468
+ Feedback = __decorateClass([TenantScoped({ mode: "optional" }), smrt({
469
+ tableName: "agent_feedback",
470
+ api: { include: [
471
+ "list",
472
+ "get",
473
+ "create"
474
+ ] },
475
+ cli: { include: ["list", "get"] },
476
+ mcp: { include: ["list", "get"] }
477
+ })], Feedback);
478
+ var FeedbackCollection = class extends SmrtCollection {
479
+ static _itemClass = Feedback;
480
+ /** All signals for a persona, newest first. */
481
+ async forPersona(personaId, options = {}) {
482
+ return this.list({
483
+ where: { personaId },
484
+ orderBy: "created_at DESC",
485
+ limit: options.limit
486
+ });
487
+ }
488
+ /** All signals filed under a memory scope, newest first. */
489
+ async forScope(memoryScope, options = {}) {
490
+ return this.list({
491
+ where: { memoryScope },
492
+ orderBy: "created_at DESC",
493
+ limit: options.limit
494
+ });
495
+ }
496
+ /** Every signal correlated to a given AI call / dispatch / job id. */
497
+ async byCorrelation(correlationId) {
498
+ return this.list({
499
+ where: { correlationId },
500
+ orderBy: "created_at DESC"
501
+ });
502
+ }
503
+ };
504
+ //#endregion
505
+ //#region src/persona-prompt.ts
506
+ function personaInstructionsPromptKey(persona) {
507
+ const id = persona.id;
508
+ if (!id) throw new Error("personaInstructionsPromptKey requires a persisted persona (missing id)");
509
+ return `persona.${id}.instructions`;
510
+ }
511
+ var DEFAULT_PERSONA_EDITABLE = {
512
+ template: true,
513
+ profile: false,
514
+ model: false,
515
+ params: false
516
+ };
517
+ function ensurePersonaInstructionsPrompt(persona, options = {}) {
518
+ const key = personaInstructionsPromptKey(persona);
519
+ const existing = PromptRegistry.get(key);
520
+ if (existing && options.editable === void 0) return existing;
521
+ return definePrompt({
522
+ key,
523
+ template: "",
524
+ editable: {
525
+ ...DEFAULT_PERSONA_EDITABLE,
526
+ ...options.editable ?? {}
527
+ }
528
+ });
529
+ }
530
+ async function upsertPromptTemplateOverride(options) {
531
+ const { db, key, tenantId, template } = options;
532
+ const overrides = await PromptOverrideCollection.create({ db });
533
+ const existing = tenantId != null ? await overrides.getTenantOverride(key, tenantId) : await overrides.getAppOverride(key);
534
+ if (existing) {
535
+ existing.template = template;
536
+ await existing.save();
537
+ return existing;
538
+ }
539
+ return overrides.create({
540
+ key,
541
+ tenantId,
542
+ template
543
+ });
544
+ }
545
+ async function applyPersonaInstructions(options) {
546
+ const { persona, db } = options;
547
+ ensurePersonaInstructionsPrompt(persona, { editable: options.editable });
548
+ return upsertPromptTemplateOverride({
549
+ db,
550
+ key: personaInstructionsPromptKey(persona),
551
+ tenantId: persona.tenantId ?? null,
552
+ template: options.instructions ?? persona.instructions ?? ""
553
+ });
554
+ }
555
+ async function resolvePersonaInstructions(options) {
556
+ const { persona, db } = options;
557
+ ensurePersonaInstructionsPrompt(persona);
558
+ return (await resolvePrompt(personaInstructionsPromptKey(persona), {
559
+ db,
560
+ tenantId: persona.tenantId ?? null,
561
+ variables: options.variables
562
+ })).text;
563
+ }
564
+ //#endregion
565
+ //#region src/directive-approval.ts
566
+ var DirectiveActivationDeniedError = class extends Error {
567
+ constructor(message = `Principal lacks the '${ACTIVATE_DIRECTIVE_PERMISSION}' permission required to review persona directives`) {
568
+ super(message);
569
+ this.name = "DirectiveActivationDeniedError";
570
+ }
571
+ };
572
+ var DirectiveNotPendingError = class extends Error {
573
+ constructor(status) {
574
+ super(`Directive proposal is not pending (status: ${status})`);
575
+ this.name = "DirectiveNotPendingError";
576
+ }
577
+ };
578
+ var DirectiveApprovalService = class {
579
+ db;
580
+ proposals;
581
+ feedback;
582
+ personas;
583
+ constructor(options) {
584
+ this.db = options.db;
585
+ this.proposals = options.proposals;
586
+ this.feedback = options.feedback;
587
+ this.personas = options.personas;
588
+ }
589
+ /**
590
+ * Assert a principal is authorised to review directives. The single gate:
591
+ * everything privileged in this service calls it first.
592
+ *
593
+ * @throws {DirectiveActivationDeniedError} when the principal lacks the slug.
594
+ */
595
+ assertCanActivate(principal) {
596
+ if (!principal.can("personas.activate-directive")) throw new DirectiveActivationDeniedError();
597
+ }
598
+ /**
599
+ * Assert a principal may review a specific proposal: its resolved tenant, when
600
+ * bound, must match the proposal's tenant. Permissions are resolved per
601
+ * tenant, so holding the slug in one tenant must not authorise activating
602
+ * another tenant's directive.
603
+ *
604
+ * @throws {DirectiveActivationDeniedError} on a cross-tenant attempt.
605
+ */
606
+ assertTenantMatch(principal, proposal) {
607
+ if (principal.tenantId !== void 0 && principal.tenantId !== proposal.tenantId) throw new DirectiveActivationDeniedError(`Principal (tenant '${principal.tenantId}') cannot review a directive for tenant '${proposal.tenantId}'`);
608
+ }
609
+ /**
610
+ * Approve a pending proposal: activate the persona-scoped override and record
611
+ * an `accept` signal. Pass `editedInstructions` to activate a revised text
612
+ * (the proposal keeps the model's original as its audit record; the override
613
+ * holds what was activated).
614
+ *
615
+ * @throws {DirectiveActivationDeniedError} when the principal lacks the slug.
616
+ * @throws {DirectiveNotPendingError} when the proposal is already reviewed.
617
+ */
618
+ async approve(ref, principal, options = {}) {
619
+ this.assertCanActivate(principal);
620
+ const proposal = await this.loadPending(ref);
621
+ this.assertTenantMatch(principal, proposal);
622
+ const template = options.editedInstructions ?? proposal.proposedInstructions;
623
+ const override = await upsertPromptTemplateOverride({
624
+ db: this.db,
625
+ key: proposal.promptKey,
626
+ tenantId: proposal.tenantId,
627
+ template
628
+ });
629
+ await this.syncPersonaInstructions(proposal.personaId, template);
630
+ proposal.status = "approved";
631
+ proposal.reviewedBy = principal.id ?? null;
632
+ proposal.reviewedAt = /* @__PURE__ */ new Date();
633
+ proposal.reviewNote = options.note ?? null;
634
+ proposal.activatedOverrideId = override.id ?? null;
635
+ await proposal.save();
636
+ return {
637
+ proposal,
638
+ override,
639
+ signal: await this.recordSignal(proposal, "accept", principal, {
640
+ note: options.note,
641
+ edited: options.editedInstructions !== void 0
642
+ })
643
+ };
644
+ }
645
+ /**
646
+ * Reject a pending proposal: record a `reject` signal and close it so it is
647
+ * never re-surfaced.
648
+ *
649
+ * @throws {DirectiveActivationDeniedError} when the principal lacks the slug.
650
+ * @throws {DirectiveNotPendingError} when the proposal is already reviewed.
651
+ */
652
+ async reject(ref, principal, options = {}) {
653
+ this.assertCanActivate(principal);
654
+ const proposal = await this.loadPending(ref);
655
+ this.assertTenantMatch(principal, proposal);
656
+ proposal.status = "rejected";
657
+ proposal.reviewedBy = principal.id ?? null;
658
+ proposal.reviewedAt = /* @__PURE__ */ new Date();
659
+ proposal.reviewNote = options.note ?? null;
660
+ await proposal.save();
661
+ return {
662
+ proposal,
663
+ signal: await this.recordSignal(proposal, "reject", principal, { note: options.note })
664
+ };
665
+ }
666
+ async loadPending(ref) {
667
+ const proposal = ref instanceof DirectiveProposal ? ref : await this.getProposal(ref);
668
+ if (!proposal) throw new Error(`Directive proposal not found: ${String(ref)}`);
669
+ if (proposal.status !== "pending") throw new DirectiveNotPendingError(proposal.status);
670
+ return proposal;
671
+ }
672
+ async getProposal(id) {
673
+ return (await this.proposalsCollection()).get({ id });
674
+ }
675
+ async recordSignal(proposal, signalType, principal, options = {}) {
676
+ return (await this.feedbackCollection()).create({
677
+ tenantId: proposal.tenantId,
678
+ personaId: proposal.personaId,
679
+ agentClass: proposal.agentClass,
680
+ memoryScope: "",
681
+ scope: "persona/directive",
682
+ key: proposal.id ?? "",
683
+ signalType,
684
+ source: "human",
685
+ correlationId: proposal.id ?? "",
686
+ correlationType: "directive_proposal",
687
+ actorId: principal.id ?? null,
688
+ comment: options.note ?? null,
689
+ metadata: JSON.stringify({ edited: options.edited ?? false })
690
+ });
691
+ }
692
+ async syncPersonaInstructions(personaId, instructions) {
693
+ const persona = await (await this.personasCollection()).get({ id: personaId });
694
+ if (!persona) return;
695
+ persona.instructions = instructions;
696
+ await persona.save();
697
+ }
698
+ async personasCollection() {
699
+ if (!this.personas) this.personas = await AgentPersonaCollection.create({ db: this.db });
700
+ return this.personas;
701
+ }
702
+ async proposalsCollection() {
703
+ if (!this.proposals) this.proposals = await DirectiveProposalCollection.create({ db: this.db });
704
+ return this.proposals;
705
+ }
706
+ async feedbackCollection() {
707
+ if (!this.feedback) this.feedback = await FeedbackCollection.create({ db: this.db });
708
+ return this.feedback;
709
+ }
710
+ };
711
+ //#endregion
712
+ //#region src/persona-memory.ts
713
+ function personaMemoryScope(persona) {
714
+ const explicit = persona.memoryScope?.trim();
715
+ if (explicit) return explicit;
716
+ if (persona.id) return `persona:${persona.id}`;
717
+ throw new Error("personaMemoryScope requires a persona with a memoryScope or an id");
718
+ }
719
+ function personaLearningMemory(options) {
720
+ const ownerClass = options.ownerClass ?? (options.persona.agentClass?.trim() || "AgentPersona");
721
+ return new LearningMemory({
722
+ db: options.db,
723
+ ownerClass,
724
+ ownerId: personaMemoryScope(options.persona),
725
+ tenantId: options.tenantId ?? options.persona.tenantId ?? null,
726
+ semanticSearch: options.semanticSearch,
727
+ config: options.config
728
+ });
729
+ }
730
+ async function reinforceFromFeedback(memory, feedback, options = {}) {
731
+ const outcome = feedback.toLearningOutcome(options);
732
+ if (!outcome) return null;
733
+ const value = feedback.getCorrectionValue();
734
+ return memory.capture({
735
+ scope: feedback.scope,
736
+ key: feedback.key,
737
+ ...value !== void 0 ? { value } : {}
738
+ }, outcome);
739
+ }
740
+ //#endregion
741
+ //#region src/persona-instance.ts
742
+ var DEFAULT_PERSONA_NAME = "default";
743
+ function personaInstanceKey(persona) {
744
+ if (persona.name === "default") return null;
745
+ if (!persona.id) throw new Error("personaInstanceKey: a non-default persona must be saved (have an id) before it can act as a durable instance");
746
+ return persona.id;
747
+ }
748
+ function isDefaultPersona(persona) {
749
+ return persona.name === DEFAULT_PERSONA_NAME;
750
+ }
751
+ function agentOptionsForPersona(persona) {
752
+ return {
753
+ instanceKey: personaInstanceKey(persona),
754
+ tenantId: persona.tenantId
755
+ };
756
+ }
757
+ async function schedulePersonaInstance(schedules, persona, options) {
758
+ const instanceKey = personaInstanceKey(persona);
759
+ const agentConfig = { ...options.agentConfig ?? {} };
760
+ if (instanceKey) agentConfig.instanceKey = instanceKey;
761
+ const schedule = await schedules.create({
762
+ tenantId: persona.tenantId,
763
+ agentType: persona.agentClass,
764
+ agentId: null,
765
+ cron: options.cron,
766
+ timezone: options.timezone ?? "UTC",
767
+ method: options.method ?? "run",
768
+ agentConfig,
769
+ methodArgs: options.methodArgs ?? {},
770
+ enabled: options.enabled ?? true
771
+ });
772
+ await schedule.save();
773
+ return schedule;
774
+ }
775
+ async function buildPersonaInstanceAdmin(personas, options) {
776
+ const canonical = canonicalAgentClass(options.agentClass);
777
+ const slots = options.manifest?.uiSlots ?? {};
778
+ const adminRoutes = options.manifest?.adminRoutes ?? [];
779
+ const instances = (await personas.byTenantAndClass(options.tenantId, canonical)).map((persona) => {
780
+ const instanceKey = personaInstanceKey(persona);
781
+ return {
782
+ personaId: persona.id,
783
+ name: persona.name,
784
+ instanceKey,
785
+ isDefault: isDefaultPersona(persona),
786
+ enabled: persona.enabled,
787
+ priority: persona.priority,
788
+ contextType: persona.contextType,
789
+ contextId: persona.contextId,
790
+ runAsUserId: persona.runAsUserId,
791
+ actsAsProfileId: persona.actsAsProfileId,
792
+ dispatchSubscriber: instanceScopedSubscriber(canonical, instanceKey),
793
+ slots,
794
+ adminRoutes
795
+ };
796
+ });
797
+ return {
798
+ agentClass: canonical,
799
+ tenantId: options.tenantId,
800
+ instances,
801
+ canAddInstance: true
802
+ };
803
+ }
804
+ async function addPersonaInstance(personas, options) {
805
+ const persona = await personas.create({
806
+ tenantId: options.tenantId,
807
+ agentClass: canonicalAgentClass(options.agentClass),
808
+ name: options.name,
809
+ instructions: options.instructions ?? "",
810
+ contextType: options.contextType ?? null,
811
+ contextId: options.contextId ?? null,
812
+ priority: options.priority ?? 0,
813
+ enabled: options.enabled ?? true,
814
+ runAsUserId: options.runAsUserId,
815
+ actsAsProfileId: options.actsAsProfileId ?? null,
816
+ memoryScope: options.memoryScope ?? ""
817
+ });
818
+ if (options.allowedTools) persona.setAllowedTools(options.allowedTools);
819
+ await persona.save();
820
+ return persona;
821
+ }
822
+ async function removePersonaInstance(personas, personaId) {
823
+ const persona = await personas.get({ id: personaId });
824
+ if (!persona) return false;
825
+ await persona.delete();
826
+ return true;
827
+ }
828
+ async function upgradeSingletonToDefaultPersona(personas, options) {
829
+ const canonical = canonicalAgentClass(options.agentClass);
830
+ const existingDefault = (await personas.byTenantAndClass(options.tenantId, canonical)).find(isDefaultPersona);
831
+ if (existingDefault) return {
832
+ persona: existingDefault,
833
+ created: false,
834
+ instanceKey: null
835
+ };
836
+ return {
837
+ persona: await addPersonaInstance(personas, {
838
+ tenantId: options.tenantId,
839
+ agentClass: canonical,
840
+ name: DEFAULT_PERSONA_NAME,
841
+ runAsUserId: options.runAsUserId,
842
+ instructions: options.instructions,
843
+ allowedTools: options.allowedTools,
844
+ memoryScope: options.memoryScope,
845
+ actsAsProfileId: options.actsAsProfileId,
846
+ priority: 0,
847
+ enabled: true
848
+ }),
849
+ created: true,
850
+ instanceKey: null
851
+ };
852
+ }
853
+ //#endregion
170
854
  //#region src/persona-resolver.ts
171
855
  function availabilityFromResolvedAgent(resolved, options = {}) {
172
856
  if (!resolved) return null;
@@ -285,6 +969,132 @@ function resolveMemoryScope(explicit, ctx) {
285
969
  return `${ctx.canonical}:${ctx.tenantId}${contextSuffix}`;
286
970
  }
287
971
  //#endregion
288
- export { AgentPersona, AgentPersonaCollection, PersonaResolver, availabilityFromResolvedAgent, canonicalAgentClass, personaAppliesToContext, personaContextRank };
972
+ //#region src/reflection-runner.ts
973
+ function normalizePersona(input) {
974
+ if (!input.id) throw new Error("ReflectionRunner.run requires a persisted persona (missing id)");
975
+ if (!input.tenantId) throw new Error("ReflectionRunner.run requires a tenant-scoped persona (missing tenantId)");
976
+ return {
977
+ id: input.id,
978
+ tenantId: input.tenantId,
979
+ agentClass: input.agentClass,
980
+ name: input.name,
981
+ instructions: input.instructions,
982
+ memoryScope: input.memoryScope
983
+ };
984
+ }
985
+ function meanConfidence(episodes) {
986
+ if (episodes.length === 0) return .5;
987
+ return episodes.reduce((acc, e) => acc + e.confidence, 0) / episodes.length;
988
+ }
989
+ var ReflectionRunner = class {
990
+ db;
991
+ reflect;
992
+ now;
993
+ _principal;
994
+ proposalsCol;
995
+ feedbackCol;
996
+ constructor(options) {
997
+ this.db = options.db;
998
+ this._principal = options.principal;
999
+ this.reflect = options.reflect;
1000
+ this.now = options.now ?? (() => /* @__PURE__ */ new Date());
1001
+ this.proposalsCol = options.proposals;
1002
+ this.feedbackCol = options.feedback;
1003
+ }
1004
+ /**
1005
+ * The autonomous principal this runner acts as. Exposed so callers can prove
1006
+ * it cannot activate a proposal (it lacks `personas.activate-directive`).
1007
+ */
1008
+ get principal() {
1009
+ return this._principal;
1010
+ }
1011
+ /**
1012
+ * Run one reflection pass for a persona.
1013
+ */
1014
+ async run(options) {
1015
+ const { memory } = options;
1016
+ const persona = normalizePersona(options.persona);
1017
+ const feedbackCol = await this.feedbackCollection();
1018
+ const feedbackLimit = options.feedbackLimit ?? 50;
1019
+ let feedback = await feedbackCol.forPersona(persona.id, { limit: feedbackLimit });
1020
+ if (options.lookbackMs != null) {
1021
+ const cutoff = this.now().getTime() - options.lookbackMs;
1022
+ feedback = feedback.filter((f) => {
1023
+ return (f.created_at ? new Date(f.created_at).getTime() : 0) >= cutoff;
1024
+ });
1025
+ }
1026
+ let reinforced = 0;
1027
+ for (const signal of feedback) {
1028
+ if (signal.reinforcedAt) continue;
1029
+ if (signal.correlationType !== "directive_proposal") {
1030
+ if (await reinforceFromFeedback(memory, signal, { ratingNeutral: options.ratingNeutral })) reinforced += 1;
1031
+ }
1032
+ signal.reinforcedAt = this.now();
1033
+ await signal.save();
1034
+ }
1035
+ const episodes = options.episodeScope ? await memory.recall(options.episodeScope, {
1036
+ minConfidence: 0,
1037
+ includeAncestors: true
1038
+ }) : [];
1039
+ ensurePersonaInstructionsPrompt(persona);
1040
+ const currentInstructions = await resolvePersonaInstructions({
1041
+ persona,
1042
+ db: this.db
1043
+ });
1044
+ const draft = await this.reflect({
1045
+ persona,
1046
+ currentInstructions,
1047
+ episodes,
1048
+ feedback
1049
+ });
1050
+ if (!draft || draft.instructions.trim() === currentInstructions.trim()) return {
1051
+ proposals: [],
1052
+ reinforced,
1053
+ skipped: draft ? 1 : 0
1054
+ };
1055
+ const promptKey = options.promptKey ?? personaInstructionsPromptKey(persona);
1056
+ const fingerprint = computeDirectiveFingerprint(persona.id, promptKey, draft.instructions);
1057
+ const proposals = await this.proposalsCollection();
1058
+ if ((await proposals.findByFingerprint(persona.id, fingerprint)).length > 0) return {
1059
+ proposals: [],
1060
+ reinforced,
1061
+ skipped: 1
1062
+ };
1063
+ return {
1064
+ proposals: [await proposals.create({
1065
+ tenantId: persona.tenantId,
1066
+ personaId: persona.id,
1067
+ agentClass: persona.agentClass ?? "",
1068
+ promptKey,
1069
+ proposedInstructions: draft.instructions,
1070
+ currentInstructions,
1071
+ rationale: draft.rationale,
1072
+ status: "pending",
1073
+ fingerprint,
1074
+ confidence: draft.confidence ?? meanConfidence(episodes),
1075
+ proposedBy: this._principal.id ?? "reflection",
1076
+ evidence: JSON.stringify({
1077
+ episodeIds: episodes.map((e) => e.id),
1078
+ feedbackIds: feedback.map((f) => f.id).filter((id) => Boolean(id))
1079
+ })
1080
+ })],
1081
+ reinforced,
1082
+ skipped: 0
1083
+ };
1084
+ }
1085
+ async proposalsCollection() {
1086
+ if (!this.proposalsCol) this.proposalsCol = await DirectiveProposalCollection.create({ db: this.db });
1087
+ return this.proposalsCol;
1088
+ }
1089
+ async feedbackCollection() {
1090
+ if (!this.feedbackCol) this.feedbackCol = await FeedbackCollection.create({ db: this.db });
1091
+ return this.feedbackCol;
1092
+ }
1093
+ };
1094
+ //#endregion
1095
+ //#region src/index.ts
1096
+ ensurePersonaPermissionsRegistered();
1097
+ //#endregion
1098
+ export { ACTIVATE_DIRECTIVE_PERMISSION, AgentPersona, AgentPersonaCollection, DEFAULT_PERSONA_NAME, DIRECTIVE_ACTIVATION_PERMISSION_DEF, DirectiveActivationDeniedError, DirectiveApprovalService, DirectiveNotPendingError, DirectiveProposal, DirectiveProposalCollection, Feedback, FeedbackCollection, HUMAN_SIGNAL_TYPES, PersonaResolver, ReflectionRunner, addPersonaInstance, agentOptionsForPersona, applyPersonaInstructions, availabilityFromResolvedAgent, buildPersonaInstanceAdmin, canonicalAgentClass, computeDirectiveFingerprint, ensurePersonaInstructionsPrompt, ensurePersonaPermissionsRegistered, feedbackSourceFor, isDefaultPersona, personaAppliesToContext, personaContextRank, personaInstanceKey, personaInstructionsPromptKey, personaLearningMemory, personaMemoryScope, principalFromPermissions, registerPersonaPermissions, reinforceFromFeedback, removePersonaInstance, resolveDirectivePrincipal, resolvePersonaInstructions, schedulePersonaInstance, upgradeSingletonToDefaultPersona, upsertPromptTemplateOverride };
289
1099
 
290
1100
  //# sourceMappingURL=index.js.map