@ixo/oracle-runtime-workers 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -0
- package/package.json +77 -0
- package/src/attachments/classify.ts +114 -0
- package/src/attachments/content-blocks.ts +51 -0
- package/src/attachments/download.ts +235 -0
- package/src/attachments/extract.ts +241 -0
- package/src/attachments/index.ts +84 -0
- package/src/attachments/magic.ts +133 -0
- package/src/attachments/pipeline.ts +409 -0
- package/src/attachments/retention.ts +205 -0
- package/src/attachments/route.ts +41 -0
- package/src/attachments/sandbox-archive.ts +90 -0
- package/src/attachments/sanitize.ts +35 -0
- package/src/attachments/types.ts +86 -0
- package/src/attachments/view.ts +107 -0
- package/src/core/env.ts +200 -0
- package/src/core/index.ts +513 -0
- package/src/core/llm.ts +842 -0
- package/src/core/main-agent-types.ts +123 -0
- package/src/core/main-agent.ts +399 -0
- package/src/core/manifest.ts +365 -0
- package/src/core/meta-tools.ts +232 -0
- package/src/core/middlewares/byo-history-sanitizer.ts +165 -0
- package/src/core/middlewares/capability-gate.ts +76 -0
- package/src/core/middlewares/index.ts +18 -0
- package/src/core/middlewares/page-context.ts +98 -0
- package/src/core/middlewares/safety-guardrail.ts +117 -0
- package/src/core/middlewares/summarization.ts +99 -0
- package/src/core/middlewares/tool-repetition-guard.ts +125 -0
- package/src/core/middlewares/tool-validation.ts +83 -0
- package/src/core/middlewares/work-status.ts +57 -0
- package/src/core/openrouter-pricing.ts +124 -0
- package/src/core/plugin-loader.ts +192 -0
- package/src/core/plugins/index.ts +6 -0
- package/src/core/plugins/skills/index.ts +8 -0
- package/src/core/plugins/skills/skills-tools.ts +356 -0
- package/src/core/plugins/skills/skills.plugin.ts +113 -0
- package/src/core/plugins/weather/index.ts +8 -0
- package/src/core/plugins/weather/weather-client.ts +153 -0
- package/src/core/plugins/weather/weather-middleware.ts +27 -0
- package/src/core/plugins/weather/weather-sub-agent.ts +65 -0
- package/src/core/plugins/weather/weather-tools.ts +103 -0
- package/src/core/plugins/weather/weather.plugin.ts +227 -0
- package/src/core/prompt-composer.ts +469 -0
- package/src/core/registries.ts +642 -0
- package/src/core/runtime-context.ts +619 -0
- package/src/core/state.ts +108 -0
- package/src/core/sub-agent-fallback.ts +187 -0
- package/src/core/subagent-as-tool.ts +322 -0
- package/src/core/template.ts +245 -0
- package/src/core/utils.ts +246 -0
- package/src/core/wrap-plugin-tool.ts +100 -0
- package/src/do/ambient.ts +266 -0
- package/src/do/contracts.ts +562 -0
- package/src/do/debug-timers.ts +120 -0
- package/src/do/fresh-stub.ts +32 -0
- package/src/do/gateway-retry.ts +73 -0
- package/src/do/secrets-adapter.ts +32 -0
- package/src/do/size-alerts.ts +76 -0
- package/src/do/sse-stream.ts +472 -0
- package/src/do/transcript.ts +192 -0
- package/src/do/turn-body.ts +84 -0
- package/src/do/turn-metadata.ts +146 -0
- package/src/do/ucan-service.ts +339 -0
- package/src/do/user-oracle-do.ts +3035 -0
- package/src/gateway-worker.ts +82 -0
- package/src/index.ts +237 -0
- package/src/llm/byo-adapter.ts +59 -0
- package/src/llm/byo-catalog.ts +520 -0
- package/src/llm/byo-client.ts +280 -0
- package/src/llm/byo-routes.ts +255 -0
- package/src/llm/byo-service.ts +836 -0
- package/src/llm/chatgpt-oauth.ts +430 -0
- package/src/llm/provider-error.ts +283 -0
- package/src/matrix/gateway-do.ts +918 -0
- package/src/matrix/ingest.ts +209 -0
- package/src/matrix/replay-format.ts +34 -0
- package/src/matrix/reply-chain.ts +109 -0
- package/src/matrix/room-state-codec.ts +115 -0
- package/src/matrix/user-homeserver.ts +106 -0
- package/src/matrix/work-status.ts +294 -0
- package/src/memory/session-history-indexer.ts +328 -0
- package/src/owner-store/ixo-vfs-store.ts +570 -0
- package/src/owner-store/matrix-media-store.ts +136 -0
- package/src/owner-store/migrating-store.ts +185 -0
- package/src/owner-store/owner-copy-errors.ts +175 -0
- package/src/owner-store/retry.ts +45 -0
- package/src/owner-store/tus-upload.ts +333 -0
- package/src/owner-store/types.ts +0 -0
- package/src/plugin-api/define-plugin.ts +45 -0
- package/src/plugin-api/index.ts +56 -0
- package/src/plugin-api/oracle-plugin.ts +145 -0
- package/src/plugin-api/tool-helper.ts +82 -0
- package/src/plugin-api/types.ts +816 -0
- package/src/plugin-api/ucan-errors.ts +16 -0
- package/src/plugins/agui/agui-agent.ts +115 -0
- package/src/plugins/agui/agui.plugin.ts +148 -0
- package/src/plugins/agui/index.ts +2 -0
- package/src/plugins/attachments/attachments.plugin.ts +54 -0
- package/src/plugins/attachments/index.ts +6 -0
- package/src/plugins/attachments/view-attachment-tool.ts +91 -0
- package/src/plugins/base64.ts +26 -0
- package/src/plugins/composio/composio-tools.ts +365 -0
- package/src/plugins/composio/composio-ucan.ts +43 -0
- package/src/plugins/composio/composio.plugin.ts +214 -0
- package/src/plugins/composio/index.ts +15 -0
- package/src/plugins/domain-indexer/domain-indexer-agent.ts +57 -0
- package/src/plugins/domain-indexer/domain-indexer-tools.ts +253 -0
- package/src/plugins/domain-indexer/domain-indexer.plugin.ts +100 -0
- package/src/plugins/domain-indexer/index.ts +3 -0
- package/src/plugins/editor/blocknote-bridge.ts +120 -0
- package/src/plugins/editor/content-session.ts +331 -0
- package/src/plugins/editor/content-tools.ts +686 -0
- package/src/plugins/editor/document-model.ts +0 -0
- package/src/plugins/editor/editor-access-denied-tool.ts +58 -0
- package/src/plugins/editor/editor-agent.ts +34 -0
- package/src/plugins/editor/editor-config.ts +64 -0
- package/src/plugins/editor/editor-mx.ts +128 -0
- package/src/plugins/editor/editor.plugin.ts +143 -0
- package/src/plugins/editor/failures.ts +154 -0
- package/src/plugins/editor/index.ts +31 -0
- package/src/plugins/editor/jsdom-shim.ts +55 -0
- package/src/plugins/editor/prompts.ts +59 -0
- package/src/plugins/editor/prop-policy.ts +147 -0
- package/src/plugins/editor/provider.ts +386 -0
- package/src/plugins/editor/room-membership.ts +95 -0
- package/src/plugins/editor/standalone-editor-tool.ts +200 -0
- package/src/plugins/firecrawl/firecrawl-agent.ts +93 -0
- package/src/plugins/firecrawl/firecrawl-tools.ts +220 -0
- package/src/plugins/firecrawl/firecrawl.plugin.ts +105 -0
- package/src/plugins/firecrawl/index.ts +15 -0
- package/src/plugins/flows/action-metadata.ts +3505 -0
- package/src/plugins/flows/actions.ts +190 -0
- package/src/plugins/flows/edit.ts +314 -0
- package/src/plugins/flows/errors.ts +38 -0
- package/src/plugins/flows/explain.ts +43 -0
- package/src/plugins/flows/flow-doc.ts +111 -0
- package/src/plugins/flows/flows.plugin.ts +129 -0
- package/src/plugins/flows/forms.ts +330 -0
- package/src/plugins/flows/index.ts +2 -0
- package/src/plugins/flows/linkage.ts +147 -0
- package/src/plugins/flows/port-types.ts +53 -0
- package/src/plugins/flows/prompts.ts +65 -0
- package/src/plugins/flows/read.ts +392 -0
- package/src/plugins/flows/references.ts +66 -0
- package/src/plugins/flows/test-support.ts +165 -0
- package/src/plugins/flows/tools/authoring.ts +516 -0
- package/src/plugins/flows/tools/discovery.ts +119 -0
- package/src/plugins/flows/tools/forms.ts +142 -0
- package/src/plugins/flows/tools/inspect.ts +165 -0
- package/src/plugins/flows/tools/linkage.ts +117 -0
- package/src/plugins/flows/tools/settings.ts +184 -0
- package/src/plugins/flows/translator.ts +328 -0
- package/src/plugins/flows/types.ts +210 -0
- package/src/plugins/flows/ydoc-helpers.ts +543 -0
- package/src/plugins/index.ts +70 -0
- package/src/plugins/mcp-call-timeout.ts +38 -0
- package/src/plugins/mcp-tool-adapter.ts +87 -0
- package/src/plugins/memory/index.ts +17 -0
- package/src/plugins/memory/memory-tools.ts +463 -0
- package/src/plugins/memory/memory-ucan.ts +51 -0
- package/src/plugins/memory/memory.plugin.ts +122 -0
- package/src/plugins/memory/types.ts +147 -0
- package/src/plugins/portal/action-log.ts +34 -0
- package/src/plugins/portal/index.ts +2 -0
- package/src/plugins/portal/portal.plugin.ts +203 -0
- package/src/plugins/sandbox/index.ts +34 -0
- package/src/plugins/sandbox/sandbox-bridge.ts +295 -0
- package/src/plugins/sandbox/sandbox-mcp.ts +127 -0
- package/src/plugins/sandbox/sandbox-write-blob.ts +103 -0
- package/src/plugins/sandbox/sandbox.plugin.ts +599 -0
- package/src/plugins/tasks/index.ts +17 -0
- package/src/plugins/tasks/manifest.ts +81 -0
- package/src/plugins/tasks/middleware.ts +219 -0
- package/src/plugins/tasks/tasks-tools.ts +414 -0
- package/src/plugins/tasks/tasks.plugin.ts +74 -0
- package/src/plugins/ucan-failure.ts +133 -0
- package/src/plugins/user-preferences/index.ts +22 -0
- package/src/plugins/user-preferences/schema.ts +31 -0
- package/src/plugins/user-preferences/user-preferences-store.ts +172 -0
- package/src/plugins/user-preferences/user-preferences-tool.ts +131 -0
- package/src/plugins/user-preferences/user-preferences.plugin.ts +137 -0
- package/src/plugins/vfs/index.ts +40 -0
- package/src/plugins/vfs/vfs-auth.ts +56 -0
- package/src/plugins/vfs/vfs-client.ts +655 -0
- package/src/plugins/vfs/vfs-content.ts +181 -0
- package/src/plugins/vfs/vfs-errors.ts +163 -0
- package/src/plugins/vfs/vfs-sandbox-tools.ts +272 -0
- package/src/plugins/vfs/vfs-tools.ts +635 -0
- package/src/plugins/vfs/vfs.plugin.ts +201 -0
- package/src/realtime/frontend-call-registry.ts +163 -0
- package/src/realtime/realtime-endpoint.ts +619 -0
- package/src/realtime/session-socket-hub.ts +249 -0
- package/src/realtime/socket-io-codec.ts +187 -0
- package/src/secrets/jwe.ts +74 -0
- package/src/secrets/pin-cipher.ts +43 -0
- package/src/secrets/secrets-service.ts +319 -0
- package/src/shell/app.ts +564 -0
- package/src/shell/auth.ts +290 -0
- package/src/sqlite/blob-codec.ts +100 -0
- package/src/sqlite/blob-compactor.ts +146 -0
- package/src/sqlite/cache-config.ts +45 -0
- package/src/sqlite/database.ts +643 -0
- package/src/sqlite/do-vfs.ts +1485 -0
- package/src/sqlite/index.ts +61 -0
- package/src/sqlite/serialization.ts +370 -0
- package/src/sqlite/sessions-store.ts +311 -0
- package/src/sqlite/sqlite-saver.ts +919 -0
- package/src/sqlite/vacuum-policy.ts +77 -0
- package/src/sqlite/wa-sqlite-loader.ts +123 -0
- package/src/sqlite/wasm.d.ts +10 -0
- package/src/tasks/schedule.ts +174 -0
- package/src/tasks/scheduler.ts +753 -0
- package/src/tasks/spec.ts +125 -0
- package/src/tasks/store.ts +351 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Form tools (spec §3.5). `describe_form` returns a step's fillable questions
|
|
3
|
+
* with their exact allowed values; `fill_form` pre-fills answers (never submits).
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import type { MatrixClient } from 'matrix-js-sdk';
|
|
7
|
+
import { tool } from '../../../plugin-api/tool-helper';
|
|
8
|
+
import type { PluginTool, RuntimeContext } from '../../../plugin-api/types';
|
|
9
|
+
import { toToolError } from '../errors';
|
|
10
|
+
import { withFlowDoc } from '../flow-doc';
|
|
11
|
+
import { describeForm, fillForm, setFormSchema } from '../forms';
|
|
12
|
+
|
|
13
|
+
const describeSchema = z.object({
|
|
14
|
+
flowRef: z
|
|
15
|
+
.string()
|
|
16
|
+
.optional()
|
|
17
|
+
.describe('Which flow. Omit to use the flow that is currently open.'),
|
|
18
|
+
stepId: z.string().min(1).describe('The form step to describe.'),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const questionSchema = z.object({
|
|
22
|
+
name: z
|
|
23
|
+
.string()
|
|
24
|
+
.min(1)
|
|
25
|
+
.describe(
|
|
26
|
+
'The answer key this question produces (referenced downstream as {{step-id.output.<name>}}).',
|
|
27
|
+
),
|
|
28
|
+
label: z
|
|
29
|
+
.string()
|
|
30
|
+
.optional()
|
|
31
|
+
.describe('The question text shown to the user (defaults to the name).'),
|
|
32
|
+
type: z
|
|
33
|
+
.string()
|
|
34
|
+
.optional()
|
|
35
|
+
.describe(
|
|
36
|
+
'Question type: text (default), comment (multi-line), dropdown, radiogroup, checkbox (multi-select), boolean, rating.',
|
|
37
|
+
),
|
|
38
|
+
required: z.boolean().optional(),
|
|
39
|
+
choices: z
|
|
40
|
+
.array(z.string())
|
|
41
|
+
.optional()
|
|
42
|
+
.describe(
|
|
43
|
+
'Allowed options for choice questions (dropdown/radiogroup/checkbox).',
|
|
44
|
+
),
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const setFormSchemaSchema = z.object({
|
|
48
|
+
flowRef: z
|
|
49
|
+
.string()
|
|
50
|
+
.optional()
|
|
51
|
+
.describe('Which flow. Omit to use the flow that is currently open.'),
|
|
52
|
+
stepId: z
|
|
53
|
+
.string()
|
|
54
|
+
.min(1)
|
|
55
|
+
.describe('The form step to define the questions for.'),
|
|
56
|
+
questions: z
|
|
57
|
+
.array(questionSchema)
|
|
58
|
+
.min(1)
|
|
59
|
+
.describe('The questions the form should ask, in order.'),
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const fillSchema = describeSchema.extend({
|
|
63
|
+
answers: z
|
|
64
|
+
.record(z.string(), z.unknown())
|
|
65
|
+
.describe(
|
|
66
|
+
'Answers keyed by question name. Choice questions need the underlying value, not the label.',
|
|
67
|
+
),
|
|
68
|
+
merge: z
|
|
69
|
+
.boolean()
|
|
70
|
+
.optional()
|
|
71
|
+
.describe('Merge with existing answers (default true).'),
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
export function buildFormTools(
|
|
75
|
+
matrixClient: MatrixClient | undefined,
|
|
76
|
+
): PluginTool[] {
|
|
77
|
+
return [
|
|
78
|
+
tool(
|
|
79
|
+
async (args, ctx: RuntimeContext) => {
|
|
80
|
+
try {
|
|
81
|
+
const { flowRef, stepId, questions } =
|
|
82
|
+
setFormSchemaSchema.parse(args);
|
|
83
|
+
return await withFlowDoc(
|
|
84
|
+
ctx,
|
|
85
|
+
flowRef,
|
|
86
|
+
matrixClient,
|
|
87
|
+
async (doc, roomId) =>
|
|
88
|
+
setFormSchema(doc, roomId, stepId, questions),
|
|
89
|
+
);
|
|
90
|
+
} catch (err) {
|
|
91
|
+
return toToolError(err);
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: 'set_form_schema',
|
|
96
|
+
description:
|
|
97
|
+
'Define the questions a form step asks (its survey). REQUIRED for any form step — a form with no questions ' +
|
|
98
|
+
'shows "Configure Survey Schema JSON" and cannot run. Give each question a name (the answer key, referenced ' +
|
|
99
|
+
'downstream as {{step-id.output.<name>}}), a label, a type, and whether it is required. Call this after adding the form step.',
|
|
100
|
+
schema: setFormSchemaSchema,
|
|
101
|
+
},
|
|
102
|
+
),
|
|
103
|
+
tool(
|
|
104
|
+
async (args, ctx: RuntimeContext) => {
|
|
105
|
+
try {
|
|
106
|
+
const { flowRef, stepId } = describeSchema.parse(args);
|
|
107
|
+
return await withFlowDoc(ctx, flowRef, matrixClient, async (doc) =>
|
|
108
|
+
describeForm(doc, stepId),
|
|
109
|
+
);
|
|
110
|
+
} catch (err) {
|
|
111
|
+
return toToolError(err);
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: 'describe_form',
|
|
116
|
+
description:
|
|
117
|
+
'Read the questions of a form step — their names, types, whether they are required, and the exact allowed ' +
|
|
118
|
+
'values for choice questions — so you can fill it correctly.',
|
|
119
|
+
schema: describeSchema,
|
|
120
|
+
},
|
|
121
|
+
),
|
|
122
|
+
tool(
|
|
123
|
+
async (args, ctx: RuntimeContext) => {
|
|
124
|
+
try {
|
|
125
|
+
const { flowRef, stepId, answers, merge } = fillSchema.parse(args);
|
|
126
|
+
return await withFlowDoc(ctx, flowRef, matrixClient, async (doc) =>
|
|
127
|
+
fillForm(doc, stepId, answers, merge ?? true),
|
|
128
|
+
);
|
|
129
|
+
} catch (err) {
|
|
130
|
+
return toToolError(err);
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: 'fill_form',
|
|
135
|
+
description:
|
|
136
|
+
'Pre-fill a form step with answers. Does NOT submit — the user reviews and submits in the portal. ' +
|
|
137
|
+
'Returns which answers applied, which were rejected, and any still-required questions.',
|
|
138
|
+
schema: fillSchema,
|
|
139
|
+
},
|
|
140
|
+
),
|
|
141
|
+
];
|
|
142
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inspect tools (spec §3.6) — the multi-source read surface. Each connects to
|
|
3
|
+
* the flow room, gathers the FlowSpec from all sources, and returns the
|
|
4
|
+
* friendly projection. Status fields are read-only (§2.6).
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import type { MatrixClient } from 'matrix-js-sdk';
|
|
8
|
+
import { tool } from '../../../plugin-api/tool-helper';
|
|
9
|
+
import type { PluginTool, RuntimeContext } from '../../../plugin-api/types';
|
|
10
|
+
import { FlowError, toToolError } from '../errors';
|
|
11
|
+
import { explainStep } from '../explain';
|
|
12
|
+
import { withFlowDoc } from '../flow-doc';
|
|
13
|
+
import { readFlowSpec, readFlowStatus, readStep } from '../read';
|
|
14
|
+
|
|
15
|
+
const flowRefSchema = z.object({
|
|
16
|
+
flowRef: z
|
|
17
|
+
.string()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe(
|
|
20
|
+
'Which flow to inspect. Omit to use the flow that is currently open.',
|
|
21
|
+
),
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const stepRefSchema = flowRefSchema.extend({
|
|
25
|
+
stepId: z.string().min(1).describe('The step to read.'),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export function buildReadFlowTool(
|
|
29
|
+
matrixClient: MatrixClient | undefined,
|
|
30
|
+
): PluginTool {
|
|
31
|
+
return tool(
|
|
32
|
+
async (args, ctx: RuntimeContext) => {
|
|
33
|
+
try {
|
|
34
|
+
const { flowRef } = flowRefSchema.parse(args);
|
|
35
|
+
return await withFlowDoc(
|
|
36
|
+
ctx,
|
|
37
|
+
flowRef,
|
|
38
|
+
matrixClient,
|
|
39
|
+
async (doc, roomId) => {
|
|
40
|
+
const flow = readFlowSpec(doc, roomId);
|
|
41
|
+
if (!flow)
|
|
42
|
+
throw new FlowError(
|
|
43
|
+
'flow_not_found',
|
|
44
|
+
'That flow does not exist or has no steps yet.',
|
|
45
|
+
);
|
|
46
|
+
return flow;
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
} catch (err) {
|
|
50
|
+
return toToolError(err);
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'read_flow',
|
|
55
|
+
description:
|
|
56
|
+
'Read a whole flow as a clean, friendly structure: its title, goal, and every step with inputs, ' +
|
|
57
|
+
'conditions, schedule, assignee, and a read-only status. Use to see the true current state of a flow.',
|
|
58
|
+
schema: flowRefSchema,
|
|
59
|
+
},
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function buildGetStepTool(
|
|
64
|
+
matrixClient: MatrixClient | undefined,
|
|
65
|
+
): PluginTool {
|
|
66
|
+
return tool(
|
|
67
|
+
async (args, ctx: RuntimeContext) => {
|
|
68
|
+
try {
|
|
69
|
+
const { flowRef, stepId } = stepRefSchema.parse(args);
|
|
70
|
+
return await withFlowDoc(
|
|
71
|
+
ctx,
|
|
72
|
+
flowRef,
|
|
73
|
+
matrixClient,
|
|
74
|
+
async (doc, roomId) => {
|
|
75
|
+
const step = readStep(doc, roomId, stepId);
|
|
76
|
+
if (!step)
|
|
77
|
+
throw new FlowError(
|
|
78
|
+
'step_not_found',
|
|
79
|
+
`No step "${stepId}" in this flow.`,
|
|
80
|
+
);
|
|
81
|
+
return step;
|
|
82
|
+
},
|
|
83
|
+
);
|
|
84
|
+
} catch (err) {
|
|
85
|
+
return toToolError(err);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'get_step',
|
|
90
|
+
description:
|
|
91
|
+
'Read a single step of a flow, including its read-only runtime status.',
|
|
92
|
+
schema: stepRefSchema,
|
|
93
|
+
},
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function buildFlowStatusTool(
|
|
98
|
+
matrixClient: MatrixClient | undefined,
|
|
99
|
+
): PluginTool {
|
|
100
|
+
return tool(
|
|
101
|
+
async (args, ctx: RuntimeContext) => {
|
|
102
|
+
try {
|
|
103
|
+
const { flowRef } = flowRefSchema.parse(args);
|
|
104
|
+
return await withFlowDoc(
|
|
105
|
+
ctx,
|
|
106
|
+
flowRef,
|
|
107
|
+
matrixClient,
|
|
108
|
+
async (doc, roomId) => {
|
|
109
|
+
const status = readFlowStatus(doc, roomId);
|
|
110
|
+
if (!status)
|
|
111
|
+
throw new FlowError(
|
|
112
|
+
'flow_not_found',
|
|
113
|
+
'That flow does not exist or has no steps yet.',
|
|
114
|
+
);
|
|
115
|
+
return { steps: status };
|
|
116
|
+
},
|
|
117
|
+
);
|
|
118
|
+
} catch (err) {
|
|
119
|
+
return toToolError(err);
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: 'flow_status',
|
|
124
|
+
description:
|
|
125
|
+
'Get the per-step status of a flow: which steps are idle, running, completed, or failed (with the error), ' +
|
|
126
|
+
'plus which are blocked and by what. Use to report progress or diagnose why a step failed.',
|
|
127
|
+
schema: flowRefSchema,
|
|
128
|
+
},
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function buildExplainStepTool(
|
|
133
|
+
matrixClient: MatrixClient | undefined,
|
|
134
|
+
): PluginTool {
|
|
135
|
+
return tool(
|
|
136
|
+
async (args, ctx: RuntimeContext) => {
|
|
137
|
+
try {
|
|
138
|
+
const { flowRef, stepId } = stepRefSchema.parse(args);
|
|
139
|
+
return await withFlowDoc(
|
|
140
|
+
ctx,
|
|
141
|
+
flowRef,
|
|
142
|
+
matrixClient,
|
|
143
|
+
async (doc, roomId) => {
|
|
144
|
+
const explanation = explainStep(doc, roomId, stepId);
|
|
145
|
+
if (!explanation)
|
|
146
|
+
throw new FlowError(
|
|
147
|
+
'step_not_found',
|
|
148
|
+
`No step "${stepId}" in this flow.`,
|
|
149
|
+
);
|
|
150
|
+
return explanation;
|
|
151
|
+
},
|
|
152
|
+
);
|
|
153
|
+
} catch (err) {
|
|
154
|
+
return toToolError(err);
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: 'explain_step',
|
|
159
|
+
description:
|
|
160
|
+
'Explain in plain language what a step will do and the inputs it will run with, plus its current status. ' +
|
|
161
|
+
'Use to walk the user through a step before they run it.',
|
|
162
|
+
schema: stepRefSchema,
|
|
163
|
+
},
|
|
164
|
+
);
|
|
165
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Linkage tools (spec §3.2) — typed wiring checks. `check_link` and
|
|
3
|
+
* `compatible_actions` read the flow; `requirements` is a pure action lookup.
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import type { MatrixClient } from 'matrix-js-sdk';
|
|
7
|
+
import { tool } from '../../../plugin-api/tool-helper';
|
|
8
|
+
import type { PluginTool, RuntimeContext } from '../../../plugin-api/types';
|
|
9
|
+
import { toToolError } from '../errors';
|
|
10
|
+
import { withFlowDoc } from '../flow-doc';
|
|
11
|
+
import { checkLink, compatibleActions, requirements } from '../linkage';
|
|
12
|
+
|
|
13
|
+
const flowRef = z
|
|
14
|
+
.string()
|
|
15
|
+
.optional()
|
|
16
|
+
.describe('Which flow. Omit to use the flow that is currently open.');
|
|
17
|
+
|
|
18
|
+
const checkLinkSchema = z.object({
|
|
19
|
+
flowRef,
|
|
20
|
+
fromStep: z.string().min(1).describe('The step producing the value.'),
|
|
21
|
+
field: z.string().min(1).describe('The output field of fromStep.'),
|
|
22
|
+
toStep: z.string().min(1).describe('The step receiving the value.'),
|
|
23
|
+
input: z.string().min(1).describe('The input of toStep to feed.'),
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const compatibleSchema = z.object({
|
|
27
|
+
flowRef,
|
|
28
|
+
stepId: z
|
|
29
|
+
.string()
|
|
30
|
+
.min(1)
|
|
31
|
+
.describe('The step whose input you want to satisfy.'),
|
|
32
|
+
forInput: z.string().min(1).describe('The input name you want to fill.'),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const requirementsSchema = z.object({
|
|
36
|
+
action: z.string().min(1).describe('Action name (from list_actions).'),
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export function buildLinkageTools(
|
|
40
|
+
matrixClient: MatrixClient | undefined,
|
|
41
|
+
): PluginTool[] {
|
|
42
|
+
return [
|
|
43
|
+
tool(
|
|
44
|
+
async (args, ctx: RuntimeContext) => {
|
|
45
|
+
try {
|
|
46
|
+
const {
|
|
47
|
+
flowRef: ref,
|
|
48
|
+
fromStep,
|
|
49
|
+
field,
|
|
50
|
+
toStep,
|
|
51
|
+
input,
|
|
52
|
+
} = checkLinkSchema.parse(args);
|
|
53
|
+
return await withFlowDoc(
|
|
54
|
+
ctx,
|
|
55
|
+
ref,
|
|
56
|
+
matrixClient,
|
|
57
|
+
async (doc, roomId) =>
|
|
58
|
+
checkLink(doc, roomId, fromStep, field, toStep, input),
|
|
59
|
+
);
|
|
60
|
+
} catch (err) {
|
|
61
|
+
return toToolError(err);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'check_link',
|
|
66
|
+
description:
|
|
67
|
+
"Check whether one step's output field can feed another step's input. Catches references to outputs a step " +
|
|
68
|
+
"doesn't produce, and flags type mismatches.",
|
|
69
|
+
schema: checkLinkSchema,
|
|
70
|
+
},
|
|
71
|
+
),
|
|
72
|
+
tool(
|
|
73
|
+
async (args, ctx: RuntimeContext) => {
|
|
74
|
+
try {
|
|
75
|
+
const {
|
|
76
|
+
flowRef: ref,
|
|
77
|
+
stepId,
|
|
78
|
+
forInput,
|
|
79
|
+
} = compatibleSchema.parse(args);
|
|
80
|
+
return await withFlowDoc(
|
|
81
|
+
ctx,
|
|
82
|
+
ref,
|
|
83
|
+
matrixClient,
|
|
84
|
+
async (doc, roomId) => ({
|
|
85
|
+
producers: compatibleActions(doc, roomId, stepId, forInput),
|
|
86
|
+
}),
|
|
87
|
+
);
|
|
88
|
+
} catch (err) {
|
|
89
|
+
return toToolError(err);
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'compatible_actions',
|
|
94
|
+
description:
|
|
95
|
+
'List the actions (and their output field) that produce a value compatible with a given input, so you can ' +
|
|
96
|
+
'pick an upstream step to wire in.',
|
|
97
|
+
schema: compatibleSchema,
|
|
98
|
+
},
|
|
99
|
+
),
|
|
100
|
+
tool(
|
|
101
|
+
async (args) => {
|
|
102
|
+
try {
|
|
103
|
+
const { action } = requirementsSchema.parse(args);
|
|
104
|
+
return { requires: requirements(action) };
|
|
105
|
+
} catch (err) {
|
|
106
|
+
return toToolError(err);
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: 'requirements',
|
|
111
|
+
description:
|
|
112
|
+
"List an action's prerequisites (e.g. a needed role, connection, or collection) before using it in a flow.",
|
|
113
|
+
schema: requirementsSchema,
|
|
114
|
+
},
|
|
115
|
+
),
|
|
116
|
+
];
|
|
117
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings mutators (spec §3.4) — one focused tool per setting, each a
|
|
3
|
+
* per-block / delta edit (§4.2). Every tool resolves the flow, runs its edit
|
|
4
|
+
* against the connected doc, and returns `{ ok: true }`.
|
|
5
|
+
*/
|
|
6
|
+
import type { MatrixClient } from 'matrix-js-sdk';
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import { tool } from '../../../plugin-api/tool-helper';
|
|
9
|
+
import type { PluginTool, RuntimeContext } from '../../../plugin-api/types';
|
|
10
|
+
import {
|
|
11
|
+
setStepAssignment,
|
|
12
|
+
setStepConditions,
|
|
13
|
+
setStepConfirmation,
|
|
14
|
+
setStepInputs,
|
|
15
|
+
setStepSchedule,
|
|
16
|
+
setStepTrigger,
|
|
17
|
+
} from '../edit';
|
|
18
|
+
import { toToolError } from '../errors';
|
|
19
|
+
import { withFlowDoc } from '../flow-doc';
|
|
20
|
+
import { conditionSchema, dueSchema } from '../types';
|
|
21
|
+
|
|
22
|
+
const base = {
|
|
23
|
+
flowRef: z
|
|
24
|
+
.string()
|
|
25
|
+
.optional()
|
|
26
|
+
.describe('Which flow. Omit to use the flow that is currently open.'),
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const inputsSchema = z.object({
|
|
30
|
+
...base,
|
|
31
|
+
stepId: z.string().min(1),
|
|
32
|
+
inputs: z.record(z.string(), z.unknown()),
|
|
33
|
+
});
|
|
34
|
+
const conditionsSchema = z.object({
|
|
35
|
+
...base,
|
|
36
|
+
stepId: z.string().min(1),
|
|
37
|
+
conditions: z.array(conditionSchema),
|
|
38
|
+
});
|
|
39
|
+
const scheduleSchema = z.object({
|
|
40
|
+
...base,
|
|
41
|
+
stepId: z.string().min(1),
|
|
42
|
+
due: dueSchema.optional(),
|
|
43
|
+
commitTo: z.string().optional(),
|
|
44
|
+
});
|
|
45
|
+
const assignmentSchema = z.object({
|
|
46
|
+
...base,
|
|
47
|
+
stepId: z.string().min(1),
|
|
48
|
+
assignTo: z.string().nullable().optional(),
|
|
49
|
+
});
|
|
50
|
+
const confirmationSchema = z.object({
|
|
51
|
+
...base,
|
|
52
|
+
stepId: z.string().min(1),
|
|
53
|
+
requireConfirmation: z.boolean(),
|
|
54
|
+
});
|
|
55
|
+
const triggerSchema = z.object({
|
|
56
|
+
...base,
|
|
57
|
+
stepId: z.string().min(1),
|
|
58
|
+
trigger: z.enum(['manual', 'flow-start']),
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const ok = { ok: true } as const;
|
|
62
|
+
|
|
63
|
+
export function buildSettingsTools(
|
|
64
|
+
matrixClient: MatrixClient | undefined,
|
|
65
|
+
): PluginTool[] {
|
|
66
|
+
return [
|
|
67
|
+
tool(
|
|
68
|
+
async (args, ctx: RuntimeContext) => {
|
|
69
|
+
try {
|
|
70
|
+
const { flowRef, stepId, inputs } = inputsSchema.parse(args);
|
|
71
|
+
await withFlowDoc(ctx, flowRef, matrixClient, async (doc) =>
|
|
72
|
+
setStepInputs(doc, stepId, inputs),
|
|
73
|
+
);
|
|
74
|
+
return ok;
|
|
75
|
+
} catch (err) {
|
|
76
|
+
return toToolError(err);
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: 'set_step_inputs',
|
|
81
|
+
description:
|
|
82
|
+
'Set a step\'s inputs. Reference an upstream output as "{{step-id.output.field}}" — either as the whole value, or embedded inside a longer string (e.g. a prompt: "Employee {{a.output.name}} submitted {{a.output.amount}}."). Replaces the ENTIRE inputs object — it does not merge.',
|
|
83
|
+
schema: inputsSchema,
|
|
84
|
+
},
|
|
85
|
+
),
|
|
86
|
+
tool(
|
|
87
|
+
async (args, ctx: RuntimeContext) => {
|
|
88
|
+
try {
|
|
89
|
+
const { flowRef, stepId, conditions } = conditionsSchema.parse(args);
|
|
90
|
+
await withFlowDoc(ctx, flowRef, matrixClient, async (doc) =>
|
|
91
|
+
setStepConditions(doc, stepId, conditions),
|
|
92
|
+
);
|
|
93
|
+
return ok;
|
|
94
|
+
} catch (err) {
|
|
95
|
+
return toToolError(err);
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'set_step_conditions',
|
|
100
|
+
description:
|
|
101
|
+
'Set the activation conditions on a step (all must pass). Conditions gate on an upstream step’s configured value. Pass an empty list to clear them.',
|
|
102
|
+
schema: conditionsSchema,
|
|
103
|
+
},
|
|
104
|
+
),
|
|
105
|
+
tool(
|
|
106
|
+
async (args, ctx: RuntimeContext) => {
|
|
107
|
+
try {
|
|
108
|
+
const { flowRef, stepId, due, commitTo } = scheduleSchema.parse(args);
|
|
109
|
+
await withFlowDoc(ctx, flowRef, matrixClient, async (doc) =>
|
|
110
|
+
setStepSchedule(doc, stepId, due, commitTo),
|
|
111
|
+
);
|
|
112
|
+
return ok;
|
|
113
|
+
} catch (err) {
|
|
114
|
+
return toToolError(err);
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: 'set_step_schedule',
|
|
119
|
+
description:
|
|
120
|
+
'Set when a step is due (an absolute date and/or a duration after it becomes active).',
|
|
121
|
+
schema: scheduleSchema,
|
|
122
|
+
},
|
|
123
|
+
),
|
|
124
|
+
tool(
|
|
125
|
+
async (args, ctx: RuntimeContext) => {
|
|
126
|
+
try {
|
|
127
|
+
const { flowRef, stepId, assignTo } = assignmentSchema.parse(args);
|
|
128
|
+
await withFlowDoc(ctx, flowRef, matrixClient, async (doc) =>
|
|
129
|
+
setStepAssignment(doc, stepId, assignTo ?? undefined),
|
|
130
|
+
);
|
|
131
|
+
return ok;
|
|
132
|
+
} catch (err) {
|
|
133
|
+
return toToolError(err);
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: 'set_step_assignment',
|
|
138
|
+
description:
|
|
139
|
+
'Set who is meant to run a step (a DID or known alias). This is metadata only — it grants nothing.',
|
|
140
|
+
schema: assignmentSchema,
|
|
141
|
+
},
|
|
142
|
+
),
|
|
143
|
+
tool(
|
|
144
|
+
async (args, ctx: RuntimeContext) => {
|
|
145
|
+
try {
|
|
146
|
+
const { flowRef, stepId, requireConfirmation } =
|
|
147
|
+
confirmationSchema.parse(args);
|
|
148
|
+
await withFlowDoc(ctx, flowRef, matrixClient, async (doc) =>
|
|
149
|
+
setStepConfirmation(doc, stepId, requireConfirmation),
|
|
150
|
+
);
|
|
151
|
+
return ok;
|
|
152
|
+
} catch (err) {
|
|
153
|
+
return toToolError(err);
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
name: 'set_step_confirmation',
|
|
158
|
+
description:
|
|
159
|
+
'Set whether the portal should force a confirmation before this step runs.',
|
|
160
|
+
schema: confirmationSchema,
|
|
161
|
+
},
|
|
162
|
+
),
|
|
163
|
+
tool(
|
|
164
|
+
async (args, ctx: RuntimeContext) => {
|
|
165
|
+
try {
|
|
166
|
+
const { flowRef, stepId, trigger } = triggerSchema.parse(args);
|
|
167
|
+
await withFlowDoc(ctx, flowRef, matrixClient, async (doc) =>
|
|
168
|
+
setStepTrigger(doc, stepId, trigger),
|
|
169
|
+
);
|
|
170
|
+
return ok;
|
|
171
|
+
} catch (err) {
|
|
172
|
+
return toToolError(err);
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
name: 'set_step_trigger',
|
|
177
|
+
description:
|
|
178
|
+
"Set when a step runs: 'manual' (the user invokes it) or 'flow-start' (runs when the flow begins). " +
|
|
179
|
+
"For an event-driven auto-trigger, set the step's onEvent via update_step; setting 'manual' here clears one.",
|
|
180
|
+
schema: triggerSchema,
|
|
181
|
+
},
|
|
182
|
+
),
|
|
183
|
+
];
|
|
184
|
+
}
|