@ixo/oracle-runtime 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/base-env-config.d.ts.map +1 -1
- package/dist/config/base-env-config.js +0 -2
- package/dist/graph/main-agent.d.ts.map +1 -1
- package/dist/graph/main-agent.js +54 -2
- package/dist/graph/subagent-as-tool.d.ts +15 -0
- package/dist/graph/subagent-as-tool.d.ts.map +1 -1
- package/dist/graph/subagent-as-tool.js +5 -1
- package/dist/matrix/user-id.d.ts +16 -0
- package/dist/matrix/user-id.d.ts.map +1 -0
- package/dist/matrix/user-id.js +17 -0
- package/dist/modules/messages/agent-builder.d.ts.map +1 -1
- package/dist/modules/messages/agent-builder.js +2 -1
- package/dist/modules/sessions/session-history-processor.service.d.ts.map +1 -1
- package/dist/modules/sessions/session-history-processor.service.js +2 -1
- package/dist/plugins/domain-indexer/domain-indexer-tools.d.ts.map +1 -1
- package/dist/plugins/domain-indexer/domain-indexer-tools.js +22 -3
- package/dist/plugins/editor/editor-access-denied-tool.d.ts +21 -0
- package/dist/plugins/editor/editor-access-denied-tool.d.ts.map +1 -0
- package/dist/plugins/editor/editor-access-denied-tool.js +37 -0
- package/dist/plugins/editor/editor-agent.d.ts +11 -0
- package/dist/plugins/editor/editor-agent.d.ts.map +1 -1
- package/dist/plugins/editor/editor-agent.js +18 -13
- package/dist/plugins/editor/editor.plugin.d.ts.map +1 -1
- package/dist/plugins/editor/editor.plugin.js +4 -4
- package/dist/plugins/editor/index.d.ts +2 -1
- package/dist/plugins/editor/index.d.ts.map +1 -1
- package/dist/plugins/editor/index.js +2 -1
- package/dist/plugins/editor/page-functions.d.ts +0 -3
- package/dist/plugins/editor/page-functions.d.ts.map +1 -1
- package/dist/plugins/editor/page-functions.js +19 -4
- package/dist/plugins/editor/prompts.d.ts +16 -0
- package/dist/plugins/editor/prompts.d.ts.map +1 -1
- package/dist/plugins/editor/prompts.js +46 -10
- package/dist/plugins/editor/standalone-editor-tool.d.ts +5 -2
- package/dist/plugins/editor/standalone-editor-tool.d.ts.map +1 -1
- package/dist/plugins/editor/standalone-editor-tool.js +97 -65
- package/package.json +12 -8
|
@@ -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,
|
|
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":"
|
|
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"}
|
package/dist/graph/main-agent.js
CHANGED
|
@@ -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:
|
|
221
|
-
|
|
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;
|
|
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;
|
|
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:
|
|
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;
|
|
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 =
|
|
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":"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;
|
|
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:
|
|
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
|
|
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":"
|
|
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 =
|
|
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
|
-
//
|
|
146
|
-
// renders
|
|
147
|
-
//
|
|
148
|
-
//
|
|
149
|
-
|
|
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;
|
|
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:
|
|
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:
|
|
50
|
+
tool: EDITOR_AGENT_TOOL_NAME,
|
|
51
51
|
},
|
|
52
52
|
],
|
|
53
53
|
tags: ['editor', 'blocknote', 'pages', 'documents'],
|
|
54
54
|
category: 'data',
|
|
55
|
-
visibility: '
|
|
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":"
|
|
1
|
+
{"version":3,"file":"page-functions.d.ts","sourceRoot":"","sources":["../../../src/plugins/editor/page-functions.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAQlD,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AAwBvB,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACzC,cAAc,EAAE,cAAc,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACzC,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,MAAM,EAAE,KAAK,CAAC;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAqCD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAwJ3B;AAID,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACzC,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,OAAO,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CA4I3B;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,cAAc,CAAC,CAsCzB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unnecessary-type-assertion */
|
|
1
2
|
/**
|
|
2
3
|
* Page management functions — reusable from services, API routes, and tests.
|
|
3
4
|
*/
|
|
@@ -107,15 +108,31 @@ export async function createPage(params) {
|
|
|
107
108
|
});
|
|
108
109
|
const roomId = createRoomResponse.room_id;
|
|
109
110
|
logger.log(`Page room created: ${roomId}`);
|
|
110
|
-
//
|
|
111
|
+
// Link the page under its space by writing m.space.child INTO the space room.
|
|
112
|
+
// The oracle admin (this matrixClient) must be a member of the space with
|
|
113
|
+
// permission to send that state event. It may have been invited during space
|
|
114
|
+
// provisioning but not yet joined, so try to join first. If the admin has no
|
|
115
|
+
// access to the user's space this is expected to fail (M_FORBIDDEN) — the page
|
|
116
|
+
// still carries its m.space.parent claim (set in initial_state) and the
|
|
117
|
+
// returned spaceId, so a client acting as the user (who IS in the space) can
|
|
118
|
+
// complete the link.
|
|
111
119
|
if (parentSpaceId) {
|
|
112
120
|
try {
|
|
121
|
+
const adminInSpace = matrixClient.getRoom(parentSpaceId)?.getMember(creatorId)
|
|
122
|
+
?.membership === 'join';
|
|
123
|
+
if (!adminInSpace) {
|
|
124
|
+
await matrixClient.joinRoom(parentSpaceId);
|
|
125
|
+
}
|
|
113
126
|
await matrixClient.sendStateEvent(parentSpaceId,
|
|
114
127
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
115
128
|
'm.space.child', { via: [homeserver] }, roomId);
|
|
129
|
+
logger.log(`Linked page ${roomId} under space ${parentSpaceId}`);
|
|
116
130
|
}
|
|
117
131
|
catch (error) {
|
|
118
|
-
logger.warn(`
|
|
132
|
+
logger.warn(`Could not link page ${roomId} under space ${parentSpaceId}: the oracle ` +
|
|
133
|
+
`admin lacks membership/permission in that space. The page keeps its ` +
|
|
134
|
+
`m.space.parent claim and the returned spaceId — a user-authorized ` +
|
|
135
|
+
`client can complete the m.space.child link. (${error})`);
|
|
119
136
|
}
|
|
120
137
|
}
|
|
121
138
|
// Parse markdown content into BlockNote blocks if provided
|
|
@@ -220,7 +237,6 @@ export async function updatePage(params) {
|
|
|
220
237
|
let oldContentMd = '';
|
|
221
238
|
if (content !== undefined || appendContent !== undefined) {
|
|
222
239
|
const oldBlocks = serverEditor.yXmlFragmentToBlocks(doc.getXmlFragment('document'));
|
|
223
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
224
240
|
oldContentMd = await serverEditor.blocksToMarkdownLossy(oldBlocks);
|
|
225
241
|
}
|
|
226
242
|
doc.transact(() => {
|
|
@@ -252,7 +268,6 @@ export async function updatePage(params) {
|
|
|
252
268
|
// Snapshot new content as markdown (for diff) after mutations
|
|
253
269
|
if (content !== undefined || appendContent !== undefined) {
|
|
254
270
|
const newBlocks = serverEditor.yXmlFragmentToBlocks(doc.getXmlFragment('document'));
|
|
255
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
256
271
|
const newContentMd = await serverEditor.blocksToMarkdownLossy(newBlocks);
|
|
257
272
|
diff.content = { old: oldContentMd, new: newContentMd };
|
|
258
273
|
}
|
|
@@ -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;;;
|
|
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
|
|
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
|
-
**
|
|
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\`
|
|
410
|
-
3. The editor agent has full capabilities: list/edit/create/delete blocks, read/update
|
|
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\`:
|
|
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
|
-
-
|
|
418
|
-
- \`call_editor_agent({ room_id: "!abc:server.example", task: "
|
|
419
|
-
- \`call_editor_agent({ room_id: "!abc:server.example", task: "
|
|
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:**
|
|
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
|
|
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":"
|
|
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
|
-
.
|
|
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
|
|
24
|
-
'
|
|
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
|
|
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
|
-
//
|
|
46
|
-
// with the oracle's admin
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
blocknoteTools
|
|
94
|
-
blocknoteTools.bulkEditBlocksTool
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
129
|
-
|
|
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:
|
|
164
|
+
name: EDITOR_AGENT_TOOL_NAME,
|
|
133
165
|
description: STANDALONE_DESCRIPTION,
|
|
134
166
|
schema: standaloneEditorSchema,
|
|
135
167
|
});
|
package/package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ixo/oracle-runtime",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
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"
|
|
@@ -42,16 +46,16 @@
|
|
|
42
46
|
"reflect-metadata": "^0.2.2",
|
|
43
47
|
"typescript": "^5.7.3",
|
|
44
48
|
"vitest": "^3.2.4",
|
|
49
|
+
"@ixo/typescript-config": "1.0.0",
|
|
45
50
|
"@ixo/eslint-config": "2.0.0",
|
|
46
|
-
"@ixo/vitest-config": "1.0.0"
|
|
47
|
-
"@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.
|
|
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,11 +84,11 @@
|
|
|
80
84
|
"socket.io": "4.8.3",
|
|
81
85
|
"yjs": "^13.6.27",
|
|
82
86
|
"zod": "^4.4.3",
|
|
83
|
-
"@ixo/common": "1.1.
|
|
84
|
-
"@ixo/
|
|
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",
|
|
90
|
+
"@ixo/oracles-events": "1.0.5",
|
|
91
|
+
"@ixo/matrix": "1.2.33",
|
|
88
92
|
"@ixo/ucan": "1.2.3"
|
|
89
93
|
},
|
|
90
94
|
"peerDependencies": {
|