@happyvertical/smrt-agents 0.51.39 → 0.52.0

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.
@@ -2,7 +2,7 @@
2
2
  "version": "1.0.0",
3
3
  "timestamp": 0,
4
4
  "packageName": "@happyvertical/smrt-agents",
5
- "packageVersion": "0.51.39",
5
+ "packageVersion": "0.52.0",
6
6
  "objects": {
7
7
  "@happyvertical/smrt-agents:Agent": {
8
8
  "name": "agent",
@@ -246,6 +246,7 @@
246
246
  "staticProperties": {
247
247
  "uiSlots": {},
248
248
  "adminRoutes": [],
249
+ "createEntries": [],
249
250
  "signalSubscriptions": []
250
251
  },
251
252
  "schema": {
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Data repair for tenant agent config keys left behind by smrt #1092.
3
+ *
4
+ * #1092 canonicalized agent identity to the registry's qualified type
5
+ * (`@scope/package:Class`). A tenant-bound agent with no Agent row owns its
6
+ * slot configs under `tenantAgentConfigOwnerId(tenant, type)`, so the id the
7
+ * admin UI reads became `<tenant>:@scope/package:Class` — but rows written
8
+ * before (or by writers that kept composing the old id) sit under
9
+ * `<tenant>:Class`, and the settings panels show nothing. Separately,
10
+ * `tenant_agents.agent_class` may still hold a bare class or a renamed
11
+ * package's qualified name. `TenantAgentCollection` self-heals a bare class
12
+ * on read, but never the config rows and never a name the registry cannot map.
13
+ *
14
+ * This repair moves both to the canonical type:
15
+ *
16
+ * - `tenant_agents.agent_class` → canonical type (never onto an existing
17
+ * binding of the same tenant: two spellings of one binding are blocked);
18
+ * - `agent_configs` rows whose owner id is `<row tenant_id>:<type>` → owner
19
+ * `<tenant>:<canonical>`, `agent_class` canonical, and the slug
20
+ * `AgentConfig.saveSlot()` gives a new row (`<owner>-<slot>`). Two rows
21
+ * landing on one `(tenant, owner, slot)` or one slug are blocked. Other
22
+ * owner ids (persona ids, Agent row ids) are left alone.
23
+ *
24
+ * Canonical type = `aliases[stored]` when given (for renamed packages the
25
+ * registry cannot know), else `getAgentTypeName(stored)`, which needs the
26
+ * agent classes registered in the running process (import the host's
27
+ * agents first).
28
+ *
29
+ * `repairTenantAgentConfigKeys(db)` is a dry run and never writes. With
30
+ * `apply: true` it re-plans inside one transaction (table locks on
31
+ * PostgreSQL), refuses when anything is blocked, re-checks before commit,
32
+ * and returns a ledger of every before/after value. Re-running after apply
33
+ * finds nothing to do.
34
+ */
35
+ import type { DatabaseInterface } from '@happyvertical/sql';
36
+ export declare const TENANT_AGENTS_TABLE = "tenant_agents";
37
+ export declare const AGENT_CONFIGS_TABLE = "agent_configs";
38
+ export declare class TenantAgentConfigKeyRepairError extends Error {
39
+ constructor(message: string);
40
+ }
41
+ export interface TenantAgentConfigKeyRepairOptions {
42
+ /**
43
+ * Stored spelling → canonical type, consulted before the registry. Use it
44
+ * for types the registry cannot map, e.g. a package that was renamed
45
+ * (`'@happyvertical/praeco:Praeco': '@anytown/praeco:Praeco'`).
46
+ */
47
+ aliases?: Readonly<Record<string, string>>;
48
+ /** Full override of the canonicalization (aliases are then ignored). */
49
+ resolveAgentType?: (stored: string) => string;
50
+ }
51
+ export interface TenantAgentKeyRow {
52
+ id: string;
53
+ tenantId: string;
54
+ agentClass: string;
55
+ targetAgentClass: string;
56
+ reason?: string;
57
+ }
58
+ export interface AgentConfigKeyRow {
59
+ id: string;
60
+ tenantId: string | null;
61
+ slotId: string;
62
+ agentId: string;
63
+ agentClass: string;
64
+ slug: string;
65
+ targetAgentId: string;
66
+ targetAgentClass: string;
67
+ targetSlug: string;
68
+ /** No tenant binding owns the target owner id (after the binding repair). */
69
+ unbound: boolean;
70
+ reason?: string;
71
+ }
72
+ export interface TenantAgentConfigKeyPlan {
73
+ tenantAgents: {
74
+ clean: TenantAgentKeyRow[];
75
+ planned: TenantAgentKeyRow[];
76
+ blocked: TenantAgentKeyRow[];
77
+ };
78
+ configs: {
79
+ clean: AgentConfigKeyRow[];
80
+ planned: AgentConfigKeyRow[];
81
+ blocked: AgentConfigKeyRow[];
82
+ /** Owner ids that are not `<row tenant>:<type>` (persona/Agent row ids). */
83
+ skipped: AgentConfigKeyRow[];
84
+ };
85
+ }
86
+ export interface TenantAgentConfigKeyLedgerEntry {
87
+ table: typeof TENANT_AGENTS_TABLE | typeof AGENT_CONFIGS_TABLE;
88
+ id: string;
89
+ before: Record<string, string>;
90
+ after: Record<string, string>;
91
+ }
92
+ export interface TenantAgentConfigKeyRepairTotals {
93
+ tenantAgents: {
94
+ total: number;
95
+ clean: number;
96
+ planned: number;
97
+ blocked: number;
98
+ };
99
+ configs: {
100
+ total: number;
101
+ clean: number;
102
+ planned: number;
103
+ blocked: number;
104
+ skipped: number;
105
+ unbound: number;
106
+ };
107
+ /** Rows written (0 on a dry run). */
108
+ changed: number;
109
+ }
110
+ export interface TenantAgentConfigKeyRepairReport {
111
+ mode: 'dry-run' | 'apply';
112
+ /** The plan before any write (dry run) or the re-check after apply. */
113
+ plan: TenantAgentConfigKeyPlan;
114
+ totals: TenantAgentConfigKeyRepairTotals;
115
+ ledger: TenantAgentConfigKeyLedgerEntry[];
116
+ }
117
+ export interface RawTenantAgentRow {
118
+ id: unknown;
119
+ tenant_id: unknown;
120
+ agent_class: unknown;
121
+ }
122
+ export interface RawAgentConfigRow {
123
+ id: unknown;
124
+ tenant_id: unknown;
125
+ agent_id: unknown;
126
+ agent_class: unknown;
127
+ slot_id: unknown;
128
+ slug: unknown;
129
+ }
130
+ type Queryable = Pick<DatabaseInterface, 'query'>;
131
+ /** Pure planner over both tables' rows (no SQL), for tests and previews. */
132
+ export declare function planTenantAgentConfigKeyRepairRows(tenantAgentRows: readonly RawTenantAgentRow[], configRows: readonly RawAgentConfigRow[], options?: TenantAgentConfigKeyRepairOptions): TenantAgentConfigKeyPlan;
133
+ /** Read both tables and plan the repair (never writes). */
134
+ export declare function planTenantAgentConfigKeyRepair(db: Queryable, options?: TenantAgentConfigKeyRepairOptions): Promise<TenantAgentConfigKeyPlan>;
135
+ /**
136
+ * Plan (default) or apply the tenant agent config key repair. See the module
137
+ * docs; `apply: true` requires a transaction-capable adapter.
138
+ */
139
+ export declare function repairTenantAgentConfigKeys(db: DatabaseInterface, options?: TenantAgentConfigKeyRepairOptions & {
140
+ apply?: boolean;
141
+ }): Promise<TenantAgentConfigKeyRepairReport>;
142
+ export {};
143
+ //# sourceMappingURL=tenant-agent-config-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-agent-config-keys.d.ts","sourceRoot":"","sources":["../../src/migrations/tenant-agent-config-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAM5D,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AACnD,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AAEnD,qBAAa,+BAAgC,SAAQ,KAAK;gBAC5C,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,iCAAiC;IAChD;;;;OAIG;IACH,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3C,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;CAC/C;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,YAAY,EAAE;QACZ,KAAK,EAAE,iBAAiB,EAAE,CAAC;QAC3B,OAAO,EAAE,iBAAiB,EAAE,CAAC;QAC7B,OAAO,EAAE,iBAAiB,EAAE,CAAC;KAC9B,CAAC;IACF,OAAO,EAAE;QACP,KAAK,EAAE,iBAAiB,EAAE,CAAC;QAC3B,OAAO,EAAE,iBAAiB,EAAE,CAAC;QAC7B,OAAO,EAAE,iBAAiB,EAAE,CAAC;QAC7B,4EAA4E;QAC5E,OAAO,EAAE,iBAAiB,EAAE,CAAC;KAC9B,CAAC;CACH;AAED,MAAM,WAAW,+BAA+B;IAC9C,KAAK,EAAE,OAAO,mBAAmB,GAAG,OAAO,mBAAmB,CAAC;IAC/D,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,gCAAgC;IAC/C,YAAY,EAAE;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gCAAgC;IAC/C,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;IAC1B,uEAAuE;IACvE,IAAI,EAAE,wBAAwB,CAAC;IAC/B,MAAM,EAAE,gCAAgC,CAAC;IACzC,MAAM,EAAE,+BAA+B,EAAE,CAAC;CAC3C;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,KAAK,SAAS,GAAG,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;AA6BlD,4EAA4E;AAC5E,wBAAgB,kCAAkC,CAChD,eAAe,EAAE,SAAS,iBAAiB,EAAE,EAC7C,UAAU,EAAE,SAAS,iBAAiB,EAAE,EACxC,OAAO,GAAE,iCAAsC,GAC9C,wBAAwB,CAuH1B;AAeD,2DAA2D;AAC3D,wBAAsB,8BAA8B,CAClD,EAAE,EAAE,SAAS,EACb,OAAO,GAAE,iCAAsC,GAC9C,OAAO,CAAC,wBAAwB,CAAC,CAOnC;AAwCD;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,EAAE,EAAE,iBAAiB,EACrB,OAAO,GAAE,iCAAiC,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GACpE,OAAO,CAAC,gCAAgC,CAAC,CAoF3C"}
@@ -3,6 +3,15 @@ import { type JobExecutionContext } from '@happyvertical/smrt-jobs';
3
3
  import type { DataSurfaceActionResult } from '@happyvertical/smrt-types';
4
4
  import type { DatabaseInterface } from '@happyvertical/sql';
5
5
  import type { DataSurfaceBackgroundActionEnvelope, DataSurfaceBackgroundQueue } from './data-surface-actions.js';
6
+ export interface DataSurfaceBackgroundActionHandlerOptions {
7
+ /**
8
+ * Stable identity of the registering host module. A re-registration of the
9
+ * same `handlerId` by the same owner (a re-evaluated module after a hot
10
+ * reload) replaces the previous handler; a different owner, or an anonymous
11
+ * registration with a different function, is a conflict and throws.
12
+ */
13
+ owner?: string;
14
+ }
6
15
  export interface DataSurfaceActionJobArgs {
7
16
  version: 1;
8
17
  envelope: DataSurfaceBackgroundActionEnvelope;
@@ -10,6 +19,8 @@ export interface DataSurfaceActionJobArgs {
10
19
  export interface JobsDataSurfaceBackgroundQueueOptions {
11
20
  db: DatabaseInterface;
12
21
  handlerId: string;
22
+ /** See {@link DataSurfaceBackgroundActionHandlerOptions.owner}. */
23
+ owner?: string;
13
24
  execute(envelope: DataSurfaceBackgroundActionEnvelope): Promise<DataSurfaceActionResult>;
14
25
  queue?: string;
15
26
  priority?: number;
@@ -26,7 +37,7 @@ export declare class SmrtDataSurfaceActionTask extends SmrtObject {
26
37
  * Register the host handler used by workers after process restart.
27
38
  * The returned disposer only removes the same registration.
28
39
  */
29
- export declare function registerDataSurfaceBackgroundActionHandler(handlerId: string, execute: (envelope: DataSurfaceBackgroundActionEnvelope) => Promise<DataSurfaceActionResult>): () => void;
40
+ export declare function registerDataSurfaceBackgroundActionHandler(handlerId: string, execute: (envelope: DataSurfaceBackgroundActionEnvelope) => Promise<DataSurfaceActionResult>, options?: DataSurfaceBackgroundActionHandlerOptions): () => void;
30
41
  export declare function createJobsDataSurfaceBackgroundQueue(options: JobsDataSurfaceBackgroundQueueOptions): DataSurfaceBackgroundQueue & {
31
42
  unregister(): void;
32
43
  };
@@ -1 +1 @@
1
- {"version":3,"file":"jobs-data-surface-action-queue.d.ts","sourceRoot":"","sources":["../../src/server/jobs-data-surface-action-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAIL,KAAK,mBAAmB,EAGzB,MAAM,0BAA0B,CAAC;AAMlC,OAAO,KAAK,EACV,uBAAuB,EAExB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EACV,mCAAmC,EAEnC,0BAA0B,EAC3B,MAAM,2BAA2B,CAAC;AASnC,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,mCAAmC,CAAC;CAC/C;AAED,MAAM,WAAW,qCAAqC;IACpD,EAAE,EAAE,iBAAiB,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CACL,QAAQ,EAAE,mCAAmC,GAC5C,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAOa,yBAA0B,SAAQ,UAAU;IAEvD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAG/B,IAAI,EAAE,wBAAwB,CAG5B;IAGI,GAAG,CACP,IAAI,GAAE,wBAAoC,EAC1C,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,uBAAuB,CAAC;CA6CpC;AAED;;;GAGG;AACH,wBAAgB,0CAA0C,CACxD,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CACP,QAAQ,EAAE,mCAAmC,KAC1C,OAAO,CAAC,uBAAuB,CAAC,GACpC,MAAM,IAAI,CAgBZ;AAED,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,qCAAqC,GAC7C,0BAA0B,GAAG;IAAE,UAAU,IAAI,IAAI,CAAA;CAAE,CAuBrD"}
1
+ {"version":3,"file":"jobs-data-surface-action-queue.d.ts","sourceRoot":"","sources":["../../src/server/jobs-data-surface-action-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAIL,KAAK,mBAAmB,EAGzB,MAAM,0BAA0B,CAAC;AAMlC,OAAO,KAAK,EACV,uBAAuB,EAExB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EACV,mCAAmC,EAEnC,0BAA0B,EAC3B,MAAM,2BAA2B,CAAC;AA8BnC,MAAM,WAAW,yCAAyC;IACxD;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,mCAAmC,CAAC;CAC/C;AAED,MAAM,WAAW,qCAAqC;IACpD,EAAE,EAAE,iBAAiB,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CACL,QAAQ,EAAE,mCAAmC,GAC5C,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAOa,yBAA0B,SAAQ,UAAU;IAEvD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAG/B,IAAI,EAAE,wBAAwB,CAG5B;IAGI,GAAG,CACP,IAAI,GAAE,wBAAoC,EAC1C,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,uBAAuB,CAAC;CA6CpC;AAED;;;GAGG;AACH,wBAAgB,0CAA0C,CACxD,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CACP,QAAQ,EAAE,mCAAmC,KAC1C,OAAO,CAAC,uBAAuB,CAAC,EACrC,OAAO,GAAE,yCAA8C,GACtD,MAAM,IAAI,CAqBZ;AAED,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,qCAAqC,GAC7C,0BAA0B,GAAG;IAAE,UAAU,IAAI,IAAI,CAAA;CAAE,CAwBrD"}
@@ -7,7 +7,7 @@
7
7
  * @module @happyvertical/smrt-agents/server
8
8
  */
9
9
  import type { ResolvedAgentAvailability } from '../tenant-agent.js';
10
- import type { AgentAdminRoute, AgentUISlots } from '../ui.js';
10
+ import type { AgentAdminRoute, AgentCreateEntry, AgentUISlots } from '../ui.js';
11
11
  /**
12
12
  * Serialized agent data for passing to client components.
13
13
  *
@@ -15,7 +15,10 @@ import type { AgentAdminRoute, AgentUISlots } from '../ui.js';
15
15
  * alongside resolution metadata (source, sourceTenantId).
16
16
  */
17
17
  export interface SerializedAgent {
18
- /** Agent instance ID, or a synthetic key if no instance exists */
18
+ /**
19
+ * Agent instance ID, or — when the binding has no agent row — the tenant
20
+ * config owner id `tenantAgentConfigOwnerId(sourceTenantId, agentType)`.
21
+ */
19
22
  id: string;
20
23
  /** Human-readable name from manifest */
21
24
  name?: string;
@@ -29,6 +32,8 @@ export interface SerializedAgent {
29
32
  slots?: AgentUISlots;
30
33
  /** Admin route declarations from manifest */
31
34
  adminRoutes?: AgentAdminRoute[];
35
+ /** Create options from manifest (see `resolveAgentCreateEntries`) */
36
+ createEntries?: AgentCreateEntry[];
32
37
  /** How this agent was resolved for the tenant */
33
38
  source?: 'explicit' | 'inherited';
34
39
  /** Which tenant the binding came from */
@@ -1 +1 @@
1
- {"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../../src/server/serialization.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC,iDAAiD;IACjD,MAAM,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;IAClC,yCAAyC;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,yBAAyB,GAClC,eAAe,CAkBjB"}
1
+ {"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../../src/server/serialization.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAEhF;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC,qEAAqE;IACrE,aAAa,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACnC,iDAAiD;IACjD,MAAM,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;IAClC,yCAAyC;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,yBAAyB,GAClC,eAAe,CAqBjB"}
package/dist/server.js CHANGED
@@ -1,4 +1,4 @@
1
- import { n as executeAsPrincipal, r as AgentConfig } from "./chunks/execute-as-principal-uuJq7EFs.js";
1
+ import { n as executeAsPrincipal, r as AgentConfig, u as tenantAgentConfigOwnerId } from "./chunks/execute-as-principal-DtwCUq2t.js";
2
2
  import { i as loadManifestsFromPackages, n as extractAgentPackagesFromConfig, r as loadManifestsFromConfig, t as extractAgentManifest } from "./chunks/manifest-utils-CtMyFQDx.js";
3
3
  import { ObjectRegistry, SmrtObject, field, smrt } from "@happyvertical/smrt-core";
4
4
  import { sanitizeConfig } from "@happyvertical/smrt-config";
@@ -687,7 +687,10 @@ var __decorateClass$1 = (decorators, target, key, kind) => {
687
687
  if (kind && result) __defProp$1(target, key, result);
688
688
  return result;
689
689
  };
690
- var handlers = /* @__PURE__ */ new Map();
690
+ var HANDLERS_KEY = /* @__PURE__ */ Symbol.for("@happyvertical/smrt-agents/data-surface-action-handlers@2");
691
+ var globalRegistry = globalThis;
692
+ var handlers = globalRegistry[HANDLERS_KEY] ?? /* @__PURE__ */ new Map();
693
+ globalRegistry[HANDLERS_KEY] = handlers;
691
694
  var SmrtDataSurfaceActionTask = class extends SmrtObject {
692
695
  tenantId = null;
693
696
  args = {
@@ -708,7 +711,7 @@ var SmrtDataSurfaceActionTask = class extends SmrtObject {
708
711
  if (args?.version !== 1 || envelope?.version !== 1 || typeof envelope.handlerId !== "string" || envelope.handlerId.length === 0 || envelope.principal?.tenantId !== jobTenantId) throw new Error("Invalid durable data-surface action envelope");
709
712
  const handler = handlers.get(envelope.handlerId);
710
713
  if (!handler) throw new Error(`No data-surface action handler registered for ${envelope.handlerId}`);
711
- const result = await handler(envelope);
714
+ const result = await handler.execute(envelope);
712
715
  if (!result.ok && result.reason === "idempotency_in_progress") throw new Error("Data-surface action outcome requires reconciliation");
713
716
  return result;
714
717
  }
@@ -725,18 +728,24 @@ SmrtDataSurfaceActionTask = __decorateClass$1([TenantScoped({ mode: "optional" }
725
728
  cli: false,
726
729
  mcp: false
727
730
  })], SmrtDataSurfaceActionTask);
728
- function registerDataSurfaceBackgroundActionHandler(handlerId, execute) {
731
+ function registerDataSurfaceBackgroundActionHandler(handlerId, execute, options = {}) {
729
732
  if (!handlerId || handlerId.length > 256) throw new Error("Data-surface action handlerId must contain 1-256 characters");
730
733
  const existing = handlers.get(handlerId);
731
- if (existing && existing !== execute) throw new Error(`Data-surface action handler already registered: ${handlerId}`);
732
- handlers.set(handlerId, execute);
734
+ if (existing && existing.execute !== execute) {
735
+ if (!(options.owner !== void 0 && existing.owner === options.owner)) throw new Error(`Data-surface action handler already registered: ${handlerId}`);
736
+ }
737
+ const entry = {
738
+ execute,
739
+ owner: options.owner
740
+ };
741
+ handlers.set(handlerId, entry);
733
742
  return () => {
734
- if (handlers.get(handlerId) === execute) handlers.delete(handlerId);
743
+ if (handlers.get(handlerId) === entry) handlers.delete(handlerId);
735
744
  };
736
745
  }
737
746
  function createJobsDataSurfaceBackgroundQueue(options) {
738
747
  return {
739
- unregister: registerDataSurfaceBackgroundActionHandler(options.handlerId, options.execute),
748
+ unregister: registerDataSurfaceBackgroundActionHandler(options.handlerId, options.execute, { owner: options.owner }),
740
749
  async enqueue(job) {
741
750
  if (job.envelope.handlerId !== options.handlerId) throw new Error("Data-surface action envelope handler mismatch");
742
751
  const persisted = await enqueueDataSurfaceActionJob(options, job.envelope);
@@ -773,13 +782,14 @@ async function enqueueDataSurfaceActionJob(options, envelope) {
773
782
  function serializeResolvedAgent(resolved) {
774
783
  const manifest = resolved.manifest;
775
784
  return {
776
- id: resolved.agentId || `${resolved.sourceTenantId}:${resolved.agentType}`,
785
+ id: resolved.agentId || tenantAgentConfigOwnerId(resolved.sourceTenantId, resolved.agentType),
777
786
  name: manifest?.name || resolved.agentClass,
778
787
  agentClass: resolved.agentClass,
779
788
  agentType: resolved.agentType,
780
789
  _meta_type: resolved.agentType,
781
790
  slots: manifest?.uiSlots,
782
791
  adminRoutes: manifest?.adminRoutes,
792
+ createEntries: manifest?.createEntries,
783
793
  source: resolved.source,
784
794
  sourceTenantId: resolved.sourceTenantId,
785
795
  permissions: resolved.permissions,