@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.
- package/AGENTS.md +119 -7
- package/dist/__smrt-register__.d.ts +2 -0
- package/dist/__smrt-register__.d.ts.map +1 -0
- package/dist/agent-persona.d.ts +161 -0
- package/dist/agent-persona.d.ts.map +1 -0
- package/dist/directive-approval.d.ts +94 -0
- package/dist/directive-approval.d.ts.map +1 -0
- package/dist/directive-principal.d.ts +56 -0
- package/dist/directive-principal.d.ts.map +1 -0
- package/dist/directive-proposal.d.ts +103 -0
- package/dist/directive-proposal.d.ts.map +1 -0
- package/dist/feedback.d.ts +127 -0
- package/dist/feedback.d.ts.map +1 -0
- package/dist/index.d.ts +11 -294
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +829 -19
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +919 -3
- package/dist/persona-instance.d.ts +249 -0
- package/dist/persona-instance.d.ts.map +1 -0
- package/dist/persona-memory.d.ts +45 -0
- package/dist/persona-memory.d.ts.map +1 -0
- package/dist/persona-prompt.d.ts +77 -0
- package/dist/persona-prompt.d.ts.map +1 -0
- package/dist/persona-resolver.d.ts +134 -0
- package/dist/persona-resolver.d.ts.map +1 -0
- package/dist/reflection-runner.d.ts +113 -0
- package/dist/reflection-runner.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +519 -11
- package/dist/svelte/components/DirectiveReviewQueue.svelte +185 -0
- package/dist/svelte/components/DirectiveReviewQueue.svelte.d.ts +15 -0
- package/dist/svelte/components/DirectiveReviewQueue.svelte.d.ts.map +1 -0
- package/dist/svelte/index.d.ts +16 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +13 -0
- package/dist/svelte/types.d.ts +46 -0
- package/dist/svelte/types.d.ts.map +1 -0
- package/dist/svelte/types.js +39 -0
- 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
|
-
|
|
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
|