@ixo/oracle-runtime 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/bootstrap/create-oracle-app.d.ts.map +1 -1
  2. package/dist/bootstrap/create-oracle-app.js +0 -5
  3. package/dist/config/base-env-config.d.ts.map +1 -1
  4. package/dist/config/base-env-config.js +0 -2
  5. package/dist/graph/main-agent.d.ts.map +1 -1
  6. package/dist/graph/main-agent.js +54 -2
  7. package/dist/graph/subagent-as-tool.d.ts +15 -0
  8. package/dist/graph/subagent-as-tool.d.ts.map +1 -1
  9. package/dist/graph/subagent-as-tool.js +5 -1
  10. package/dist/matrix/user-id.d.ts +16 -0
  11. package/dist/matrix/user-id.d.ts.map +1 -0
  12. package/dist/matrix/user-id.js +17 -0
  13. package/dist/modules/messages/agent-builder.d.ts.map +1 -1
  14. package/dist/modules/messages/agent-builder.js +2 -1
  15. package/dist/modules/sessions/session-history-processor.service.d.ts.map +1 -1
  16. package/dist/modules/sessions/session-history-processor.service.js +2 -1
  17. package/dist/modules/ucan/ucan.service.d.ts.map +1 -1
  18. package/dist/plugins/credits/claim-processing.service.d.ts +1 -1
  19. package/dist/plugins/credits/claim-processing.service.d.ts.map +1 -1
  20. package/dist/plugins/credits/claim-processing.service.js +6 -7
  21. package/dist/plugins/credits/credits.plugin.d.ts +4 -0
  22. package/dist/plugins/credits/credits.plugin.d.ts.map +1 -1
  23. package/dist/plugins/credits/credits.plugin.js +7 -1
  24. package/dist/plugins/domain-indexer/domain-indexer-tools.d.ts.map +1 -1
  25. package/dist/plugins/domain-indexer/domain-indexer-tools.js +22 -3
  26. package/dist/plugins/editor/editor-access-denied-tool.d.ts +21 -0
  27. package/dist/plugins/editor/editor-access-denied-tool.d.ts.map +1 -0
  28. package/dist/plugins/editor/editor-access-denied-tool.js +37 -0
  29. package/dist/plugins/editor/editor-agent.d.ts +11 -0
  30. package/dist/plugins/editor/editor-agent.d.ts.map +1 -1
  31. package/dist/plugins/editor/editor-agent.js +18 -13
  32. package/dist/plugins/editor/editor.plugin.d.ts.map +1 -1
  33. package/dist/plugins/editor/editor.plugin.js +4 -4
  34. package/dist/plugins/editor/index.d.ts +2 -1
  35. package/dist/plugins/editor/index.d.ts.map +1 -1
  36. package/dist/plugins/editor/index.js +2 -1
  37. package/dist/plugins/editor/page-functions.d.ts.map +1 -1
  38. package/dist/plugins/editor/page-functions.js +18 -4
  39. package/dist/plugins/editor/prompts.d.ts +16 -0
  40. package/dist/plugins/editor/prompts.d.ts.map +1 -1
  41. package/dist/plugins/editor/prompts.js +46 -10
  42. package/dist/plugins/editor/standalone-editor-tool.d.ts +5 -2
  43. package/dist/plugins/editor/standalone-editor-tool.d.ts.map +1 -1
  44. package/dist/plugins/editor/standalone-editor-tool.js +97 -65
  45. package/dist/plugins/matrix-group-chats/channel-memory.service.js +1 -1
  46. package/package.json +13 -9
