@ericsanchezok/synergy-plugin 2.4.3 → 2.4.5
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 +117 -20
- package/dist/artifact.d.ts +15 -0
- package/dist/artifact.js +52 -0
- package/dist/display.d.ts +2 -4
- package/dist/example.d.ts +1 -1
- package/dist/example.js +1 -1
- package/dist/hooks.js +3 -3
- package/dist/ids.d.ts +13 -0
- package/dist/ids.js +33 -0
- package/dist/index.d.ts +52 -14
- package/dist/index.js +6 -2
- package/dist/manifest.d.ts +92 -73
- package/dist/manifest.js +59 -47
- package/dist/market.d.ts +34 -0
- package/dist/market.js +65 -0
- package/dist/paths.d.ts +5 -0
- package/dist/paths.js +14 -0
- package/dist/permissions.d.ts +185 -0
- package/dist/permissions.js +51 -0
- package/dist/policy.d.ts +1 -0
- package/dist/policy.js +1 -0
- package/dist/spec.d.ts +3 -0
- package/dist/spec.js +31 -0
- package/dist/tool.d.ts +25 -4
- package/dist/ui.d.ts +17 -6
- package/dist/version.d.ts +2 -0
- package/dist/version.js +2 -0
- package/package.json +50 -15
package/README.md
CHANGED
|
@@ -65,15 +65,14 @@ export default plugin
|
|
|
65
65
|
|
|
66
66
|
Tools can return user-facing files through `attachments`. Use the generated SDK `asset.upload()` route or the public `/asset` endpoint to upload binary data, then return the resulting `asset://...` URL. Do not import Synergy internal asset modules from a plugin.
|
|
67
67
|
|
|
68
|
-
For visual tools whose output belongs in the main answer area,
|
|
68
|
+
For visual tools whose output belongs in the main answer area, hide the tool card and set presentation on the returned attachment:
|
|
69
69
|
|
|
70
70
|
```ts
|
|
71
71
|
return {
|
|
72
72
|
output: "",
|
|
73
73
|
metadata: {
|
|
74
74
|
display: {
|
|
75
|
-
|
|
76
|
-
primaryAttachmentIds: [partId],
|
|
75
|
+
toolCard: "hidden",
|
|
77
76
|
},
|
|
78
77
|
},
|
|
79
78
|
attachments: [
|
|
@@ -81,31 +80,29 @@ return {
|
|
|
81
80
|
id: partId,
|
|
82
81
|
sessionID: context.sessionID,
|
|
83
82
|
messageID: context.messageID,
|
|
84
|
-
type: "
|
|
83
|
+
type: "attachment",
|
|
85
84
|
mime: "image/svg+xml",
|
|
86
85
|
filename: "result.svg",
|
|
87
86
|
url: uploaded.url,
|
|
87
|
+
presentation: { renderer: "image", size: "medium", crop: false },
|
|
88
|
+
model: { mode: "summary", summary: "Generated SVG result." },
|
|
88
89
|
},
|
|
89
90
|
],
|
|
90
91
|
}
|
|
91
92
|
```
|
|
92
93
|
|
|
93
|
-
|
|
94
|
+
Each attachment controls its own display with `presentation.hidden`, `presentation.renderer`, `presentation.size`, and `presentation.crop`. Omit `renderer` to let Synergy choose from the MIME type.
|
|
94
95
|
|
|
95
|
-
For image, video, or audio generation tools, declare the display protocol on the tool definition as well. This lets Synergy show its built-in media generation placeholder as soon as the tool starts, then replace it with the
|
|
96
|
+
For image, video, or audio generation tools, declare the display protocol on the tool definition as well. This lets Synergy show its built-in media generation placeholder as soon as the tool starts, then replace it with the completed attachment in the original message order:
|
|
96
97
|
|
|
97
98
|
```ts
|
|
98
99
|
const mediaDisplay = {
|
|
99
100
|
kind: "media-generation",
|
|
100
|
-
|
|
101
|
-
presentation: "artifact-only",
|
|
101
|
+
toolCard: "hidden",
|
|
102
102
|
media: {
|
|
103
103
|
type: "image",
|
|
104
|
-
actionLabel: "Create image",
|
|
105
|
-
pendingTitle: "Generating image",
|
|
106
|
-
pendingDescription: "Preparing the image...",
|
|
107
|
-
promptField: "prompt",
|
|
108
104
|
aspectRatio: "1:1",
|
|
105
|
+
size: "small",
|
|
109
106
|
},
|
|
110
107
|
} as const
|
|
111
108
|
|
|
@@ -116,12 +113,12 @@ tool({
|
|
|
116
113
|
prompt: tool.schema.string(),
|
|
117
114
|
},
|
|
118
115
|
async execute(args, context) {
|
|
119
|
-
// Upload the generated image, then return
|
|
116
|
+
// Upload the generated image, then return it with attachment-level presentation.
|
|
120
117
|
},
|
|
121
118
|
})
|
|
122
119
|
```
|
|
123
120
|
|
|
124
|
-
Use `
|
|
121
|
+
Use `toolCard: "hidden"` for tools whose running and completed states belong on a dedicated surface instead of a tool card. Optional media labels are for accessibility and host-specific status surfaces; Synergy does not show tool input parameters as transcript copy.
|
|
125
122
|
|
|
126
123
|
## Internal Tools And Delegated Tasks
|
|
127
124
|
|
|
@@ -152,7 +149,7 @@ const plan = await context.task?.run({
|
|
|
152
149
|
"plugin__my-plugin__private_helper": true,
|
|
153
150
|
},
|
|
154
151
|
visibility: "hidden",
|
|
155
|
-
timeoutMs:
|
|
152
|
+
timeoutMs: 120_000,
|
|
156
153
|
output: {
|
|
157
154
|
mode: "structured",
|
|
158
155
|
schema: {
|
|
@@ -169,6 +166,69 @@ const plan = await context.task?.run({
|
|
|
169
166
|
|
|
170
167
|
When `output.mode` is `structured`, Cortex validates the child task result against the schema and may run repair turns before completing. Cortex still stores its normal task trajectory summary in `task.result`; the structured value is returned to the plugin call site as `plan.outputResult.data`.
|
|
171
168
|
|
|
169
|
+
## Hooks
|
|
170
|
+
|
|
171
|
+
Plugins return hooks from `init()`. Hook permissions are declared in `plugin.json` and Synergy only invokes permissioned hooks.
|
|
172
|
+
|
|
173
|
+
### Event hook
|
|
174
|
+
|
|
175
|
+
`event(input)` observes runtime bus events without mutating them. Declare event access under `permissions.hooks`:
|
|
176
|
+
|
|
177
|
+
```jsonc
|
|
178
|
+
{
|
|
179
|
+
"permissions": {
|
|
180
|
+
"hooks": {
|
|
181
|
+
"events": "selected",
|
|
182
|
+
"eventNames": ["session.*", "message.updated"],
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
`events` is `"none"`, `"selected"`, or `"all"`. In selected mode, `eventNames` supports exact names, `*` for all events, and prefix wildcards ending in `.*` such as `session.*`.
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
event(input) {
|
|
192
|
+
console.log(input.event.type, input.event.properties)
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Config hook
|
|
197
|
+
|
|
198
|
+
`config(input, output)` observes a redacted runtime config snapshot at startup, plugin reload, and config reload. Declare `permissions.hooks.config: true`; this permission is separate from `permissions.data.config`.
|
|
199
|
+
|
|
200
|
+
```jsonc
|
|
201
|
+
{
|
|
202
|
+
"permissions": {
|
|
203
|
+
"hooks": {
|
|
204
|
+
"config": true,
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
config(input, output) {
|
|
212
|
+
console.log(input.source, input.changedFields)
|
|
213
|
+
console.log(output.config.model)
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
`input.source` is `"startup"`, `"plugin_reload"`, or `"reload"`. Secret fields in `output.config` are replaced with Synergy's redacted sentinel before dispatch.
|
|
218
|
+
|
|
219
|
+
### System prompt transform
|
|
220
|
+
|
|
221
|
+
`experimental.chat.system.transform(input, output)` can rewrite the assembled system prompt when `permissions.hooks.promptTransform` is `true`. Synergy calls this hook in two phases: `input.phase === "budget"` before token budgeting and `input.phase === "final"` before the provider call. The input includes `sessionID`, `agent`, `model`, `messageID`, and `small` for final calls.
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
"experimental.chat.system.transform"(input, output) {
|
|
225
|
+
if (input.phase !== "final") return
|
|
226
|
+
output.system.push("Additional final-call instruction.")
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
If a transform empties `output.system`, Synergy restores the original system prompt.
|
|
231
|
+
|
|
172
232
|
## Plugin Input
|
|
173
233
|
|
|
174
234
|
`init(input)` receives runtime services scoped to the active Synergy Scope:
|
|
@@ -188,7 +248,7 @@ type PluginInput = {
|
|
|
188
248
|
}
|
|
189
249
|
```
|
|
190
250
|
|
|
191
|
-
For isolated worker/process plugins, these services are proxied through the host bridge and checked against the plugin approval record.
|
|
251
|
+
For isolated worker/process plugins, these services are proxied through the host bridge and checked against the plugin approval record. Workspace file and shell bridge calls require an active plugin tool context; read plugin package assets directly from `input.pluginDir`.
|
|
192
252
|
|
|
193
253
|
## Manifest
|
|
194
254
|
|
|
@@ -200,9 +260,11 @@ Each distributable plugin has a root `plugin.json`:
|
|
|
200
260
|
"version": "0.1.0",
|
|
201
261
|
"description": "Example Synergy plugin",
|
|
202
262
|
"main": "./src/index.ts",
|
|
263
|
+
"engines": {
|
|
264
|
+
"synergy": ">=2.4.3",
|
|
265
|
+
},
|
|
203
266
|
"permissions": {
|
|
204
267
|
"tools": {
|
|
205
|
-
"invoke": true,
|
|
206
268
|
"filesystem": "none",
|
|
207
269
|
"network": false,
|
|
208
270
|
"shell": false,
|
|
@@ -235,15 +297,50 @@ Each distributable plugin has a root `plugin.json`:
|
|
|
235
297
|
|
|
236
298
|
`contributes.ui.entry` is a runtime-loadable JavaScript asset. Source files such as `src/ui.tsx` are only build inputs. `synergy-plugin build` uses the conventional UI source path and writes the compiled bundle to the declared entry.
|
|
237
299
|
|
|
300
|
+
Session workbench UI uses `contributes.ui.workbenchPanels`. A workbench panel declares which surface it belongs to and how its tabs behave:
|
|
301
|
+
|
|
302
|
+
```jsonc
|
|
303
|
+
{
|
|
304
|
+
"contributes": {
|
|
305
|
+
"ui": {
|
|
306
|
+
"entry": "./dist/ui/index.js",
|
|
307
|
+
"workbenchPanels": [
|
|
308
|
+
{
|
|
309
|
+
"id": "build-log",
|
|
310
|
+
"label": "Build Log",
|
|
311
|
+
"icon": "terminal",
|
|
312
|
+
"exportName": "BuildLogPanel",
|
|
313
|
+
"surface": "bottom",
|
|
314
|
+
"cardinality": "multi",
|
|
315
|
+
"requiresSession": true,
|
|
316
|
+
},
|
|
317
|
+
],
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
"permissions": {
|
|
321
|
+
"ui": {
|
|
322
|
+
"workbenchPanels": true,
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
`surface` is `"side"` or `"bottom"`. `cardinality` is `"exclusive"` for one active panel on that surface, `"singleton"` for one tab per panel id, or `"multi"` for a new tab each time. `requiresSession` hides the panel until the user is in a concrete session. App panels remain separate under `contributes.ui.appPanels` and create top-level sidebar entries.
|
|
329
|
+
|
|
238
330
|
## UI Types
|
|
239
331
|
|
|
240
332
|
UI contribution types are exported separately:
|
|
241
333
|
|
|
242
334
|
```ts
|
|
243
|
-
import type {
|
|
335
|
+
import type {
|
|
336
|
+
PluginToolRendererProps,
|
|
337
|
+
PluginWorkbenchPanel,
|
|
338
|
+
PluginPanelProps,
|
|
339
|
+
PluginMessageSlotProps,
|
|
340
|
+
} from "@ericsanchezok/synergy-plugin/ui"
|
|
244
341
|
```
|
|
245
342
|
|
|
246
|
-
Supported UI surfaces are tool renderers, part renderers,
|
|
343
|
+
Supported UI surfaces are tool renderers, part renderers, workbench panels, app panels, settings sections, message slots, themes, icons, app routes, and commands. The Web client loads aggregated UI metadata with the generated SDK method `plugin.listUiContributions()`, which maps to `/plugin/ui/contributions`; plugin JS and assets are still loaded through browser-native asset URLs.
|
|
247
344
|
|
|
248
345
|
## Runtime Modes
|
|
249
346
|
|
|
@@ -266,7 +363,7 @@ Worker and process plugins are started through Synergy's plugin runner. The runn
|
|
|
266
363
|
- `dist/permissions.summary.json`
|
|
267
364
|
- `dist/integrity.json`
|
|
268
365
|
|
|
269
|
-
`synergy-plugin pack` archives `dist/` into `<name>-<version>.synergy-plugin.tgz`. `synergy-plugin sign` writes `<tarball>.sig`. `synergy-plugin publish-market` prepares the official marketplace submission by uploading or checking GitHub Release assets, writing a `SII-Holos/synergy-plugins` entry with the signer public key
|
|
366
|
+
`synergy-plugin pack` archives `dist/` into `<name>-<version>.synergy-plugin.tgz`. `synergy-plugin sign` writes `<tarball>.sig`. `synergy-plugin publish-market` prepares the official marketplace submission by uploading or checking GitHub Release assets, writing a `SII-Holos/synergy-plugins` entry with the signer public key and `compatibility.synergy` from `plugin.json` `engines.synergy`, regenerating the registry index, running registry validation, and opening a PR when `gh` is available.
|
|
270
367
|
|
|
271
368
|
For local marketplace UX testing, the Synergy runtime still provides `synergy plugin publish <tarball>` to publish into the local development registry.
|
|
272
369
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare namespace PluginArtifact {
|
|
2
|
+
const manifestFile = "plugin.json";
|
|
3
|
+
const normalizedManifestFile = "plugin.normalized.json";
|
|
4
|
+
const runtimeEntry = "runtime/index.js";
|
|
5
|
+
const integrityFile = "integrity.json";
|
|
6
|
+
const permissionsSummaryFile = "permissions.summary.json";
|
|
7
|
+
const requiredFiles: readonly ["plugin.json", "runtime/index.js", "integrity.json", "permissions.summary.json"];
|
|
8
|
+
const assetRoutePrefix = "/plugin/assets";
|
|
9
|
+
const allowedAssetRoots: readonly ["dist", "public", "assets", "ui", "themes", "icons"];
|
|
10
|
+
}
|
|
11
|
+
export declare function normalizePluginArtifactPath(filePath: string): string;
|
|
12
|
+
export declare function normalizePluginArchiveEntry(entry: string): string | undefined;
|
|
13
|
+
export declare function pluginArtifactAssetRoot(filePath: string): string;
|
|
14
|
+
export declare function isAllowedPluginAssetPath(filePath: string): boolean;
|
|
15
|
+
export declare function pluginAssetUrl(pluginId: string, versionHash: string, filePath: string): string;
|
package/dist/artifact.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export var PluginArtifact;
|
|
2
|
+
(function (PluginArtifact) {
|
|
3
|
+
PluginArtifact.manifestFile = "plugin.json";
|
|
4
|
+
PluginArtifact.normalizedManifestFile = "plugin.normalized.json";
|
|
5
|
+
PluginArtifact.runtimeEntry = "runtime/index.js";
|
|
6
|
+
PluginArtifact.integrityFile = "integrity.json";
|
|
7
|
+
PluginArtifact.permissionsSummaryFile = "permissions.summary.json";
|
|
8
|
+
PluginArtifact.requiredFiles = [PluginArtifact.manifestFile, PluginArtifact.runtimeEntry, PluginArtifact.integrityFile, PluginArtifact.permissionsSummaryFile];
|
|
9
|
+
PluginArtifact.assetRoutePrefix = "/plugin/assets";
|
|
10
|
+
PluginArtifact.allowedAssetRoots = ["dist", "public", "assets", "ui", "themes", "icons"];
|
|
11
|
+
})(PluginArtifact || (PluginArtifact = {}));
|
|
12
|
+
export function normalizePluginArtifactPath(filePath) {
|
|
13
|
+
const normalized = filePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
14
|
+
if (!normalized || normalized === ".")
|
|
15
|
+
throw new Error("Plugin artifact path cannot be empty");
|
|
16
|
+
if (normalized.startsWith("/") || /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(normalized)) {
|
|
17
|
+
throw new Error(`Plugin artifact path must be relative: ${filePath}`);
|
|
18
|
+
}
|
|
19
|
+
const parts = normalized.split("/").filter(Boolean);
|
|
20
|
+
if (parts.includes(".."))
|
|
21
|
+
throw new Error(`Plugin artifact path cannot escape the plugin root: ${filePath}`);
|
|
22
|
+
return parts.join("/");
|
|
23
|
+
}
|
|
24
|
+
export function normalizePluginArchiveEntry(entry) {
|
|
25
|
+
let normalized = entry.replace(/\r$/, "").replace(/\\/g, "/");
|
|
26
|
+
while (normalized.startsWith("./"))
|
|
27
|
+
normalized = normalized.slice(2);
|
|
28
|
+
normalized = normalized.replace(/\/+$/, "");
|
|
29
|
+
if (!normalized || normalized === ".")
|
|
30
|
+
return undefined;
|
|
31
|
+
return normalizePluginArtifactPath(normalized);
|
|
32
|
+
}
|
|
33
|
+
export function pluginArtifactAssetRoot(filePath) {
|
|
34
|
+
return normalizePluginArtifactPath(filePath).split("/")[0] ?? "";
|
|
35
|
+
}
|
|
36
|
+
export function isAllowedPluginAssetPath(filePath) {
|
|
37
|
+
try {
|
|
38
|
+
const root = pluginArtifactAssetRoot(filePath);
|
|
39
|
+
return PluginArtifact.allowedAssetRoots.includes(root);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export function pluginAssetUrl(pluginId, versionHash, filePath) {
|
|
46
|
+
const normalized = normalizePluginArtifactPath(filePath);
|
|
47
|
+
const encodedPath = normalized
|
|
48
|
+
.split("/")
|
|
49
|
+
.map((part) => encodeURIComponent(part))
|
|
50
|
+
.join("/");
|
|
51
|
+
return `${PluginArtifact.assetRoutePrefix}/${encodeURIComponent(pluginId)}/${encodeURIComponent(versionHash)}/${encodedPath}`;
|
|
52
|
+
}
|
package/dist/display.d.ts
CHANGED
|
@@ -3,13 +3,11 @@ export interface ToolMediaDisplay {
|
|
|
3
3
|
actionLabel?: string;
|
|
4
4
|
pendingTitle?: string;
|
|
5
5
|
pendingDescription?: string;
|
|
6
|
-
promptField?: string;
|
|
7
6
|
aspectRatio?: "1:1" | "4:3" | "16:9" | "auto";
|
|
7
|
+
size?: "small" | "medium" | "large";
|
|
8
8
|
}
|
|
9
9
|
export interface ToolDisplay {
|
|
10
10
|
kind?: "default" | "media-generation";
|
|
11
|
-
|
|
12
|
-
presentation?: "default" | "artifact-only";
|
|
11
|
+
toolCard?: "visible" | "hidden";
|
|
13
12
|
media?: ToolMediaDisplay;
|
|
14
|
-
primaryAttachmentIds?: string[];
|
|
15
13
|
}
|
package/dist/example.d.ts
CHANGED
package/dist/example.js
CHANGED
package/dist/hooks.js
CHANGED
|
@@ -21,13 +21,13 @@ export const HOOKS = [
|
|
|
21
21
|
name: "config",
|
|
22
22
|
category: "core",
|
|
23
23
|
mutatesOutput: false,
|
|
24
|
-
summary: "Observe
|
|
24
|
+
summary: "Observe redacted runtime config snapshots at startup and config reload",
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
27
|
name: "event",
|
|
28
28
|
category: "core",
|
|
29
29
|
mutatesOutput: false,
|
|
30
|
-
summary: "Observe runtime bus events",
|
|
30
|
+
summary: "Observe permitted runtime bus events by exact or wildcard event name",
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
33
|
name: "chat.message",
|
|
@@ -153,7 +153,7 @@ export const HOOKS = [
|
|
|
153
153
|
name: "experimental.chat.system.transform",
|
|
154
154
|
category: "experimental",
|
|
155
155
|
mutatesOutput: true,
|
|
156
|
-
summary: "Rewrite the assembled system prompt",
|
|
156
|
+
summary: "Rewrite the assembled system prompt during budget and final phases",
|
|
157
157
|
},
|
|
158
158
|
{
|
|
159
159
|
name: "experimental.session.compacting",
|
package/dist/ids.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare namespace PluginToolId {
|
|
2
|
+
function format(pluginId: string, toolId: string): string;
|
|
3
|
+
function parse(id: string): {
|
|
4
|
+
pluginId: string;
|
|
5
|
+
toolId: string;
|
|
6
|
+
} | undefined;
|
|
7
|
+
function is(id: string): boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare namespace PluginId {
|
|
10
|
+
function isValid(id: string): boolean;
|
|
11
|
+
function normalize(id: string): string;
|
|
12
|
+
function mcpServerKey(pluginId: string, serverKey: string): string;
|
|
13
|
+
}
|
package/dist/ids.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export var PluginToolId;
|
|
2
|
+
(function (PluginToolId) {
|
|
3
|
+
function format(pluginId, toolId) {
|
|
4
|
+
return `plugin__${pluginId}__${toolId}`;
|
|
5
|
+
}
|
|
6
|
+
PluginToolId.format = format;
|
|
7
|
+
function parse(id) {
|
|
8
|
+
const match = id.match(/^plugin__([^_]+(?:_[^_]+)*?)__([^_].*)$/);
|
|
9
|
+
if (!match)
|
|
10
|
+
return undefined;
|
|
11
|
+
return { pluginId: match[1], toolId: match[2] };
|
|
12
|
+
}
|
|
13
|
+
PluginToolId.parse = parse;
|
|
14
|
+
function is(id) {
|
|
15
|
+
return id.startsWith("plugin__");
|
|
16
|
+
}
|
|
17
|
+
PluginToolId.is = is;
|
|
18
|
+
})(PluginToolId || (PluginToolId = {}));
|
|
19
|
+
export var PluginId;
|
|
20
|
+
(function (PluginId) {
|
|
21
|
+
function isValid(id) {
|
|
22
|
+
return /^[a-z][a-z0-9_-]*$/i.test(id);
|
|
23
|
+
}
|
|
24
|
+
PluginId.isValid = isValid;
|
|
25
|
+
function normalize(id) {
|
|
26
|
+
return id.trim().toLowerCase();
|
|
27
|
+
}
|
|
28
|
+
PluginId.normalize = normalize;
|
|
29
|
+
function mcpServerKey(pluginId, serverKey) {
|
|
30
|
+
return `${pluginId}::${serverKey}`;
|
|
31
|
+
}
|
|
32
|
+
PluginId.mcpServerKey = mcpServerKey;
|
|
33
|
+
})(PluginId || (PluginId = {}));
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import type { AgendaItem, AgendaRunLog, CortexTask,
|
|
2
|
-
import type { BunShell } from "./shell";
|
|
3
|
-
import type { ToolDefinition, ToolResult } from "./tool";
|
|
4
|
-
export * from "./tool";
|
|
5
|
-
export type { ToolDisplay, ToolMediaDisplay } from "./display";
|
|
1
|
+
import type { AgendaItem, AgendaRunLog, CortexTask, createSynergyClient, MemoryCategory, MemoryRecallMode, MemorySearchResult, Model, NoteCreateInput, NoteInfo, NotePatchInput, Provider, PermissionRequest, UserMessage, Message, Part, Auth, Config } from "@ericsanchezok/synergy-sdk";
|
|
2
|
+
import type { BunShell } from "./shell.js";
|
|
3
|
+
import type { ToolDefinition, ToolResult } from "./tool.js";
|
|
4
|
+
export * from "./tool.js";
|
|
5
|
+
export type { ToolDisplay, ToolMediaDisplay } from "./display.js";
|
|
6
6
|
export type { ToolResult };
|
|
7
|
-
export * from "./manifest";
|
|
8
|
-
export
|
|
7
|
+
export * from "./manifest.js";
|
|
8
|
+
export * from "./policy.js";
|
|
9
|
+
export * from "./spec.js";
|
|
10
|
+
export * from "./version.js";
|
|
11
|
+
export * from "./artifact.js";
|
|
12
|
+
export type { BunShell, BunShellOutput, BunShellPromise, ShellExpression, ShellFunction } from "./shell.js";
|
|
9
13
|
export interface PluginConfigAccessor {
|
|
10
14
|
/** Get the plugin's full config object */
|
|
11
15
|
get(): Promise<Record<string, any>>;
|
|
12
|
-
/**
|
|
16
|
+
/** Replace the plugin's config namespace with these values */
|
|
13
17
|
set(values: Record<string, any>): Promise<void>;
|
|
14
18
|
}
|
|
15
19
|
/**
|
|
@@ -310,6 +314,15 @@ export type ProviderProfileHook = {
|
|
|
310
314
|
modelID: string;
|
|
311
315
|
options?: Record<string, any>;
|
|
312
316
|
}) => Promise<any>;
|
|
317
|
+
fetchModelCatalog?: (input: {
|
|
318
|
+
auth?: Auth;
|
|
319
|
+
fetch?: typeof fetch;
|
|
320
|
+
baseURL?: string;
|
|
321
|
+
}) => Promise<Array<{
|
|
322
|
+
id: string;
|
|
323
|
+
rank?: number;
|
|
324
|
+
model?: Partial<Model>;
|
|
325
|
+
}>>;
|
|
313
326
|
fetchModels?: (input: {
|
|
314
327
|
auth?: Auth;
|
|
315
328
|
fetch?: typeof fetch;
|
|
@@ -354,6 +367,33 @@ export interface PluginDescriptor {
|
|
|
354
367
|
/** Initialize the plugin and return hooks */
|
|
355
368
|
init(input: PluginInput): Promise<PluginHooks>;
|
|
356
369
|
}
|
|
370
|
+
export interface PluginEventHookInput {
|
|
371
|
+
event: {
|
|
372
|
+
type: string;
|
|
373
|
+
properties: unknown;
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
export interface PluginConfigHookInput {
|
|
377
|
+
source: "startup" | "reload" | "plugin_reload";
|
|
378
|
+
scopeID?: string;
|
|
379
|
+
scopeType?: string;
|
|
380
|
+
changedFields?: string[];
|
|
381
|
+
timestamp: number;
|
|
382
|
+
}
|
|
383
|
+
export interface PluginConfigHookOutput {
|
|
384
|
+
config: Config;
|
|
385
|
+
}
|
|
386
|
+
export interface PluginChatSystemTransformInput {
|
|
387
|
+
phase: "budget" | "final";
|
|
388
|
+
sessionID: string;
|
|
389
|
+
agent: string;
|
|
390
|
+
model: {
|
|
391
|
+
providerID: string;
|
|
392
|
+
modelID: string;
|
|
393
|
+
};
|
|
394
|
+
messageID?: string;
|
|
395
|
+
small?: boolean;
|
|
396
|
+
}
|
|
357
397
|
export interface PluginHooks {
|
|
358
398
|
/** Called when the plugin is being unloaded (e.g. runtime reload) */
|
|
359
399
|
dispose?(): Promise<void>;
|
|
@@ -370,11 +410,9 @@ export interface PluginHooks {
|
|
|
370
410
|
/** Provider runtime/catalog profiles */
|
|
371
411
|
provider?: ProviderProfileHook | ProviderProfileHook[];
|
|
372
412
|
/** Observe runtime bus events */
|
|
373
|
-
event?(input:
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
/** Observe the loaded runtime config */
|
|
377
|
-
config?(input: Config): Promise<void>;
|
|
413
|
+
event?(input: PluginEventHookInput): Promise<void>;
|
|
414
|
+
/** Observe a redacted runtime config snapshot */
|
|
415
|
+
config?(input: PluginConfigHookInput, output: PluginConfigHookOutput): Promise<void>;
|
|
378
416
|
/** Rewrite incoming user messages */
|
|
379
417
|
"chat.message"?(input: {
|
|
380
418
|
sessionID: string;
|
|
@@ -432,7 +470,7 @@ export interface PluginHooks {
|
|
|
432
470
|
}[];
|
|
433
471
|
}): Promise<void>;
|
|
434
472
|
/** Rewrite the assembled system prompt */
|
|
435
|
-
"experimental.chat.system.transform"?(input:
|
|
473
|
+
"experimental.chat.system.transform"?(input: PluginChatSystemTransformInput, output: {
|
|
436
474
|
system: string[];
|
|
437
475
|
}): Promise<void>;
|
|
438
476
|
/** Customize session compaction */
|
package/dist/index.js
CHANGED