@@ -1 +1 @@
1
- {"version":3,"file":"create-oracle-app.d.ts","sourceRoot":"","sources":["../../src/bootstrap/create-oracle-app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create-oracle-app.d.ts","sourceRoot":"","sources":["../../src/bootstrap/create-oracle-app.ts"],"names":[],"mappings":"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"}
@@ -272,11 +272,6 @@ export async function createOracleApp(opts) {
272
272
  ? {
273
273
  checkpointerForUser: async (userDid) => {
274
274
  const db = await checkpointSync.getUserDatabase(userDid);
275
- // Cross-package interop: SqliteSaver extends BaseCheckpointSaver
276
- // from `@langchain/langgraph-checkpoint`; the hook return type
277
- // pulls from `@langchain/langgraph`. pnpm hoists these into
278
- // separate type identities even at the same version — they are
279
- // structurally identical at runtime.
280
275
  return SqliteSaver.fromDatabase(db);
281
276
  },
282
277
  }
@@ -1 +1 @@
1
- {"version":3,"file":"base-env-config.d.ts","sourceRoot":"","sources":["../../src/config/base-env-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEnE;;;;;;;;;;GAUG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG;IACzC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,CAAC,SAAS,MAAM,kBAAkB,EACpC,GAAG,EAAE,CAAC,EACN,YAAY,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,GACnC,kBAAkB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IACrC,UAAU,CAAC,CAAC,SAAS,MAAM,kBAAkB,EAAE,GAAG,EAAE,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;CAC/E;AAmDD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,GAChD,eAAe,CAiBjB;AAED,wBAAgB,4BAA4B,IAAI,IAAI,CAEnD"}
1
+ {"version":3,"file":"base-env-config.d.ts","sourceRoot":"","sources":["../../src/config/base-env-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEnE;;;;;;;;;;GAUG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG;IACzC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,CAAC,SAAS,MAAM,kBAAkB,EACpC,GAAG,EAAE,CAAC,EACN,YAAY,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,GACnC,kBAAkB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IACrC,UAAU,CAAC,CAAC,SAAS,MAAM,kBAAkB,EAAE,GAAG,EAAE,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;CAC/E;AAmDD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,GAChD,eAAe,CAejB;AAED,wBAAgB,4BAA4B,IAAI,IAAI,CAEnD"}
@@ -56,11 +56,9 @@ export function getBaseEnvConfig(configService) {
56
56
  const svc = configService ?? singletonConfigService();
57
57
  return {
58
58
  get(key, defaultValue) {
59
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
59
  return svc.get(key, defaultValue);
61
60
  },
62
61
  getOrThrow(key) {
63
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
62
  return svc.getOrThrow(key);
65
63
  },
66
64
  };
@@ -1 +1 @@
1
- {"version":3,"file":"main-agent.d.ts","sourceRoot":"","sources":["../../src/graph/main-agent.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAc9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AA0CjD;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,iBAAiB,CAAC,CA0P5B;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAC/B,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"main-agent.d.ts","sourceRoot":"","sources":["../../src/graph/main-agent.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAc9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AA0CjD;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,iBAAiB,CAAC,CA2T5B;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAC/B,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC"}
@@ -2,6 +2,10 @@ import { createAgent, toolRetryMiddleware, } from 'langchain';
2
2
  import { renderTier1 } from '../manifest/tier1-renderer.js';
3
3
  import { buildMetaTools } from '../meta-tools/index.js';
4
4
  import { MEMORY_CLEAR_MCP_NAME, MemoryPlugin, } from '../plugins/memory/index.js';
5
+ import { isUserInRoom } from '../matrix/room-membership.js';
6
+ import { createEditorAccessDeniedTool } from '../plugins/editor/editor-access-denied-tool.js';
7
+ import { EDITOR_AGENT_TOOL_NAME } from '../plugins/editor/editor-agent.js';
8
+ import { EDITOR_MODE_PROMPTS, editorUnavailableMode, STANDALONE_EDITOR_PROMPTS, } from '../plugins/editor/prompts.js';
5
9
  import { buildPluginContext } from '../runtime-context/build-plugin.js';
6
10
  import { buildRuntimeContext, } from '../runtime-context/build-runtime.js';
7
11
  import { createCapabilityGateMiddleware, createPageContextMiddleware, createSafetyGuardrailMiddleware, createToolRepetitionGuardMiddleware, createToolValidationMiddleware, } from './middlewares/index.js';
@@ -54,6 +58,7 @@ export async function createMainAgent(args) {
54
58
  pluginName: PLUGIN_LOGGER_COMPONENT,
55
59
  });
56
60
  // ── 2. Request-time runtime context (drives getRequestTools/...SubAgents) ─
61
+ ambient.logger.debug?.(`[MainAgent] state.loadedPlugins:`, state.loadedPlugins);
57
62
  const loadedSet = new Set(state.loadedPlugins ?? []);
58
63
  // Carry the prior request state (editorRoomId, spaceId, browserTools,
59
64
  // agActions, …) into the per-request RuntimeContext and the tool-wrapper
@@ -214,11 +219,58 @@ export async function createMainAgent(args) {
214
219
  const tier1 = renderTier1({ manifests: eagerEntries });
215
220
  for (const warning of tier1.warnings)
216
221
  ambient.logger.warn(warning);
222
+ // Editor mode is selected per-request from the live state (the static
223
+ // `hooks` from the bundle can't carry request-scoped editorRoomId/spaceId).
224
+ // When a page is open (`editorRoomId`) the editor prompt is the "richer mode"
225
+ // that overrides the fork's operationalMode; with only a `spaceId` the
226
+ // standalone variant applies. Falls back to hooks/defaults otherwise.
227
+ //
228
+ // Gated on `call_editor_agent` actually being bound: the editor plugin can
229
+ // refuse to contribute its surface even when the state fields are set (room
230
+ // membership check failed, Matrix unavailable, sub-agent build error).
231
+ // Injecting "EDITOR MODE ACTIVE — use the Editor Agent tool" without the
232
+ // tool bound makes the model emit its sub-agent task as user-facing text
233
+ // instead of calling anything.
234
+ const editorToolBound = tools.some((t) => t.name === EDITOR_AGENT_TOOL_NAME);
235
+ // A page is open but the editor refused to bind. Tell the model WHY via a
236
+ // dedicated operational mode AND bind a stub `call_editor_agent` that
237
+ // returns the same denial — so even a model that ignores the prompt and
238
+ // calls the editor learns the truth from the tool result. The membership
239
+ // re-check hits the cache the editor plugin's own guard just populated
240
+ // (60s TTL), so this costs no extra Matrix round-trip; `isUserInRoom`
241
+ // fails closed, matching the plugin's decision.
242
+ let editorUnavailableBlock = null;
243
+ if (!editorToolBound && state.editorRoomId) {
244
+ const isMember = await isUserInRoom(state.editorRoomId, requestCtx.user.matrixUserId);
245
+ const reason = isMember ? 'bind-error' : 'not-member';
246
+ editorUnavailableBlock = editorUnavailableMode({
247
+ editorRoomId: state.editorRoomId,
248
+ reason,
249
+ });
250
+ tools.push(createEditorAccessDeniedTool({
251
+ editorRoomId: state.editorRoomId,
252
+ reason,
253
+ }));
254
+ ambient.logger.warn(`[main-agent] editorRoomId=${state.editorRoomId} set but ${EDITOR_AGENT_TOOL_NAME} did not bind (reason: ${reason}, user: ${requestCtx.user.matrixUserId}) — ` +
255
+ `binding access-denied stub and injecting the unavailable notice`);
256
+ }
257
+ else if (!editorToolBound && state.spaceId) {
258
+ ambient.logger.warn(`[main-agent] spaceId=${state.spaceId} set but ${EDITOR_AGENT_TOOL_NAME} did not bind — suppressing editor prompts; ` +
259
+ `see preceding [editor] log lines for the refusal reason`);
260
+ }
261
+ const editorPrompts = editorToolBound && state.editorRoomId
262
+ ? EDITOR_MODE_PROMPTS
263
+ : editorToolBound && state.spaceId
264
+ ? STANDALONE_EDITOR_PROMPTS
265
+ : null;
217
266
  const prompt = await composePrompt({
218
267
  identity,
219
268
  capabilityBlock: tier1.block,
220
- operationalMode: hooks?.operationalMode ?? DEFAULT_OPERATIONAL_MODE,
221
- editorSection: hooks?.editorSection ?? '',
269
+ operationalMode: editorPrompts?.operationalMode ??
270
+ editorUnavailableBlock ??
271
+ hooks?.operationalMode ??
272
+ DEFAULT_OPERATIONAL_MODE,
273
+ editorSection: editorPrompts?.editorSection ?? hooks?.editorSection ?? '',
222
274
  composioContext: hooks?.composioContext ?? '',
223
275
  slackFormattingConstraints: requestCtx.session.client === 'slack'
224
276
  ? SLACK_FORMATTING_CONSTRAINTS_CONTENT
@@ -56,6 +56,21 @@ export interface SubagentToolOptions {
56
56
  /** Called after subagent completes with the full message history. Fire-and-forget. */
57
57
  onComplete?: (messages: BaseMessage[], task: string) => void;
58
58
  }
59
+ /**
60
+ * Filter subagent messages to only those whose tool name is in forwardTools.
61
+ * Returns AIMessages (with tool_calls filtered) and their matching ToolMessages.
62
+ *
63
+ * Rewrites each forwarded tool_call id with `idPrefix` so ids are unique
64
+ * across sub-agent invocations. Without this, each sub-agent run produces
65
+ * LangChain-generated ids like `functions.create_data_table:0` starting at
66
+ * 0, and two invocations in one chat collide — the frontend uses these
67
+ * ids as React keys and picks the wrong artifact.
68
+ *
69
+ * Exported so ad-hoc sub-agent runners (e.g. the editor's standalone tool,
70
+ * which spins up its own inner agent instead of going through
71
+ * `createSubagentAsTool`) forward with identical semantics.
72
+ */
73
+ export declare function filterForwardedMessages(messages: BaseMessage[], forwardTools: Set<string>, idPrefix: string): BaseMessage[];
59
74
  /**
60
75
  * Wraps an AgentSpec as a LangChain tool. When the parent agent calls this
61
76
  * tool with a task, an ephemeral agent runs (model + tools + systemPrompt)
@@ -1 +1 @@
1
- {"version":3,"file":"subagent-as-tool.d.ts","sourceRoot":"","sources":["../../src/graph/subagent-as-tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,WAAW,EACX,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,MAAM,WAAW,CAAC;AAInB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAQrD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,gBAAgB,CAAC,EAAE,cAAc,EAAE,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACnD,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,YAAY,CAAC,EACT,mBAAmB,GACnB,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACxD,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,sFAAsF;IACtF,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9D;AAsGD;;;;;;;GAOG;AACH;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,SAAS,EACf,OAAO,CAAC,EAAE,mBAAmB,GAC5B,cAAc,CA8HhB"}
1
+ {"version":3,"file":"subagent-as-tool.d.ts","sourceRoot":"","sources":["../../src/graph/subagent-as-tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,WAAW,EACX,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,MAAM,WAAW,CAAC;AAInB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAQrD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,gBAAgB,CAAC,EAAE,cAAc,EAAE,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACnD,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,YAAY,CAAC,EACT,mBAAmB,GACnB,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACxD,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,sFAAsF;IACtF,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9D;AA0CD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,WAAW,EAAE,EACvB,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,EACzB,QAAQ,EAAE,MAAM,GACf,WAAW,EAAE,CAkCf;AAYD;;;;;;;GAOG;AACH;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,SAAS,EACf,OAAO,CAAC,EAAE,mBAAmB,GAC5B,cAAc,CA8HhB"}
@@ -52,8 +52,12 @@ function lastMessageContent(messages) {
52
52
  * LangChain-generated ids like `functions.create_data_table:0` starting at
53
53
  * 0, and two invocations in one chat collide — the frontend uses these
54
54
  * ids as React keys and picks the wrong artifact.
55
+ *
56
+ * Exported so ad-hoc sub-agent runners (e.g. the editor's standalone tool,
57
+ * which spins up its own inner agent instead of going through
58
+ * `createSubagentAsTool`) forward with identical semantics.
55
59
  */
56
- function filterForwardedMessages(messages, forwardTools, idPrefix) {
60
+ export function filterForwardedMessages(messages, forwardTools, idPrefix) {
57
61
  const oldToNewId = new Map();
58
62
  return messages.reduce((acc, msg) => {
59
63
  if (msg.type === 'ai') {
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Convert a canonical IXO DID (`did:ixo:abc`) to its Matrix user id
3
+ * (`@did-ixo-abc:homeserver`).
4
+ *
5
+ * Matrix localparts disallow `:`, so the DID's colons become hyphens and the
6
+ * whole thing is prefixed with `@`. The DID already starts with `did`, so the
7
+ * result naturally reads `@did-ixo-…` — do NOT add an extra `did-` prefix.
8
+ * This is the inverse of the `@did-…` → `did:…` parse used by the Matrix
9
+ * listener bridge and `normalizeDid` in the editor's page-functions.
10
+ *
11
+ * @example
12
+ * didToMatrixUserId('did:ixo:abc', 'devmx.ixo.earth')
13
+ * // => '@did-ixo-abc:devmx.ixo.earth'
14
+ */
15
+ export declare function didToMatrixUserId(did: string, homeServer: string): string;
16
+ //# sourceMappingURL=user-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-id.d.ts","sourceRoot":"","sources":["../../src/matrix/user-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEzE"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Convert a canonical IXO DID (`did:ixo:abc`) to its Matrix user id
3
+ * (`@did-ixo-abc:homeserver`).
4
+ *
5
+ * Matrix localparts disallow `:`, so the DID's colons become hyphens and the
6
+ * whole thing is prefixed with `@`. The DID already starts with `did`, so the
7
+ * result naturally reads `@did-ixo-…` — do NOT add an extra `did-` prefix.
8
+ * This is the inverse of the `@did-…` → `did:…` parse used by the Matrix
9
+ * listener bridge and `normalizeDid` in the editor's page-functions.
10
+ *
11
+ * @example
12
+ * didToMatrixUserId('did:ixo:abc', 'devmx.ixo.earth')
13
+ * // => '@did-ixo-abc:devmx.ixo.earth'
14
+ */
15
+ export function didToMatrixUserId(did, homeServer) {
16
+ return `@${did.replace(/:/g, '-')}:${homeServer}`;
17
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"agent-builder.d.ts","sourceRoot":"","sources":["../../../src/modules/messages/agent-builder.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EACV,iBAAiB,EAElB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,QAAQ,EAAE,eAAe,CAAC;IAC1B,aAAa,EAAE,WAAW,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,iBAAiB,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC1C;;;;;;;;;;OAUG;IACH,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBACa,YAAY;IAIrB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAJrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;gBAGrC,YAAY,EAAE,yBAAyB,EACvC,kBAAkB,EAAE,kBAAkB;IAGnD,KAAK,CACT,IAAI,EAAE,cAAc,EACpB,eAAe,CAAC,EAAE,eAAe,GAChC,OAAO,CAAC,UAAU,CAAC;CA6LvB"}
1
+ {"version":3,"file":"agent-builder.d.ts","sourceRoot":"","sources":["../../../src/modules/messages/agent-builder.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EACV,iBAAiB,EAElB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAIjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,QAAQ,EAAE,eAAe,CAAC;IAC1B,aAAa,EAAE,WAAW,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,iBAAiB,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC1C;;;;;;;;;;OAUG;IACH,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBACa,YAAY;IAIrB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAJrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;gBAGrC,YAAY,EAAE,yBAAyB,EACvC,kBAAkB,EAAE,kBAAkB;IAGnD,KAAK,CACT,IAAI,EAAE,cAAc,EACpB,eAAe,CAAC,EAAE,eAAe,GAChC,OAAO,CAAC,UAAU,CAAC;CA6LvB"}
@@ -10,6 +10,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
10
10
  var AgentBuilder_1;
11
11
  import { Injectable, Logger } from '@nestjs/common';
12
12
  import { createMainAgent } from '../../graph/main-agent.js';
13
+ import { didToMatrixUserId } from '../../matrix/user-id.js';
13
14
  import { UserPreferencesService } from '../../plugins/user-preferences/service/user-preferences.service.js';
14
15
  import { OracleRuntimeBundleHolder } from './oracle-runtime-bundle.js';
15
16
  import { UserContextFetcher } from './user-context-fetcher.js';
@@ -142,7 +143,7 @@ let AgentBuilder = AgentBuilder_1 = class AgentBuilder {
142
143
  const requestCtx = {
143
144
  user: {
144
145
  did: payload.did,
145
- matrixUserId: `@did-${payload.did.replace(/:/g, '-')}:${prepared.homeServerName}`,
146
+ matrixUserId: didToMatrixUserId(payload.did, prepared.homeServerName),
146
147
  ucanDelegation,
147
148
  timezone: prepared.timezone,
148
149
  currentTime: prepared.currentTime,
@@ -1 +1 @@
1
- {"version":3,"file":"session-history-processor.service.d.ts","sourceRoot":"","sources":["../../../src/modules/sessions/session-history-processor.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAKzE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBACa,uBAAuB;IAIhC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa;IACP,OAAO,CAAC,QAAQ,CAAC,YAAY;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAR3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4C;gBAGhD,eAAe,EAAE,eAAe,EAChC,mBAAmB,EAAE,mBAAmB,EACxC,qBAAqB,EAAE,qBAAqB,EAC5C,aAAa,EAAE,aAAa,EACL,YAAY,EAAE,KAAK,EAC9B,WAAW,CAAC,EAAE,WAAW,YAAA;IAGxD;;;OAGG;IACG,qBAAqB,CACzB,MAAM,EAAE,2BAA2B,GAClC,OAAO,CAAC,IAAI,CAAC;YAuBF,8BAA8B;YAiC9B,6BAA6B;IAgJ3C;;;;;;;;OAQG;IACH,OAAO,CAAC,qCAAqC;IAyD7C;;;;;;;OAOG;YACW,sBAAsB;CAwBrC"}
1
+ {"version":3,"file":"session-history-processor.service.d.ts","sourceRoot":"","sources":["../../../src/modules/sessions/session-history-processor.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAKzE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBACa,uBAAuB;IAIhC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa;IACP,OAAO,CAAC,QAAQ,CAAC,YAAY;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAR3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4C;gBAGhD,eAAe,EAAE,eAAe,EAChC,mBAAmB,EAAE,mBAAmB,EACxC,qBAAqB,EAAE,qBAAqB,EAC5C,aAAa,EAAE,aAAa,EACL,YAAY,EAAE,KAAK,EAC9B,WAAW,CAAC,EAAE,WAAW,YAAA;IAGxD;;;OAGG;IACG,qBAAqB,CACzB,MAAM,EAAE,2BAA2B,GAClC,OAAO,CAAC,IAAI,CAAC;YAuBF,8BAA8B;YAiC9B,6BAA6B;IAgJ3C;;;;;;;;OAQG;IACH,OAAO,CAAC,qCAAqC;IAyD7C;;;;;;;OAOG;YACW,sBAAsB;CAwBrC"}
@@ -19,6 +19,7 @@ import { getMatrixHomeServerCroppedForDid } from '@ixo/oracles-chain-client';
19
19
  import { CACHE_MANAGER } from '@nestjs/cache-manager';
20
20
  import { Inject, Injectable, Logger, Optional } from '@nestjs/common';
21
21
  import { ConfigService } from '@nestjs/config';
22
+ import { didToMatrixUserId } from '../../matrix/user-id.js';
22
23
  import { UserPreferencesService } from '../../plugins/user-preferences/service/user-preferences.service.js';
23
24
  import { MessagesService } from '../messages/messages.service.js';
24
25
  import { UcanService } from '../ucan/ucan.service.js';
@@ -230,7 +231,7 @@ let SessionHistoryProcessor = SessionHistoryProcessor_1 = class SessionHistoryPr
230
231
  if (fromPrefs)
231
232
  return fromPrefs;
232
233
  try {
233
- const matrixUserId = `@did-${did.replace(/:/g, '-')}:${userHomeServer}`;
234
+ const matrixUserId = didToMatrixUserId(did, userHomeServer);
234
235
  const displayName = await MatrixManager.getInstance().getDisplayName(matrixUserId);
235
236
  const trimmed = displayName?.trim();
236
237
  if (trimmed)
@@ -1 +1 @@
1
- {"version":3,"file":"ucan.service.d.ts","sourceRoot":"","sources":["../../../src/modules/ucan/ucan.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ucan.service.d.ts","sourceRoot":"","sources":["../../../src/modules/ucan/ucan.service.ts"],"names":[],"mappings":"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"}
@@ -22,7 +22,7 @@ interface ClaimProcessingConfig {
22
22
  MATRIX_VALUE_PIN: string;
23
23
  SECP_MNEMONIC: string;
24
24
  SUBSCRIPTION_URL?: string;
25
- DISABLE_CREDITS?: boolean;
25
+ DISABLE_CREDITS?: string;
26
26
  }
27
27
  /**
28
28
  * Submits held-credit claims to the chain on a fixed cron. Pulls users with
@@ -1 +1 @@
1
- {"version":3,"file":"claim-processing.service.d.ts","sourceRoot":"","sources":["../../../src/plugins/credits/claim-processing.service.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAY/C,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,sFAAsF;AACtF,eAAO,MAAM,8BAA8B,eAE1C,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAQD,UAAU,qBAAqB;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC1C,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gCAAgC,EAAE,MAAM,CAAC;IACzC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA0BD;;;;;;;;;;;;;GAaG;AACH,qBACa,sBAAsB;IAc/B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAd9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2C;IAClE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAsB;IAClE,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;IAC/C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAE5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAI1B;gBAGiB,aAAa,EAAE,aAAa,CAAC,qBAAqB,CAAC,EACnD,WAAW,EAAE,WAAW,EAGzC,YAAY,CAAC,EAAE,YAAY;IA0C7B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAevB,sEAAsE;IACtE,OAAO,CAAC,gBAAgB,CAgDtB;IAEF,6EAA6E;IAC7E,OAAO,CAAC,gBAAgB,CA+DtB;IAEF,8EAA8E;IAC9E,OAAO,CAAC,iBAAiB,CAwCvB;IAEF,+EAA+E;IAC/E,OAAO,CAAC,iBAAiB,CAkBvB;IAEF;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAgB/B;;;;;OAKG;IAEG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAsIxC;;;OAGG;YACW,aAAa;CAyE5B;AAED;;;;GAIG;AACH,wBAAsB,4BAA4B,CAChD,kBAAkB,EAAE,MAAM,EAC1B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA0BjD"}
1
+ {"version":3,"file":"claim-processing.service.d.ts","sourceRoot":"","sources":["../../../src/plugins/credits/claim-processing.service.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAY/C,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,sFAAsF;AACtF,eAAO,MAAM,8BAA8B,eAE1C,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAQD,UAAU,qBAAqB;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC1C,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gCAAgC,EAAE,MAAM,CAAC;IACzC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAG1B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AA0BD;;;;;;;;;;;;;GAaG;AACH,qBACa,sBAAsB;IAc/B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAd9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2C;IAClE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAsB;IAClE,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;IAC/C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAE5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAI1B;gBAGiB,aAAa,EAAE,aAAa,CAAC,qBAAqB,CAAC,EACnD,WAAW,EAAE,WAAW,EAGzC,YAAY,CAAC,EAAE,YAAY;IAqC7B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAevB,sEAAsE;IACtE,OAAO,CAAC,gBAAgB,CAgDtB;IAEF,6EAA6E;IAC7E,OAAO,CAAC,gBAAgB,CA+DtB;IAEF,8EAA8E;IAC9E,OAAO,CAAC,iBAAiB,CAwCvB;IAEF,+EAA+E;IAC/E,OAAO,CAAC,iBAAiB,CAkBvB;IAEF;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAgB/B;;;;;OAKG;IAEG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IA0IxC;;;OAGG;YACW,aAAa;CAyE5B;AAED;;;;GAIG;AACH,wBAAsB,4BAA4B,CAChD,kBAAkB,EAAE,MAAM,EAC1B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA0BjD"}
@@ -75,11 +75,6 @@ let ClaimProcessingService = ClaimProcessingService_1 = class ClaimProcessingSer
75
75
  catch (err) {
76
76
  this.logger.error(`Failed to create claim processing folder: ${err instanceof Error ? err.message : String(err)}`, err instanceof Error ? err.stack : undefined);
77
77
  }
78
- // `@ixo/sqlite-saver` and `@langchain/langgraph` end up referencing two
79
- // structurally-identical `BaseCheckpointSaver` instances from
80
- // separately-resolved `@langchain/langgraph-checkpoint` copies (one via
81
- // core@1.1.42, one via core@1.1.45). Bridge once at construction so the
82
- // rest of the service sees a single langgraph-native type.
83
78
  const sqliteSaver = SqliteSaver.fromConnString(this.claimProcessingDbPath);
84
79
  this.claimProcessingCheckpointer =
85
80
  sqliteSaver;
@@ -247,10 +242,14 @@ let ClaimProcessingService = ClaimProcessingService_1 = class ClaimProcessingSer
247
242
  */
248
243
  async processHeldAmount() {
249
244
  const matrixAccountRoomId = this.configService.get('MATRIX_ACCOUNT_ROOM_ID');
250
- const disableCredits = Boolean(this.configService.get('DISABLE_CREDITS')) ||
245
+ // The env var is a string — `Boolean('false')` is true, so compare
246
+ // against the literal instead of truthiness.
247
+ const disableCredits = this.configService.get('DISABLE_CREDITS') === 'true' ||
251
248
  !matrixAccountRoomId;
252
249
  if (disableCredits) {
253
- this.logger.debug('Claims task submission skipped (DISABLE_CREDITS=true)');
250
+ this.logger.debug(matrixAccountRoomId
251
+ ? 'Claims task submission skipped (DISABLE_CREDITS=true)'
252
+ : 'Claims task submission skipped (MATRIX_ACCOUNT_ROOM_ID not set)');
254
253
  return;
255
254
  }
256
255
  const users = await this.tokenLimiter.listUsersWithHeldAmount(MINIMUM_CLAIM_THRESHOLD);
@@ -42,6 +42,10 @@ export declare class CreditsPlugin extends OraclePlugin {
42
42
  readonly configSchema: z.ZodObject<{
43
43
  SUBSCRIPTION_URL: z.ZodOptional<z.ZodURL>;
44
44
  SUBSCRIPTION_ORACLE_MCP_URL: z.ZodOptional<z.ZodURL>;
45
+ DISABLE_CREDITS: z.ZodPipe<z.ZodOptional<z.ZodEnum<{
46
+ true: "true";
47
+ false: "false";
48
+ }>>, z.ZodTransform<boolean, "true" | "false" | undefined>>;
45
49
  }, z.core.$strip>;
46
50
  readonly autoDetectHint = "DISABLE_CREDITS!=true";
47
51
  private readonly redis;
@@ -1 +1 @@
1
- {"version":3,"file":"credits.plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/credits/credits.plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,cAAc,EACf,MAAM,2BAA2B,CAAC;AAKnC,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACxB,MAAM,oBAAoB,CAAC;AAE5B,kDAAkD;AAClD,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACrB;;;;OAIG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAcD;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAc,SAAQ,YAAY;IAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,aAAa;IAEjC,QAAQ,CAAC,IAAI,aAAsB;IAEnC,QAAQ,CAAC,OAAO,WAAW;IAE3B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAQ/B;IAEF,SAAkB,YAAY;;;sBAAuB;IAErD,SAAkB,cAAc,2BAA2B;IAE3D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IAErC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAiB;IAE1C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAqB;gBAE7C,OAAO,GAAE,oBAAyB;IAOrC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO;IAI3C,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,eAAe,EAAE;IAsBrD,cAAc,IAAI,KAAK,CAAC,IAAI,GAAG,aAAa,CAAC;CA2BvD"}
1
+ {"version":3,"file":"credits.plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/credits/credits.plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,cAAc,EACf,MAAM,2BAA2B,CAAC;AAKnC,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACxB,MAAM,oBAAoB,CAAC;AAE5B,kDAAkD;AAClD,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACrB;;;;OAIG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAsBD;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAc,SAAQ,YAAY;IAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,aAAa;IAEjC,QAAQ,CAAC,IAAI,aAAsB;IAEnC,QAAQ,CAAC,OAAO,WAAW;IAE3B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAQ/B;IAEF,SAAkB,YAAY;;;;;;;sBAAuB;IAErD,SAAkB,cAAc,2BAA2B;IAE3D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IAErC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAiB;IAE1C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAqB;gBAE7C,OAAO,GAAE,oBAAyB;IAOrC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO;IAI3C,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,eAAe,EAAE;IAsBrD,cAAc,IAAI,KAAK,CAAC,IAAI,GAAG,aAAa,CAAC;CA2BvD"}
@@ -8,6 +8,12 @@ import { TokenLimiter, } from './token-limiter.js';
8
8
  const CreditsConfigSchema = z.object({
9
9
  SUBSCRIPTION_URL: z.url().optional(),
10
10
  SUBSCRIPTION_ORACLE_MCP_URL: z.url().optional(),
11
+ // Env vars are strings — coerce here so consumers get a real boolean
12
+ // (`Boolean('false')` is true; only the literal 'true' disables credits).
13
+ DISABLE_CREDITS: z
14
+ .enum(['true', 'false'])
15
+ .optional()
16
+ .transform((v) => v === 'true'),
11
17
  });
12
18
  /**
13
19
  * Owns the full credit lifecycle:
@@ -58,7 +64,7 @@ export class CreditsPlugin extends OraclePlugin {
58
64
  const limiter = new TokenLimiter({
59
65
  redis,
60
66
  network: config.NETWORK ?? 'devnet',
61
- disableCredits: config.DISABLE_CREDITS ?? false,
67
+ disableCredits: config.DISABLE_CREDITS,
62
68
  modelPricingLookup: this.modelPricingLookup,
63
69
  logger: ctx.logger,
64
70
  });
@@ -1 +1 @@
1
- {"version":3,"file":"domain-indexer-tools.d.ts","sourceRoot":"","sources":["../../../src/plugins/domain-indexer/domain-indexer-tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAiL5D;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAgDtE"}
1
+ {"version":3,"file":"domain-indexer-tools.d.ts","sourceRoot":"","sources":["../../../src/plugins/domain-indexer/domain-indexer-tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAqM5D;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAgDtE"}
@@ -25,8 +25,9 @@ const searchSchema = z.object({
25
25
  .describe('Optional: Comma-separated list of scopes to search: domain_cards (default), agents, compositions, events. Use "domain_cards" to find organizations/projects/DAOs with summaries and FAQs.'),
26
26
  filters: z.record(z.string(), z.string()).optional()
27
27
  .describe(`Optional filters as key-value pairs. Examples:
28
+ - {"dc.entity_type": "dao/pod"} - Filter by exact chain entity type (e.g. dao/pod, dao/protocol, dao — compound types are preserved, not split)
29
+ - {"dc.entity_verified": "true"} - Only verified entities (chain-sourced: true/false/omit for all)
28
30
  - {"dc.categories": "dao,project"} - Filter by categories
29
- - {"dc.entity_type": "dao"} - Filter by entity type
30
31
  - {"dc.has_url": "true"} - Only entities with URLs
31
32
  - {"dc.keywords": "blockchain,web3"} - Filter by keywords
32
33
  - {"agent.domain_card_id": "did:ixo:entity:ixoworld"} - Agents for specific entity
@@ -84,11 +85,27 @@ WORKFLOW:
84
85
  5. If you need more complete information, use get_domain_card with the entity's DID (found in record.id)
85
86
 
86
87
  FILTERS (optional):
87
- - Domain cards: dc.categories (comma-separated), dc.entity_type, dc.keywords, dc.issuer, dc.has_url (true/false), dc.has_logo (true/false), dc.valid_from_gte (ISO date), dc.valid_from_lte (ISO date), dc.bbox (minLng,minLat,maxLng,maxLat), dc.near (lng,lat), dc.radius (meters)
88
+ - Domain cards:
89
+ - dc.entity_type: exact chain entity type — "dao/pod" for pods, "dao/protocol" for protocol DAOs, "dao" for plain DAOs. Compound types are never split; "dao/pod" and "dao" are distinct values.
90
+ - dc.entity_verified: "true" or "false" — chain-verified status. Omit to include both.
91
+ - dc.categories: comma-separated category values
92
+ - dc.keywords: comma-separated keywords
93
+ - dc.issuer: DID of the issuer
94
+ - dc.has_url: "true"/"false" — whether entity has a URL
95
+ - dc.has_logo: "true"/"false" — whether entity has a logo
96
+ - dc.valid_from_gte / dc.valid_from_lte: ISO datetime bounds
97
+ - dc.bbox: minLng,minLat,maxLng,maxLat (geo bounding box)
98
+ - dc.near + dc.radius: lng,lat and radius in km (geo proximity)
88
99
  - Agents: agent.domain_card_id, agent.has_url (true/false)
89
100
  - Compositions: comp.domain_card_id, comp.creator, comp.has_url (true/false)
90
101
  - Events: event.domain_card_id, event.from (ISO date), event.to (ISO date), event.location
91
102
 
103
+ ENTITY TYPE EXAMPLES:
104
+ - Find all pods: {"dc.entity_type": "dao/pod"}
105
+ - Find protocol DAOs: {"dc.entity_type": "dao/protocol"}
106
+ - Find verified entities of type protocol/dao: {"dc.entity_type": "dao/protocol", "dc.entity_verified": "true"}
107
+ - "verified entities of type protocol/dao relevant to mining" → query: "mining", filters: {"dc.entity_type": "dao/protocol", "dc.entity_verified": "true"}
108
+
92
109
  IMPORTANT: Always check the 'record' field in results for summary, overview, and faq data. These fields contain the curated information about the entity.`;
93
110
  const CARD_DESCRIPTION = `Get essential domain card details by DID (Decentralized Identifier) including summary, overview, FAQs, and key information. Returns only essential fields to optimize context usage.
94
111
 
@@ -119,7 +136,8 @@ WHAT IT RETURNS (filtered to essential fields only):
119
136
  - faq: Array of FAQ objects with question and answer fields
120
137
  - url: Entity website URL
121
138
  - keywords: Array of keywords
122
- - entity_type: Array of entity types
139
+ - entity_type: Array containing the chain entity type (e.g. ["dao/pod"], ["dao/protocol"], ["dao"])
140
+ - entity_verified: boolean or null — whether the entity is verified on-chain (null means not yet determined)
123
141
 
124
142
  WORKFLOW:
125
143
  1. First use domain_indexer_search to find entities
@@ -143,6 +161,7 @@ function projectDomainCard(card) {
143
161
  url: c.url,
144
162
  keywords: c.keywords ?? [],
145
163
  entity_type: c.entity_type ?? [],
164
+ entity_verified: c.entity_verified ?? null,
146
165
  };
147
166
  }
148
167
  /**
@@ -0,0 +1,21 @@
1
+ import type { StructuredTool } from 'langchain';
2
+ import type { EditorUnavailableReason } from './prompts.js';
3
+ export interface EditorAccessDeniedToolOptions {
4
+ /** The page room the client reported open. */
5
+ editorRoomId: string;
6
+ /** Why the real editor surface refused to bind. */
7
+ reason: EditorUnavailableReason;
8
+ }
9
+ /**
10
+ * Stand-in for `call_editor_agent` bound when a page is open but the real
11
+ * editor surface refused to attach (the user is not a verified member of the
12
+ * page's room, or the sub-agent build failed).
13
+ *
14
+ * Without it, the model is shown an "editor" capability it cannot reach and
15
+ * either narrates its sub-agent task as user-facing text or hunts through
16
+ * `list_capabilities`/`load_capability` for a tool that will never appear.
17
+ * With it, any editor call returns the denial so the model can report the
18
+ * real reason to the user.
19
+ */
20
+ export declare function createEditorAccessDeniedTool(options: EditorAccessDeniedToolOptions): StructuredTool;
21
+ //# sourceMappingURL=editor-access-denied-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-access-denied-tool.d.ts","sourceRoot":"","sources":["../../../src/plugins/editor/editor-access-denied-tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGhD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAQ5D,MAAM,WAAW,6BAA6B;IAC5C,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,MAAM,EAAE,uBAAuB,CAAC;CACjC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,6BAA6B,GACrC,cAAc,CAqBhB"}
@@ -0,0 +1,37 @@
1
+ import { tool } from '@langchain/core/tools';
2
+ import { z } from 'zod';
3
+ import { EDITOR_AGENT_TOOL_NAME } from './editor-agent.js';
4
+ // Mirrors the real sub-agent tool's schema so a model that composed a task
5
+ // for the editor still produces a valid call — the answer is just the denial.
6
+ const taskSchema = z.object({
7
+ task: z.string().describe('The task you intended to send to the editor.'),
8
+ });
9
+ /**
10
+ * Stand-in for `call_editor_agent` bound when a page is open but the real
11
+ * editor surface refused to attach (the user is not a verified member of the
12
+ * page's room, or the sub-agent build failed).
13
+ *
14
+ * Without it, the model is shown an "editor" capability it cannot reach and
15
+ * either narrates its sub-agent task as user-facing text or hunts through
16
+ * `list_capabilities`/`load_capability` for a tool that will never appear.
17
+ * With it, any editor call returns the denial so the model can report the
18
+ * real reason to the user.
19
+ */
20
+ export function createEditorAccessDeniedTool(options) {
21
+ const { editorRoomId, reason } = options;
22
+ // Membership is resolved with the oracle's admin identity, so a failed
23
+ // check can mean either side is missing — the user OR the oracle itself
24
+ // (the lookup is forbidden and fails closed). Keep the wording unified.
25
+ const message = reason === 'not-member'
26
+ ? `Editor unavailable: membership of the page's room (${editorRoomId}) could not be verified — ` +
27
+ `either the user's account or this oracle is not a member of it, and BOTH must be members for page access. ` +
28
+ `Tell the user: the page can't be read or edited because either they or this oracle is missing from the page's room; ` +
29
+ `inviting this oracle to the page (or opening a page they own) fixes it. Do not retry this tool.`
30
+ : `Editor unavailable: the editor service failed to attach to the page's room (${editorRoomId}). ` +
31
+ `Tell the user the page editor is currently unavailable and they can retry shortly. Do not retry this tool.`;
32
+ return tool(async () => message, {
33
+ name: EDITOR_AGENT_TOOL_NAME,
34
+ description: 'Editor Agent (unavailable for this request — calls return the denial reason).',
35
+ schema: taskSchema,
36
+ });
37
+ }
@@ -2,6 +2,17 @@ import type { PluginSubAgent } from '../../plugin-api/types.js';
2
2
  import { type BlocknoteToolsConfig } from './blocknote-tools.js';
3
3
  import { type BlobStoreCapable, type UcanMintCapable } from './mint-invocation-tool.js';
4
4
  import type { AppConfig, MatrixRoomConfig } from './provider.js';
5
+ /** Default sub-agent name surfaced to the main agent. */
6
+ export declare const EDITOR_AGENT_NAME = "Editor Agent";
7
+ /**
8
+ * The tool name the main agent sees for the editor surface — identical for
9
+ * the room-bound sub-agent (derived via `computeSubAgentToolName`) and the
10
+ * standalone tool (which sets it directly). The prompt composer checks this
11
+ * name to decide whether the editor-mode prompts may be injected: telling the
12
+ * model "EDITOR MODE ACTIVE — use the Editor Agent tool" without this tool
13
+ * bound makes it narrate its sub-agent task as user-facing text.
14
+ */
15
+ export declare const EDITOR_AGENT_TOOL_NAME: string;
5
16
  type AppConfigOverrides = {
6
17
  matrix?: Partial<AppConfig['matrix']>;
7
18
  provider?: Partial<AppConfig['provider']>;
@@ -1 +1 @@
1
- {"version":3,"file":"editor-agent.d.ts","sourceRoot":"","sources":["../../../src/plugins/editor/editor-agent.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EACL,KAAK,oBAAoB,EAE1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AASjE,KAAK,kBAAkB,GAAG;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC;CAC7C,CAAC;AA+DF,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,UAAU,CAAC;AAElD,MAAM,WAAW,0BAA0B;IACzC,uEAAuE;IACvE,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAChC,gEAAgE;IAChE,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,2EAA2E;IAC3E,WAAW,EAAE,oBAAoB,CAAC;IAClC,yDAAyD;IACzD,eAAe,CAAC,EAAE,kBAAkB,CAAC;IACrC,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4FAA4F;IAC5F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;sDAEkD;IAClD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B;;;2CAGuC;IACvC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA6FD;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,0BAA0B,GACjC,OAAO,CAAC,cAAc,CAAC,CAyFzB"}
1
+ {"version":3,"file":"editor-agent.d.ts","sourceRoot":"","sources":["../../../src/plugins/editor/editor-agent.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjE,yDAAyD;AACzD,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAEhD;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,QACS,CAAC;AAS7C,KAAK,kBAAkB,GAAG;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC;CAC7C,CAAC;AA+DF,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,UAAU,CAAC;AAElD,MAAM,WAAW,0BAA0B;IACzC,uEAAuE;IACvE,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAChC,gEAAgE;IAChE,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,2EAA2E;IAC3E,WAAW,EAAE,oBAAoB,CAAC;IAClC,yDAAyD;IACzD,eAAe,CAAC,EAAE,kBAAkB,CAAC;IACrC,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4FAA4F;IAC5F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;sDAEkD;IAClD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B;;;2CAGuC;IACvC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA6FD;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,0BAA0B,GACjC,OAAO,CAAC,cAAc,CAAC,CAkFzB"}
@@ -1,9 +1,21 @@
1
+ import { computeSubAgentToolName } from '../../graph/subagent-as-tool.js';
1
2
  import { tool as pluginTool } from '../../plugin-api/tool-helper.js';
2
3
  import { createBlocknoteTools, } from './blocknote-tools.js';
3
4
  import { resolveEditorMatrixClient } from './editor-mx.js';
4
5
  import { createMintInvocationEditorTool, } from './mint-invocation-tool.js';
5
6
  import { createPageTools } from './page-tools.js';
6
7
  import { editorAgentPrompt, editorAgentReadOnlyPrompt } from './prompts.js';
8
+ /** Default sub-agent name surfaced to the main agent. */
9
+ export const EDITOR_AGENT_NAME = 'Editor Agent';
10
+ /**
11
+ * The tool name the main agent sees for the editor surface — identical for
12
+ * the room-bound sub-agent (derived via `computeSubAgentToolName`) and the
13
+ * standalone tool (which sets it directly). The prompt composer checks this
14
+ * name to decide whether the editor-mode prompts may be injected: telling the
15
+ * model "EDITOR MODE ACTIVE — use the Editor Agent tool" without this tool
16
+ * bound makes it narrate its sub-agent task as user-facing text.
17
+ */
18
+ export const EDITOR_AGENT_TOOL_NAME = computeSubAgentToolName(EDITOR_AGENT_NAME);
7
19
  const normalizeRoom = (room) => {
8
20
  if (typeof room === 'string') {
9
21
  return { type: 'id', value: room };
@@ -96,7 +108,7 @@ function wrapStructuredTool(t) {
96
108
  * first call with the credentials carried in `toolsConfig`.
97
109
  */
98
110
  export async function createEditorSubAgent(params) {
99
- const { room, mode = 'edit', toolsConfig, configOverrides, name = 'Editor Agent', description = 'AI Agent that reads and writes pages and blocks in the BlockNote editor.', userMatrixId, spaceId, ucanService, blobStore, userDid, } = params;
111
+ const { room, mode = 'edit', toolsConfig, configOverrides, name = EDITOR_AGENT_NAME, description = 'AI Agent that reads and writes pages and blocks in the BlockNote editor.', userMatrixId, spaceId, ucanService, blobStore, userDid, } = params;
100
112
  const roomConfig = normalizeRoom(room);
101
113
  const matrixClient = await resolveEditorMatrixClient({
102
114
  baseUrl: toolsConfig.matrix.baseUrl,
@@ -142,17 +154,10 @@ export async function createEditorSubAgent(params) {
142
154
  tools,
143
155
  model: 'subagent',
144
156
  middlewares: [],
145
- // Bubble the page + block mutation events into the main chat so the FE
146
- // renders artifact previews and edit confirmations inline. Names absent
147
- // in the read-only toolset are simply nothing-to-forward. `mint_invocation`
148
- // is forwarded so the main agent sees the returned `blobId` and can pass
149
- // it straight to `sandbox_write_blob`.
150
- forwardTools: [
151
- 'create_page',
152
- 'update_page',
153
- 'edit_block',
154
- 'create_block',
155
- 'mint_invocation',
156
- ],
157
+ // Forward EVERY tool call (reads and writes) into the main chat so the
158
+ // FE renders page/block activity inline and the main agent sees results
159
+ // directly e.g. `mint_invocation`'s `blobId`, which it passes straight
160
+ // to `sandbox_write_blob`.
161
+ forwardTools: true,
157
162
  };
158
163
  }
@@ -1 +1 @@
1
- {"version":3,"file":"editor.plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/editor/editor.plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,UAAU,EACV,cAAc,EACf,MAAM,2BAA2B,CAAC;AAUnC;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AA2FD;;;;;;;;;GASG;AACH,qBAAa,YAAa,SAAQ,YAAY;IAC5C,MAAM,CAAC,QAAQ,CAAC,IAAI,YAAY;IAEhC,QAAQ,CAAC,IAAI,YAAqB;IAElC,QAAQ,CAAC,OAAO,WAAW;IAE3B,QAAQ,CAAC,QAAQ,iBAAY;IAK7B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAe;gBAEjC,OAAO,GAAE,mBAAwB;IAK9B,mBAAmB,CAChC,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,cAAc,EAAE,CAAC;IAwCb,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;CAyD7E"}
1
+ {"version":3,"file":"editor.plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/editor/editor.plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,UAAU,EACV,cAAc,EACf,MAAM,2BAA2B,CAAC;AAanC;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AA2FD;;;;;;;;;GASG;AACH,qBAAa,YAAa,SAAQ,YAAY;IAC5C,MAAM,CAAC,QAAQ,CAAC,IAAI,YAAY;IAEhC,QAAQ,CAAC,IAAI,YAAqB;IAElC,QAAQ,CAAC,OAAO,WAAW;IAE3B,QAAQ,CAAC,QAAQ,iBAAY;IAK7B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAe;gBAEjC,OAAO,GAAE,mBAAwB;IAK9B,mBAAmB,CAChC,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,cAAc,EAAE,CAAC;IAwCb,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;CAyD7E"}
@@ -4,7 +4,7 @@ import { OraclePlugin } from '../../plugin-api/oracle-plugin.js';
4
4
  import { SandboxPlugin } from '../sandbox/index.js';
5
5
  import { createApplySandboxOutputTool } from './apply-sandbox-output.js';
6
6
  import { buildBlocknoteToolsConfig, } from './blocknote-tools.js';
7
- import { createEditorSubAgent } from './editor-agent.js';
7
+ import { createEditorSubAgent, EDITOR_AGENT_TOOL_NAME, } from './editor-agent.js';
8
8
  import { createStandaloneEditorTool } from './standalone-editor-tool.js';
9
9
  /**
10
10
  * Internal parse schema for `parseToolsConfig`. These 3 env vars already
@@ -42,17 +42,17 @@ const manifest = {
42
42
  {
43
43
  user: 'Summarize the current page.',
44
44
  thought: 'Delegate to the Editor sub-agent with the active room. It will read the page and return a summary.',
45
- tool: 'call_editor_agent',
45
+ tool: EDITOR_AGENT_TOOL_NAME,
46
46
  },
47
47
  {
48
48
  user: 'Set the status block to completed.',
49
49
  thought: 'Page edit — delegate with explicit block target + new value. Never paraphrase block IDs or status names.',
50
- tool: 'call_editor_agent',
50
+ tool: EDITOR_AGENT_TOOL_NAME,
51
51
  },
52
52
  ],
53
53
  tags: ['editor', 'blocknote', 'pages', 'documents'],
54
54
  category: 'data',
55
- visibility: 'on-demand',
55
+ visibility: 'always',
56
56
  stability: 'stable',
57
57
  };
58
58
  function parseToolsConfig(cfg, matrixClient) {
@@ -1,6 +1,7 @@
1
1
  export { EditorPlugin } from './editor.plugin.js';
2
- export { createEditorSubAgent, type CreateEditorSubAgentParams, type EditorAgentMode, } from './editor-agent.js';
2
+ export { createEditorSubAgent, EDITOR_AGENT_NAME, EDITOR_AGENT_TOOL_NAME, type CreateEditorSubAgentParams, type EditorAgentMode, } from './editor-agent.js';
3
3
  export { createStandaloneEditorTool } from './standalone-editor-tool.js';
4
+ export { createEditorAccessDeniedTool, type EditorAccessDeniedToolOptions, } from './editor-access-denied-tool.js';
4
5
  export { createApplySandboxOutputTool } from './apply-sandbox-output.js';
5
6
  export { buildBlocknoteToolsConfig, type BlocknoteToolsConfig, type BlocknoteToolsMatrixConfig, } from './blocknote-tools.js';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/editor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,oBAAoB,EACpB,KAAK,0BAA0B,EAC/B,KAAK,eAAe,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,EACL,yBAAyB,EACzB,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,GAChC,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/editor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,KAAK,0BAA0B,EAC/B,KAAK,eAAe,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EACL,4BAA4B,EAC5B,KAAK,6BAA6B,GACnC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,EACL,yBAAyB,EACzB,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,GAChC,MAAM,sBAAsB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export { EditorPlugin } from './editor.plugin.js';
2
- export { createEditorSubAgent, } from './editor-agent.js';
2
+ export { createEditorSubAgent, EDITOR_AGENT_NAME, EDITOR_AGENT_TOOL_NAME, } from './editor-agent.js';
3
3
  export { createStandaloneEditorTool } from './standalone-editor-tool.js';
4
+ export { createEditorAccessDeniedTool, } from './editor-access-denied-tool.js';
4
5
  export { createApplySandboxOutputTool } from './apply-sandbox-output.js';
5
6
  export { buildBlocknoteToolsConfig, } from './blocknote-tools.js';
@@ -1 +1 @@
1
- {"version":3,"file":"page-functions.d.ts","sourceRoot":"","sources":["../../../src/plugins/editor/page-functions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"page-functions.d.ts","sourceRoot":"","sources":["../../../src/plugins/editor/page-functions.ts"],"names":[],"mappings":"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"}
@@ -107,15 +107,31 @@ export async function createPage(params) {
107
107
  });
108
108
  const roomId = createRoomResponse.room_id;
109
109
  logger.log(`Page room created: ${roomId}`);
110
- // If parent space exists, add the room as a child of the space
110
+ // Link the page under its space by writing m.space.child INTO the space room.
111
+ // The oracle admin (this matrixClient) must be a member of the space with
112
+ // permission to send that state event. It may have been invited during space
113
+ // provisioning but not yet joined, so try to join first. If the admin has no
114
+ // access to the user's space this is expected to fail (M_FORBIDDEN) — the page
115
+ // still carries its m.space.parent claim (set in initial_state) and the
116
+ // returned spaceId, so a client acting as the user (who IS in the space) can
117
+ // complete the link.
111
118
  if (parentSpaceId) {
112
119
  try {
120
+ const adminInSpace = matrixClient.getRoom(parentSpaceId)?.getMember(creatorId)
121
+ ?.membership === 'join';
122
+ if (!adminInSpace) {
123
+ await matrixClient.joinRoom(parentSpaceId);
124
+ }
113
125
  await matrixClient.sendStateEvent(parentSpaceId,
114
126
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
115
127
  'm.space.child', { via: [homeserver] }, roomId);
128
+ logger.log(`Linked page ${roomId} under space ${parentSpaceId}`);
116
129
  }
117
130
  catch (error) {
118
- logger.warn(`Failed to add page as child of space ${parentSpaceId}: ${error}`);
131
+ logger.warn(`Could not link page ${roomId} under space ${parentSpaceId}: the oracle ` +
132
+ `admin lacks membership/permission in that space. The page keeps its ` +
133
+ `m.space.parent claim and the returned spaceId — a user-authorized ` +
134
+ `client can complete the m.space.child link. (${error})`);
119
135
  }
120
136
  }
121
137
  // Parse markdown content into BlockNote blocks if provided
@@ -220,7 +236,6 @@ export async function updatePage(params) {
220
236
  let oldContentMd = '';
221
237
  if (content !== undefined || appendContent !== undefined) {
222
238
  const oldBlocks = serverEditor.yXmlFragmentToBlocks(doc.getXmlFragment('document'));
223
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
224
239
  oldContentMd = await serverEditor.blocksToMarkdownLossy(oldBlocks);
225
240
  }
226
241
  doc.transact(() => {
@@ -252,7 +267,6 @@ export async function updatePage(params) {
252
267
  // Snapshot new content as markdown (for diff) after mutations
253
268
  if (content !== undefined || appendContent !== undefined) {
254
269
  const newBlocks = serverEditor.yXmlFragmentToBlocks(doc.getXmlFragment('document'));
255
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
256
270
  const newContentMd = await serverEditor.blocksToMarkdownLossy(newBlocks);
257
271
  diff.content = { old: oldContentMd, new: newContentMd };
258
272
  }
@@ -17,6 +17,22 @@ export declare const STANDALONE_EDITOR_PROMPTS: {
17
17
  operationalMode: string;
18
18
  editorSection: string;
19
19
  };
20
+ /** Why the editor surface could not be attached to this request. */
21
+ export type EditorUnavailableReason = 'not-member' | 'bind-error';
22
+ /**
23
+ * Operational-mode block injected when a page is open in the client
24
+ * (`editorRoomId`) but the editor surface refused to bind — the user is not
25
+ * a verified member of the page's room, or the sub-agent build failed.
26
+ *
27
+ * Paired with the stub `call_editor_agent` tool (see
28
+ * `createEditorAccessDeniedTool`): even a model that skips this block and
29
+ * calls the editor anyway learns the denial from the tool result instead of
30
+ * narrating its sub-agent task as user-facing text.
31
+ */
32
+ export declare function editorUnavailableMode(options: {
33
+ editorRoomId: string;
34
+ reason: EditorUnavailableReason;
35
+ }): string;
20
36
  export declare const editorAgentPrompt: string;
21
37
  export declare const editorAgentReadOnlyPrompt: string;
22
38
  //# sourceMappingURL=prompts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/plugins/editor/prompts.ts"],"names":[],"mappings":"AAyFA,eAAO,MAAM,4BAA4B,2tQAmHrC,CAAC;AAEL,eAAO,MAAM,sCAAsC,2/GAiE/C,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;;;CAwH/B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,yBAAyB;;;CA0CrC,CAAC;AAEF,eAAO,MAAM,iBAAiB,QAItB,CAAC;AAET,eAAO,MAAM,yBAAyB,QAI9B,CAAC"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/plugins/editor/prompts.ts"],"names":[],"mappings":"AAyFA,eAAO,MAAM,4BAA4B,2tQAmHrC,CAAC;AAEL,eAAO,MAAM,sCAAsC,2/GAiE/C,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;;;CAwH/B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,yBAAyB;;;CA8CrC,CAAC;AAEF,oEAAoE;AACpE,MAAM,MAAM,uBAAuB,GAAG,YAAY,GAAG,YAAY,CAAC;AAElE;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,uBAAuB,CAAC;CACjC,GAAG,MAAM,CAwBT;AAED,eAAO,MAAM,iBAAiB,QAItB,CAAC;AAET,eAAO,MAAM,yBAAyB,QAI9B,CAAC"}
@@ -308,7 +308,7 @@ For read-only operations (reading, listing, summarizing), always proceed without
308
308
  confirmation — only pause when about to write or edit.
309
309
 
310
310
  **Page Management:**
311
- - **Create page:** Delegate to the Editor Agent — it has the \`create_page\` tool. Example: call_editor_agent with "Create a new page titled 'Meeting Notes' with the following content: ..."
311
+ - **Create page:** Delegate to the Editor Agent — it has the \`create_page\` tool, which creates a **brand-new page room under the user's space automatically**. You do NOT supply, look up, or know a room ID to create a page — \`create_page\` generates the room and returns the new \`roomId\`. Example: call_editor_agent with "Create a new page titled 'Meeting Notes' with the following content: ..."
312
312
  - **List pages:** Use the \`list_workspace_pages\` browser tool to list all pages in the user's workspace. This runs on the client side and returns page names, room IDs, and types.
313
313
  - **Edit/read a specific page by name:** When the user asks to edit or read a page and you don't have its room ID:
314
314
  1. Call \`list_workspace_pages\` (browser tool) to find the page by name and get its room ID
@@ -404,22 +404,26 @@ You have \`call_editor_agent\` which starts an Editor Agent subagent for any pag
404
404
 
405
405
  **⚠️ Pages are BlockNote documents — NOT entities.** Pages are collaborative documents in the user's workspace. They are completely separate from IXO blockchain entities. NEVER use the Domain Indexer Agent for page operations — it has no knowledge of pages. ALL page operations (list, read, edit, create, update) go through \`list_workspace_pages\` and \`call_editor_agent\`.
406
406
 
407
- **Workflow for ANY page-related request (read, edit, update, create, list):**
407
+ **Creating a NEW page:**
408
+ - To create a new page, call \`call_editor_agent\` with ONLY a \`task\` and **NO \`room_id\`**. \`create_page\` makes a fresh page room under the user's space automatically and returns the new \`roomId\` — you never provide, look up, or guess a room ID to create a page.
409
+ - Example: \`call_editor_agent({ task: "Create a new page titled 'Meeting Notes' with a short agenda" })\`
410
+
411
+ **Workflow for reading/editing an EXISTING page:**
408
412
  1. Use \`list_workspace_pages\` (browser tool) to discover pages and their room IDs
409
- 2. Call \`call_editor_agent\` with the \`room_id\` and your editing \`task\`
410
- 3. The editor agent has full capabilities: list/edit/create/delete blocks, read/update/create pages, surveys, find-and-replace, bulk edits
413
+ 2. Call \`call_editor_agent\` with the \`room_id\` AND your editing \`task\`
414
+ 3. The editor agent has full capabilities: list/edit/create/delete blocks, read/update pages, surveys, find-and-replace, bulk edits
411
415
 
412
416
  **⚠️ Parameter format — room_id and task are SEPARATE fields:**
413
- - \`room_id\`: ONLY the Matrix room ID string (starts with "!", contains ":"). Nothing else.
417
+ - \`room_id\`: the Matrix room ID of an EXISTING page (starts with "!", contains ":"). **OMIT it entirely to CREATE a new page.**
414
418
  - \`task\`: ONLY the detailed, self-contained instruction. No room IDs here.
415
419
 
416
420
  **Examples (correct):**
417
- - \`call_editor_agent({ room_id: "!abc:server.example", task: "Read this page and summarize its content" })\`
418
- - \`call_editor_agent({ room_id: "!abc:server.example", task: "Find the status block and set it to completed" })\`
419
- - \`call_editor_agent({ room_id: "!abc:server.example", task: "Create a new page titled 'Meeting Notes'" })\`
420
- - \`call_editor_agent({ room_id: "!abc:server.example", task: "Shorten the content by 50% while keeping key points" })\`
421
+ - Create (no room_id): \`call_editor_agent({ task: "Create a new page titled 'Meeting Notes'" })\`
422
+ - Read: \`call_editor_agent({ room_id: "!abc:server.example", task: "Read this page and summarize its content" })\`
423
+ - Edit: \`call_editor_agent({ room_id: "!abc:server.example", task: "Find the status block and set it to completed" })\`
424
+ - Rewrite: \`call_editor_agent({ room_id: "!abc:server.example", task: "Shorten the content by 50% while keeping key points" })\`
421
425
 
422
- **Important:** Always get the room ID from \`list_workspace_pages\` first — never guess room IDs.
426
+ **Important:** When editing an existing page, get the room ID from \`list_workspace_pages\` first — never guess room IDs. Creating a page needs no room ID.
423
427
 
424
428
  **Page Context Switches:**
425
429
  The user may switch pages mid-conversation. When tool results (read_page, list_blocks)
@@ -439,6 +443,38 @@ Never send vague or empty tasks — the editor agent cannot infer intent from yo
439
443
 
440
444
  When a skill needs to authenticate against an external UCAN-gated service: call \`call_editor_agent\` with a task naming \`mint_invocation\` and the required args (\`delegationCid\`, \`serviceUrl\`, \`can\`, \`withResource\` — all from the companion prompt). The tool returns \`{ blobId, invocation, ... }\`. **Use \`blobId\` — pass it to \`sandbox_write_blob({ blobId, path: "/workspace/data/<skill>/ucan_token" })\`** so the runtime writes the value via \`sandbox_write_file\` without the long base64 CAR ever entering this conversation. Single-use; re-mint per protected call; expire ~90s so write the blob immediately. On "blob not found", re-mint and retry.`,
441
445
  };
446
+ /**
447
+ * Operational-mode block injected when a page is open in the client
448
+ * (`editorRoomId`) but the editor surface refused to bind — the user is not
449
+ * a verified member of the page's room, or the sub-agent build failed.
450
+ *
451
+ * Paired with the stub `call_editor_agent` tool (see
452
+ * `createEditorAccessDeniedTool`): even a model that skips this block and
453
+ * calls the editor anyway learns the denial from the tool result instead of
454
+ * narrating its sub-agent task as user-facing text.
455
+ */
456
+ export function editorUnavailableMode(options) {
457
+ const { editorRoomId, reason } = options;
458
+ // The membership lookup runs with the oracle's admin identity, so a failure
459
+ // can mean EITHER side is missing from the room: the user isn't a member,
460
+ // or the oracle itself isn't (the lookup is forbidden and fails closed).
461
+ // The check can't tell those apart — the wording stays unified.
462
+ const why = reason === 'not-member'
463
+ ? `membership of the page's room (\`${editorRoomId}\`) could not be verified — either the user's account or this oracle is not a member of it, and BOTH must be members for the editor to attach`
464
+ : `the editor service failed to attach to the page's room (\`${editorRoomId}\`)`;
465
+ const tellUser = reason === 'not-member'
466
+ ? "the page room membership could not be verified — either their account or this oracle is not a member of the page's room, and both must be. Inviting this oracle to the page (or opening a page they own) fixes it"
467
+ : 'the editor service is currently unavailable for this page — they can retry shortly';
468
+ return `**⚠️ PAGE OPEN BUT NOT ACCESSIBLE**
469
+
470
+ A page is open in the client, but the editor could not be attached to this request: ${why}.
471
+
472
+ - If the user asks about "the page" / "this page" / "the current page", tell them plainly that you cannot access it because ${tellUser}. Do not guess at the page's content.
473
+ - Calling \`call_editor_agent\` will only return this same denial — do not retry it in a loop.
474
+ - Do NOT call \`list_capabilities\` or \`load_capability\` hunting for editor tools — the editor cannot attach during this request regardless of what is loaded.
475
+ - Never claim to have read or edited the page.
476
+ - Everything unrelated to the page works normally.`;
477
+ }
442
478
  export const editorAgentPrompt = `
443
479
  ${sharedExpectations}
444
480
 
@@ -10,8 +10,11 @@ export interface CreateStandaloneEditorToolOptions {
10
10
  }
11
11
  /**
12
12
  * Build the `call_editor_agent` plugin tool for standalone (no preset room)
13
- * sessions. Each invocation spins up a short-lived inner agent over the
14
- * supplied `room_id` and returns its final reply text.
13
+ * sessions. Each invocation spins up a short-lived inner agent over the
14
+ * supplied `room_id`, or in create mode (no `room_id`) with only the
15
+ * page-lifecycle tools — and returns a Command that pushes the inner tool
16
+ * calls plus the final reply into the parent graph, mirroring the
17
+ * `forwardTools: true` behaviour of the editor sub-agent path.
15
18
  */
16
19
  export declare function createStandaloneEditorTool(opts: CreateStandaloneEditorToolOptions): PluginTool;
17
20
  //# sourceMappingURL=standalone-editor-tool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"standalone-editor-tool.d.ts","sourceRoot":"","sources":["../../../src/plugins/editor/standalone-editor-tool.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EACL,KAAK,oBAAoB,EAE1B,MAAM,sBAAsB,CAAC;AAsE9B,MAAM,WAAW,iCAAiC;IAChD,mDAAmD;IACnD,WAAW,EAAE,oBAAoB,CAAC;IAClC,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,4FAA4F;IAC5F,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,iCAAiC,GACtC,UAAU,CAoHZ"}
1
+ {"version":3,"file":"standalone-editor-tool.d.ts","sourceRoot":"","sources":["../../../src/plugins/editor/standalone-editor-tool.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AA0E9B,MAAM,WAAW,iCAAiC;IAChD,mDAAmD;IACnD,WAAW,EAAE,oBAAoB,CAAC;IAClC,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,4FAA4F;IAC5F,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,iCAAiC,GACtC,UAAU,CAyKZ"}
@@ -1,8 +1,11 @@
1
- import { HumanMessage } from '@langchain/core/messages';
1
+ import { HumanMessage, ToolMessage, } from '@langchain/core/messages';
2
+ import { Command } from '@langchain/langgraph';
2
3
  import { createAgent } from 'langchain';
3
- import { emojify } from '../../utils/emoji.js';
4
4
  import { z } from 'zod';
5
+ import { emojify } from '../../utils/emoji.js';
6
+ import { filterForwardedMessages } from '../../graph/subagent-as-tool.js';
5
7
  import { isUserInRoom } from '../../matrix/room-membership.js';
8
+ import { EDITOR_AGENT_TOOL_NAME } from './editor-agent.js';
6
9
  import { tool as pluginTool } from '../../plugin-api/tool-helper.js';
7
10
  import { createBlocknoteTools, } from './blocknote-tools.js';
8
11
  import { resolveEditorMatrixClient } from './editor-mx.js';
@@ -13,15 +16,19 @@ const standaloneEditorSchema = z.object({
13
16
  room_id: z
14
17
  .string()
15
18
  .regex(/^!.+:.+$/, 'Room ID must start with "!" (e.g., "!abc123:matrix.org")')
16
- .describe('The Matrix room ID of the page (e.g., "!oeGkcJIKNpeSiaGHVE:devmx.ixo.earth"). Must start with "!".'),
19
+ .optional()
20
+ .describe('The Matrix room ID of an EXISTING page to read or edit (e.g., "!oeGkcJIKNpeSiaGHVE:devmx.ixo.earth"). ' +
21
+ "OMIT this entirely to CREATE a new page — create_page generates a fresh room under the user's space and returns its id."),
17
22
  task: z
18
23
  .string()
19
24
  .describe('A detailed, self-contained editing instruction. The editor agent has NO conversation context — ' +
20
25
  'this string is ALL it receives. Include: explicit objective, block IDs, property names, exact values, ' +
21
26
  'and expected outcome. Do NOT include the room ID here — it goes in room_id.'),
22
27
  });
23
- const STANDALONE_DESCRIPTION = 'Call Editor Agent as a sub-agent to operate on a BlockNote page by Matrix room ID. ' +
24
- 'Spins up an ephemeral editor session with full block-level capabilities and page management tools for the supplied room.';
28
+ const STANDALONE_DESCRIPTION = 'Call Editor Agent as a sub-agent to operate on a BlockNote page. ' +
29
+ 'Pass a `room_id` to read or edit an EXISTING page; OMIT `room_id` to CREATE a new page ' +
30
+ "(create_page makes a fresh room under the user's space and returns its id). " +
31
+ 'Spins up an ephemeral editor session with full block-level and page-management tools.';
25
32
  function lastMessageContent(messages) {
26
33
  const last = messages.at(-1);
27
34
  if (!last?.content)
@@ -36,37 +43,43 @@ function lastMessageContent(messages) {
36
43
  }
37
44
  /**
38
45
  * Build the `call_editor_agent` plugin tool for standalone (no preset room)
39
- * sessions. Each invocation spins up a short-lived inner agent over the
40
- * supplied `room_id` and returns its final reply text.
46
+ * sessions. Each invocation spins up a short-lived inner agent over the
47
+ * supplied `room_id`, or in create mode (no `room_id`) with only the
48
+ * page-lifecycle tools — and returns a Command that pushes the inner tool
49
+ * calls plus the final reply into the parent graph, mirroring the
50
+ * `forwardTools: true` behaviour of the editor sub-agent path.
41
51
  */
42
52
  export function createStandaloneEditorTool(opts) {
43
53
  return pluginTool(async (rawArgs, ctx) => {
44
54
  const { room_id: roomId, task } = standaloneEditorSchema.parse(rawArgs);
45
- // The agent supplies `room_id` per call and the editor operates on it
46
- // with the oracle's admin Matrix identity. Verify the authenticated user
47
- // is a member of the room before touching it without this an agent
48
- // could be steered to read or edit any room id.
49
- if (!(await isUserInRoom(roomId, ctx.user.matrixUserId))) {
50
- ctx.logger.warn(`[StandaloneEditorTool] user ${ctx.user.did} is not a member of room ${roomId} refusing access`);
51
- return `You do not have access to room ${roomId}.`;
55
+ // Membership guard. For an EXISTING page the user must be a member of
56
+ // that room (the editor acts with the oracle's admin identity, so without
57
+ // this an agent could be steered to read/edit any room id it's handed).
58
+ // For CREATE (no roomId) the new page is nested under `opts.spaceId`, so
59
+ // guard on space membership instead. The refusal text is addressed to
60
+ // the agent so it can explain the situation to the user instead of
61
+ // surfacing a bare permission error.
62
+ const guardRoomId = roomId ?? opts.spaceId;
63
+ if (!(await isUserInRoom(guardRoomId, ctx.user.matrixUserId))) {
64
+ ctx.logger.warn(`[StandaloneEditorTool] user ${ctx.user.did} is not a member of ${guardRoomId} — refusing access`);
65
+ return roomId
66
+ ? `Access denied: the user is not a member of page room ${roomId}. ` +
67
+ 'Tell the user they do not have access to this page — they need to be ' +
68
+ 'invited to it before you can read or edit it on their behalf.'
69
+ : `Access denied: the user is not a member of workspace space ${opts.spaceId}. ` +
70
+ 'Tell the user they are not part of this workspace — they need to be ' +
71
+ 'invited to the space before you can create pages in it on their behalf.';
52
72
  }
53
73
  try {
54
- const roomConfig = { type: 'id', value: roomId };
55
74
  const matrixClient = await resolveEditorMatrixClient({
56
75
  baseUrl: opts.toolsConfig.matrix.baseUrl,
57
76
  userId: opts.toolsConfig.matrix.userId,
58
77
  accessToken: opts.toolsConfig.matrix.accessToken,
59
78
  matrixClient: opts.toolsConfig.matrixClient,
60
79
  });
61
- const appConfig = {
62
- matrix: { ...opts.toolsConfig.matrix, room: roomConfig },
63
- provider: { ...opts.toolsConfig.provider },
64
- blocknote: { ...opts.toolsConfig.blocknote },
65
- };
66
- // `createBlocknoteTools` returns a discriminated union over the
67
- // read-only flag. The standalone tool always wants the writable
68
- // branch; this is the same narrowing the editor sub-agent applies.
69
- const blocknoteTools = (await createBlocknoteTools(matrixClient, appConfig, false));
80
+ // `create_page` always mints a brand-new room under the space, so it
81
+ // needs no preset room. read/update fall back to a `room_id` argument
82
+ // when there's no `defaultRoomId` (create mode).
70
83
  const pageTools = createPageTools({
71
84
  matrixClient,
72
85
  toolsConfig: opts.toolsConfig,
@@ -74,46 +87,43 @@ export function createStandaloneEditorTool(opts) {
74
87
  defaultSpaceId: opts.spaceId,
75
88
  defaultRoomId: roomId,
76
89
  });
77
- const innerTools = [
78
- blocknoteTools.listBlocksTool,
79
- blocknoteTools.editBlockTool,
80
- blocknoteTools.createBlockTool,
81
- blocknoteTools.deleteBlockTool,
82
- blocknoteTools.readBlockByIdTool,
83
- blocknoteTools.searchBlocksTool,
84
- blocknoteTools.readFlowContextTool,
85
- blocknoteTools.readFlowStatusTool,
86
- blocknoteTools.readBlockHistoryTool,
87
- blocknoteTools.readPermissionsTool,
88
- blocknoteTools.readSurveyTool,
89
- blocknoteTools.fillSurveyAnswersTool,
90
- blocknoteTools.validateSurveyAnswersTool,
91
- blocknoteTools.executeActionTool,
92
- blocknoteTools.findAndReplaceTool,
93
- blocknoteTools.moveBlockTool,
94
- blocknoteTools.bulkEditBlocksTool,
95
- pageTools.readPageTool,
96
- pageTools.createPageTool,
97
- pageTools.updatePageTool,
98
- ].filter((t) => Boolean(t));
99
- // mint_invocation — only when an oracle signing key is loaded. The
100
- // ephemeral agent gets it for the same reasons the long-lived editor
101
- // sub-agent does: the delegation CAR is read from the flow's Y.Doc
102
- // by CID, which needs the matrixClient + roomId baked into this
103
- // closure.
104
- if (ctx.ucan.hasSigningKey()) {
105
- innerTools.push(createMintInvocationEditorTool({
106
- matrixClient,
107
- appConfig,
108
- roomId,
109
- ucanService: ctx.ucan,
110
- blobStore: ctx.blobStore,
111
- userDid: ctx.user.did,
112
- }));
90
+ const innerTools = [];
91
+ // Block-level tools (and mint_invocation) only make sense over an
92
+ // existing page's Y.Doc. In create mode there is no page yet, so we
93
+ // expose ONLY the page-lifecycle tools and let create_page make the
94
+ // room — binding block tools over a non-page room (e.g. the space)
95
+ // would be meaningless and error-prone.
96
+ if (roomId && roomId !== opts.spaceId) {
97
+ const roomConfig = { type: 'id', value: roomId };
98
+ const appConfig = {
99
+ matrix: { ...opts.toolsConfig.matrix, room: roomConfig },
100
+ provider: { ...opts.toolsConfig.provider },
101
+ blocknote: { ...opts.toolsConfig.blocknote },
102
+ };
103
+ // `createBlocknoteTools` returns a discriminated union over the
104
+ // read-only flag. The standalone tool always wants the writable
105
+ // branch; this is the same narrowing the editor sub-agent applies.
106
+ const blocknoteTools = (await createBlocknoteTools(matrixClient, appConfig, false));
107
+ innerTools.push(blocknoteTools.listBlocksTool, blocknoteTools.editBlockTool, blocknoteTools.createBlockTool, blocknoteTools.deleteBlockTool, blocknoteTools.readBlockByIdTool, blocknoteTools.searchBlocksTool, blocknoteTools.readFlowContextTool, blocknoteTools.readFlowStatusTool, blocknoteTools.readBlockHistoryTool, blocknoteTools.readPermissionsTool, blocknoteTools.readSurveyTool, blocknoteTools.fillSurveyAnswersTool, blocknoteTools.validateSurveyAnswersTool, blocknoteTools.executeActionTool, blocknoteTools.findAndReplaceTool, blocknoteTools.moveBlockTool, blocknoteTools.bulkEditBlocksTool);
108
+ // mint_invocation — only when an oracle signing key is loaded. The
109
+ // delegation CAR is read from the flow's Y.Doc by CID, which needs
110
+ // the matrixClient + roomId baked into this closure.
111
+ if (ctx.ucan.hasSigningKey()) {
112
+ innerTools.push(createMintInvocationEditorTool({
113
+ matrixClient,
114
+ appConfig,
115
+ roomId,
116
+ ucanService: ctx.ucan,
117
+ blobStore: ctx.blobStore,
118
+ userDid: ctx.user.did,
119
+ }));
120
+ }
113
121
  }
122
+ innerTools.push(pageTools.readPageTool, pageTools.createPageTool, pageTools.updatePageTool);
123
+ const boundTools = innerTools.filter((t) => Boolean(t));
114
124
  const agent = createAgent({
115
125
  model: ctx.llm.get('subagent'),
116
- tools: innerTools,
126
+ tools: boundTools,
117
127
  systemPrompt: editorAgentPrompt,
118
128
  middleware: [],
119
129
  });
@@ -121,15 +131,37 @@ export function createStandaloneEditorTool(opts) {
121
131
  messages: [new HumanMessage(task)],
122
132
  });
123
133
  const messages = result.messages;
124
- return emojify(lastMessageContent(messages));
134
+ const text = emojify(lastMessageContent(messages));
135
+ // Forward every inner tool call + result into the parent graph via
136
+ // Command — same mechanism as `createSubagentAsTool` with the editor
137
+ // sub-agent's `forwardTools: true` — so the FE renders page/block
138
+ // activity inline regardless of which editor path handled the turn.
139
+ // Without a parent tool_call_id there is no call to attach the
140
+ // Command's ToolMessage to, so fall back to plain text.
141
+ const toolCallId = ctx.toolCallId;
142
+ if (!toolCallId)
143
+ return text;
144
+ const forwardSet = new Set(boundTools.map((t) => t.name));
145
+ const forwarded = filterForwardedMessages(messages, forwardSet, toolCallId);
146
+ if (forwarded.length === 0)
147
+ return text;
148
+ return new Command({
149
+ update: {
150
+ messages: [
151
+ ...forwarded,
152
+ new ToolMessage({ content: text, tool_call_id: toolCallId }),
153
+ ],
154
+ },
155
+ });
125
156
  }
126
157
  catch (err) {
127
158
  const message = err instanceof Error ? err.message : String(err);
128
- ctx.logger.error(`[StandaloneEditorTool] Failed for room ${roomId}: ${message}`);
129
- return `Error opening editor for room ${roomId}: ${message}`;
159
+ const label = roomId ?? 'new page';
160
+ ctx.logger.error(`[StandaloneEditorTool] Failed for ${label}: ${message}`);
161
+ return `Error opening editor for ${label}: ${message}`;
130
162
  }
131
163
  }, {
132
- name: 'call_editor_agent',
164
+ name: EDITOR_AGENT_TOOL_NAME,
133
165
  description: STANDALONE_DESCRIPTION,
134
166
  schema: standaloneEditorSchema,
135
167
  });
@@ -37,7 +37,7 @@ const SESSION_INJECT_OLDEST_CHUNKS = 2;
37
37
  const SESSION_INJECT_LAST_MESSAGES = 15;
38
38
  const MATRIX_STORAGE_KEY = 'qiforge.channel_memory.v1';
39
39
  const DEFAULT_SYNC_DEBOUNCE_MS = 60 * 1000;
40
- const DEFAULT_DB_PATH = './data/channel_memory';
40
+ const DEFAULT_DB_PATH = `${process.env.SQLITE_DATABASE_PATH}/channel_memory';`;
41
41
  export const CHANNEL_MEMORY_SERVICE_CONFIG = Symbol.for('CHANNEL_MEMORY_SERVICE_CONFIG');
42
42
  export const CHANNEL_MEMORY_SUMMARIZER = Symbol.for('CHANNEL_MEMORY_SUMMARIZER');
43
43
  /**
package/package.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "name": "@ixo/oracle-runtime",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Plugin-based runtime for QiForge oracles",
5
5
  "private": false,
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/ixoworld/qiforge.git"
12
+ },
9
13
  "type": "module",
10
14
  "engines": {
11
15
  "node": ">=22"
@@ -43,15 +47,15 @@
43
47
  "typescript": "^5.7.3",
44
48
  "vitest": "^3.2.4",
45
49
  "@ixo/eslint-config": "2.0.0",
46
- "@ixo/vitest-config": "1.0.0",
47
- "@ixo/typescript-config": "1.0.0"
50
+ "@ixo/typescript-config": "1.0.0",
51
+ "@ixo/vitest-config": "1.0.0"
48
52
  },
49
53
  "dependencies": {
50
54
  "@blocknote/server-util": "0.29.1",
51
55
  "@composio/core": "0.10.0",
52
56
  "@composio/langchain": "0.9.2",
53
57
  "@ixo/editor": "3.0.0-beta.11",
54
- "@ixo/matrix-crdt": "^1.2.1",
58
+ "@ixo/matrix-crdt": "^1.2.5",
55
59
  "@ixo/slack": "1.0.0",
56
60
  "@langchain/core": "1.1.48",
57
61
  "@langchain/langgraph": "1.3.2",
@@ -80,12 +84,12 @@
80
84
  "socket.io": "4.8.3",
81
85
  "yjs": "^13.6.27",
82
86
  "zod": "^4.4.3",
83
- "@ixo/common": "1.1.41",
84
- "@ixo/matrix": "1.2.33",
85
- "@ixo/oracles-chain-client": "1.2.3",
86
- "@ixo/oracles-events": "1.0.5",
87
+ "@ixo/common": "1.1.42",
88
+ "@ixo/oracles-chain-client": "1.3.1",
87
89
  "@ixo/sqlite-saver": "1.0.53",
88
- "@ixo/ucan": "1.2.3"
90
+ "@ixo/ucan": "1.2.3",
91
+ "@ixo/oracles-events": "1.0.5",
92
+ "@ixo/matrix": "1.2.33"
89
93
  },
90
94
  "peerDependencies": {
91
95
  "typescript": ">=5.0.0"