@openclaw/plugin-inspector 0.3.10 → 0.3.12
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/CHANGELOG.md +21 -0
- package/README.md +6 -2
- package/package.json +8 -2
- package/src/advanced.js +1 -0
- package/src/api.js +4 -0
- package/src/batch.js +297 -0
- package/src/capture-cli.js +12 -1
- package/src/capture-config.js +49 -1
- package/src/cli.js +103 -6
- package/src/compatibility-report.js +4 -4
- package/src/contract-coverage.js +6 -1
- package/src/contract-probes.js +5 -0
- package/src/execution-results.js +10 -0
- package/src/fixture-summary.js +101 -4
- package/src/index.js +15 -0
- package/src/inspector.js +1 -0
- package/src/issues.js +17 -2
- package/src/report.js +26 -9
- package/src/runtime-reconciliation.js +4 -1
- package/src/sdk-mock.js +153 -1
- package/src/synthetic-entrypoint.js +47 -0
- package/src/synthetic-probes-cli.js +2 -35
- package/src/synthetic-probes.js +59 -0
package/src/sdk-mock.js
CHANGED
|
@@ -377,6 +377,9 @@ function parseModuleImports(text) {
|
|
|
377
377
|
];
|
|
378
378
|
for (const pattern of patterns) {
|
|
379
379
|
for (const match of text.matchAll(pattern)) {
|
|
380
|
+
if (isTypeOnlyImportOrExport(match[0], match[1] ?? "")) {
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
380
383
|
const specifier = match[2];
|
|
381
384
|
if (specifier) {
|
|
382
385
|
entries.push({ specifier, names: parseNamedImports(match[1] ?? "") });
|
|
@@ -389,6 +392,10 @@ function parseModuleImports(text) {
|
|
|
389
392
|
return entries;
|
|
390
393
|
}
|
|
391
394
|
|
|
395
|
+
function isTypeOnlyImportOrExport(statement, clause) {
|
|
396
|
+
return /^\s*import\s+type\b/u.test(statement) || /^\s*export\s+type\b/u.test(statement) || /^\s*type\b/u.test(clause);
|
|
397
|
+
}
|
|
398
|
+
|
|
392
399
|
function parseNamedImports(clause) {
|
|
393
400
|
const names = new Set();
|
|
394
401
|
const named = /\{([\s\S]*?)\}/.exec(clause)?.[1] ?? clause;
|
|
@@ -459,11 +466,22 @@ export async function resolve(specifier, context, nextResolve) {
|
|
|
459
466
|
export async function load(url, context, nextLoad) {
|
|
460
467
|
if (url.startsWith("file:") && /\\.[cm]?ts$/u.test(fileURLToPath(url))) {
|
|
461
468
|
const rawSource = await readFile(fileURLToPath(url), "utf8");
|
|
462
|
-
return { format: "module", source:
|
|
469
|
+
return { format: "module", source: stripPluginTypeScript(rawSource), shortCircuit: true };
|
|
463
470
|
}
|
|
464
471
|
return nextLoad(url, context);
|
|
465
472
|
}
|
|
466
473
|
|
|
474
|
+
function stripPluginTypeScript(source) {
|
|
475
|
+
try {
|
|
476
|
+
return stripTypeScriptTypes(source, { mode: "transform" });
|
|
477
|
+
} catch (error) {
|
|
478
|
+
if (error?.code !== "ERR_INVALID_ARG_VALUE") {
|
|
479
|
+
throw error;
|
|
480
|
+
}
|
|
481
|
+
return stripTypeScriptTypes(source, { mode: "strip" });
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
467
485
|
function moduleUrl(filePath) {
|
|
468
486
|
return { url: pathToFileURL(filePath).href, shortCircuit: true };
|
|
469
487
|
}
|
|
@@ -653,6 +671,24 @@ function resolveExistingSourcePath(target) {
|
|
|
653
671
|
` : ""}
|
|
654
672
|
function createMockValue(name) {
|
|
655
673
|
function fn(...args) {
|
|
674
|
+
if (name === "resolveDefaultAgentDir") {
|
|
675
|
+
return mockAgentDir();
|
|
676
|
+
}
|
|
677
|
+
if (name === "resolveAgentDir") {
|
|
678
|
+
return mockAgentDir(args[1]);
|
|
679
|
+
}
|
|
680
|
+
if (name === "resolveUserPath") {
|
|
681
|
+
return typeof args[0] === "string" ? args[0] : mockAgentDir();
|
|
682
|
+
}
|
|
683
|
+
if (name === "resolveAuthProfileOrder") {
|
|
684
|
+
return [];
|
|
685
|
+
}
|
|
686
|
+
if (name === "resolveWindowsSpawnProgram") {
|
|
687
|
+
return mockWindowsSpawnProgram(args[0]);
|
|
688
|
+
}
|
|
689
|
+
if (name === "materializeWindowsSpawnProgram") {
|
|
690
|
+
return mockWindowsSpawnInvocation(args[0], args[1]);
|
|
691
|
+
}
|
|
656
692
|
if (name === "resolvePreferredOpenClawTmpDir") {
|
|
657
693
|
return process.env.TMPDIR || "/tmp";
|
|
658
694
|
}
|
|
@@ -689,6 +725,80 @@ function createMockValue(name) {
|
|
|
689
725
|
});
|
|
690
726
|
}
|
|
691
727
|
|
|
728
|
+
function mockAgentDir(agentId = "main") {
|
|
729
|
+
const base = process.env.TMPDIR || process.env.TEMP || process.env.TMP || "/tmp";
|
|
730
|
+
const safeAgentId = String(agentId || "main").replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
731
|
+
return base.replace(/[\\/]+$/, "") + "/plugin-inspector-openclaw/agents/" + safeAgentId + "/agent";
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
function mockWindowsSpawnProgram(params = {}) {
|
|
735
|
+
return {
|
|
736
|
+
command: typeof params.command === "string" && params.command.trim() ? params.command : process.execPath,
|
|
737
|
+
leadingArgv: [],
|
|
738
|
+
resolution: "mock",
|
|
739
|
+
packageName: typeof params.packageName === "string" ? params.packageName : undefined,
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
function mockWindowsSpawnInvocation(program = {}, argv = []) {
|
|
744
|
+
const command = typeof program.command === "string" && program.command.trim() ? program.command : process.execPath;
|
|
745
|
+
if (program.packageName === "@openai/codex") {
|
|
746
|
+
return {
|
|
747
|
+
command: process.execPath,
|
|
748
|
+
argv: ["-e", mockCodexAppServerScript()],
|
|
749
|
+
resolution: program.resolution ?? "mock",
|
|
750
|
+
windowsHide: true,
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
return {
|
|
754
|
+
command,
|
|
755
|
+
argv: [...(Array.isArray(program.leadingArgv) ? program.leadingArgv : []), ...(Array.isArray(argv) ? argv : [])],
|
|
756
|
+
resolution: program.resolution ?? "mock",
|
|
757
|
+
shell: program.shell,
|
|
758
|
+
windowsHide: program.windowsHide,
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
function mockCodexAppServerScript() {
|
|
763
|
+
return [
|
|
764
|
+
"const readline = require('node:readline');",
|
|
765
|
+
"const rl = readline.createInterface({ input: process.stdin });",
|
|
766
|
+
"let idleTimer;",
|
|
767
|
+
"function scheduleIdleExit() {",
|
|
768
|
+
" if (idleTimer) clearTimeout(idleTimer);",
|
|
769
|
+
" idleTimer = setTimeout(() => process.exit(0), 1000);",
|
|
770
|
+
"}",
|
|
771
|
+
"function write(id, result) { process.stdout.write(JSON.stringify({ id, result }) + String.fromCharCode(10)); }",
|
|
772
|
+
"rl.on('line', (line) => {",
|
|
773
|
+
" let message;",
|
|
774
|
+
" try { message = JSON.parse(line); } catch { return; }",
|
|
775
|
+
" if (message.id === undefined || message.id === null) return;",
|
|
776
|
+
" switch (message.method) {",
|
|
777
|
+
" case 'initialize':",
|
|
778
|
+
" write(message.id, { userAgent: 'openclaw/999.0.0 (plugin-inspector mock)' });",
|
|
779
|
+
" break;",
|
|
780
|
+
" case 'model/list':",
|
|
781
|
+
" write(message.id, { data: [] });",
|
|
782
|
+
" break;",
|
|
783
|
+
" case 'thread/list':",
|
|
784
|
+
" case 'mcpServerStatus/list':",
|
|
785
|
+
" case 'skills/list':",
|
|
786
|
+
" write(message.id, { data: [] });",
|
|
787
|
+
" break;",
|
|
788
|
+
" case 'account/read':",
|
|
789
|
+
" write(message.id, null);",
|
|
790
|
+
" break;",
|
|
791
|
+
" case 'account/rateLimits/read':",
|
|
792
|
+
" write(message.id, null);",
|
|
793
|
+
" break;",
|
|
794
|
+
" default:",
|
|
795
|
+
" process.stdout.write(JSON.stringify({ id: message.id, error: { code: -32601, message: 'mock method not implemented' } }) + String.fromCharCode(10));",
|
|
796
|
+
" }",
|
|
797
|
+
" scheduleIdleExit();",
|
|
798
|
+
"});",
|
|
799
|
+
].join("\\n");
|
|
800
|
+
}
|
|
801
|
+
|
|
692
802
|
function createZNamespace() {
|
|
693
803
|
const namespace = {
|
|
694
804
|
any: () => createSchema(),
|
|
@@ -1665,11 +1775,53 @@ export const OPENAI_RESPONSES_STREAM_HOOKS = buildProviderStreamFamilyHooks("ope
|
|
|
1665
1775
|
export const OPENROUTER_THINKING_STREAM_HOOKS = buildProviderStreamFamilyHooks("openrouter-thinking");
|
|
1666
1776
|
export const TOOL_STREAM_DEFAULT_ON_HOOKS = buildProviderStreamFamilyHooks("tool-stream-default");
|
|
1667
1777
|
export const pluginSdkMock = true;
|
|
1778
|
+
${dynamicExportNames.length > 0 ? mockValueRuntimeSource() : ""}
|
|
1668
1779
|
${dynamicExportNames.map(genericExportStatement).join("\n")}
|
|
1669
1780
|
|
|
1670
1781
|
export default {
|
|
1671
1782
|
${[...exportNames].map((name) => ` ${name},`).join("\n")}
|
|
1672
1783
|
};
|
|
1784
|
+
`;
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
function mockValueRuntimeSource() {
|
|
1788
|
+
return `function createMockValue(name) {
|
|
1789
|
+
function fn(...args) {
|
|
1790
|
+
if (name === "resolvePreferredOpenClawTmpDir") {
|
|
1791
|
+
return process.env.TMPDIR || "/tmp";
|
|
1792
|
+
}
|
|
1793
|
+
if (name.startsWith("normalize")) {
|
|
1794
|
+
return typeof args[0] === "string" ? args[0] : "";
|
|
1795
|
+
}
|
|
1796
|
+
if (name === "jsonResult") {
|
|
1797
|
+
return { type: "json", value: args[0] };
|
|
1798
|
+
}
|
|
1799
|
+
if (name === "readStringParam") {
|
|
1800
|
+
return typeof args[0] === "string" ? args[0] : "";
|
|
1801
|
+
}
|
|
1802
|
+
return createMockValue(name);
|
|
1803
|
+
}
|
|
1804
|
+
return new Proxy(fn, {
|
|
1805
|
+
get(_target, property) {
|
|
1806
|
+
if (property === "then") {
|
|
1807
|
+
return undefined;
|
|
1808
|
+
}
|
|
1809
|
+
if (property === Symbol.toPrimitive) {
|
|
1810
|
+
return () => name;
|
|
1811
|
+
}
|
|
1812
|
+
if (property === "toString") {
|
|
1813
|
+
return () => name;
|
|
1814
|
+
}
|
|
1815
|
+
if (property === "valueOf") {
|
|
1816
|
+
return () => name;
|
|
1817
|
+
}
|
|
1818
|
+
return createMockValue(\`\${name}.\${String(property)}\`);
|
|
1819
|
+
},
|
|
1820
|
+
construct() {
|
|
1821
|
+
return createMockValue(name);
|
|
1822
|
+
},
|
|
1823
|
+
});
|
|
1824
|
+
}
|
|
1673
1825
|
`;
|
|
1674
1826
|
}
|
|
1675
1827
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { rmSync } from "node:fs";
|
|
2
|
+
import { mkdtemp } from "node:fs/promises";
|
|
3
|
+
import { register } from "node:module";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { pathToFileURL } from "node:url";
|
|
7
|
+
import { captureEntrypoint } from "./inspector.js";
|
|
8
|
+
import { createMockSdkPackage } from "./sdk-mock.js";
|
|
9
|
+
import { runCapturedSyntheticProbes } from "./synthetic-probes.js";
|
|
10
|
+
|
|
11
|
+
export async function runEntrypointSyntheticProbes(entrypoint, options = {}) {
|
|
12
|
+
const capture = await captureEntrypointForSyntheticProbes(entrypoint, {
|
|
13
|
+
...options,
|
|
14
|
+
apiOptions: {
|
|
15
|
+
...(options.apiOptions ?? {}),
|
|
16
|
+
retainHandlers: true,
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
return runCapturedSyntheticProbes(capture, options);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function captureEntrypointForSyntheticProbes(entrypoint, options) {
|
|
23
|
+
if (options.mockSdk !== true) {
|
|
24
|
+
return captureEntrypoint(entrypoint, options);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const cwd = options.cwd ?? process.cwd();
|
|
28
|
+
const resolvedEntrypoint = path.resolve(cwd, entrypoint);
|
|
29
|
+
const pluginRoot = path.resolve(cwd, options.pluginRoot ?? path.dirname(resolvedEntrypoint));
|
|
30
|
+
const workspace = await mkdtemp(path.join(os.tmpdir(), "plugin-inspector-synthetic-mock-sdk-"));
|
|
31
|
+
cleanupTempDirOnExit(workspace);
|
|
32
|
+
const { loaderPath } = await createMockSdkPackage(workspace, { pluginRoot });
|
|
33
|
+
register(pathToFileURL(loaderPath));
|
|
34
|
+
|
|
35
|
+
return captureEntrypoint(entrypoint, {
|
|
36
|
+
...options,
|
|
37
|
+
cwd,
|
|
38
|
+
mockSdk: false,
|
|
39
|
+
pluginRoot,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function cleanupTempDirOnExit(dir) {
|
|
44
|
+
process.once("exit", () => {
|
|
45
|
+
rmSync(dir, { force: true, recursive: true });
|
|
46
|
+
});
|
|
47
|
+
}
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { mkdtemp } from "node:fs/promises";
|
|
4
|
-
import { register } from "node:module";
|
|
5
|
-
import os from "node:os";
|
|
6
|
-
import path from "node:path";
|
|
7
|
-
import { pathToFileURL } from "node:url";
|
|
8
|
-
import { captureEntrypoint, runCapturedSyntheticProbes, writeArtifacts } from "./advanced.js";
|
|
9
|
-
import { createMockSdkPackage } from "./sdk-mock.js";
|
|
2
|
+
import { runEntrypointSyntheticProbes, writeArtifacts } from "./advanced.js";
|
|
10
3
|
|
|
11
4
|
const args = process.argv.slice(2);
|
|
12
5
|
|
|
@@ -33,12 +26,10 @@ async function run(commandArgs) {
|
|
|
33
26
|
throw new Error("synthetic probes import plugin code; rerun with PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1 in an isolated workspace");
|
|
34
27
|
}
|
|
35
28
|
|
|
36
|
-
const
|
|
29
|
+
const results = await runEntrypointSyntheticProbes(entrypoint, {
|
|
37
30
|
mockSdk,
|
|
38
31
|
pluginRoot,
|
|
39
32
|
apiOptions: { retainHandlers: true },
|
|
40
|
-
});
|
|
41
|
-
const results = await runCapturedSyntheticProbes(capture, {
|
|
42
33
|
includeLifecycle,
|
|
43
34
|
includeChannelRuntime,
|
|
44
35
|
includeProviderCapabilities,
|
|
@@ -52,30 +43,6 @@ async function run(commandArgs) {
|
|
|
52
43
|
}
|
|
53
44
|
}
|
|
54
45
|
|
|
55
|
-
async function captureForSyntheticProbes(entrypoint, options) {
|
|
56
|
-
if (options.mockSdk !== true) {
|
|
57
|
-
return captureEntrypoint(entrypoint, options);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const resolvedEntrypoint = path.resolve(process.cwd(), entrypoint);
|
|
61
|
-
const pluginRoot = path.resolve(process.cwd(), options.pluginRoot ?? path.dirname(resolvedEntrypoint));
|
|
62
|
-
const workspace = await mkdtemp(path.join(os.tmpdir(), "plugin-inspector-synthetic-mock-sdk-"));
|
|
63
|
-
cleanupTempDirOnExit(workspace);
|
|
64
|
-
const { loaderPath } = await createMockSdkPackage(workspace, { pluginRoot });
|
|
65
|
-
register(pathToFileURL(loaderPath));
|
|
66
|
-
return captureEntrypoint(entrypoint, {
|
|
67
|
-
...options,
|
|
68
|
-
mockSdk: false,
|
|
69
|
-
pluginRoot,
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function cleanupTempDirOnExit(dir) {
|
|
74
|
-
process.once("exit", () => {
|
|
75
|
-
rmSync(dir, { force: true, recursive: true });
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
|
|
79
46
|
function readFlag(commandArgs, name) {
|
|
80
47
|
const index = commandArgs.indexOf(name);
|
|
81
48
|
if (index === -1) {
|
package/src/synthetic-probes.js
CHANGED
|
@@ -89,6 +89,11 @@ export const syntheticRegistrationExecutionProfiles = {
|
|
|
89
89
|
callableProperties: [],
|
|
90
90
|
reason: "detached task runtimes are captured as registration metadata before async task execution",
|
|
91
91
|
},
|
|
92
|
+
registerEmbeddingProvider: {
|
|
93
|
+
mode: "metadata-only",
|
|
94
|
+
callableProperties: [],
|
|
95
|
+
reason: "embedding providers are captured as registration metadata before provider runtime execution",
|
|
96
|
+
},
|
|
92
97
|
registerGatewayDiscoveryService: {
|
|
93
98
|
mode: "metadata-only",
|
|
94
99
|
callableProperties: [],
|
|
@@ -116,11 +121,21 @@ export const syntheticRegistrationExecutionProfiles = {
|
|
|
116
121
|
callableProperties: [],
|
|
117
122
|
reason: "image generation providers are captured as registration metadata before provider runtime execution",
|
|
118
123
|
},
|
|
124
|
+
registerHostedMediaResolver: {
|
|
125
|
+
mode: "metadata-only",
|
|
126
|
+
callableProperties: [],
|
|
127
|
+
reason: "hosted media resolvers are captured as registration metadata before media URL resolution",
|
|
128
|
+
},
|
|
119
129
|
registerMemoryPromptSection: {
|
|
120
130
|
mode: "metadata-only",
|
|
121
131
|
callableProperties: [],
|
|
122
132
|
reason: "memory prompt section renderers are captured as metadata before prompt-runtime execution",
|
|
123
133
|
},
|
|
134
|
+
registerMeetingNotesSourceProvider: {
|
|
135
|
+
mode: "metadata-only",
|
|
136
|
+
callableProperties: [],
|
|
137
|
+
reason: "meeting notes source providers are captured as registration metadata before source discovery",
|
|
138
|
+
},
|
|
124
139
|
registerMediaUnderstandingProvider: {
|
|
125
140
|
mode: "metadata-only",
|
|
126
141
|
callableProperties: [],
|
|
@@ -161,11 +176,21 @@ export const syntheticRegistrationExecutionProfiles = {
|
|
|
161
176
|
callableProperties: [],
|
|
162
177
|
reason: "migration providers are captured as registration metadata before migration runtime execution",
|
|
163
178
|
},
|
|
179
|
+
registerModelCatalogProvider: {
|
|
180
|
+
mode: "metadata-only",
|
|
181
|
+
callableProperties: [],
|
|
182
|
+
reason: "model catalog providers are captured as registration metadata before catalog runtime execution",
|
|
183
|
+
},
|
|
164
184
|
registerMusicGenerationProvider: {
|
|
165
185
|
mode: "metadata-only",
|
|
166
186
|
callableProperties: [],
|
|
167
187
|
reason: "music generation providers are captured as registration metadata before provider runtime execution",
|
|
168
188
|
},
|
|
189
|
+
registerNodeCliFeature: {
|
|
190
|
+
mode: "metadata-only",
|
|
191
|
+
callableProperties: [],
|
|
192
|
+
reason: "node CLI features are captured as registration metadata before host CLI integration",
|
|
193
|
+
},
|
|
169
194
|
registerNodeHostCommand: {
|
|
170
195
|
mode: "metadata-only",
|
|
171
196
|
callableProperties: [],
|
|
@@ -206,6 +231,11 @@ export const syntheticRegistrationExecutionProfiles = {
|
|
|
206
231
|
callableProperties: [],
|
|
207
232
|
reason: "security audit collectors are captured as registration metadata before filesystem or policy scans",
|
|
208
233
|
},
|
|
234
|
+
registerSessionAction: {
|
|
235
|
+
mode: "metadata-only",
|
|
236
|
+
callableProperties: [],
|
|
237
|
+
reason: "session actions are captured as registration metadata before session runtime execution",
|
|
238
|
+
},
|
|
209
239
|
registerService: {
|
|
210
240
|
mode: "lifecycle-opt-in",
|
|
211
241
|
callableProperties: ["start", "stop", "dispose"],
|
|
@@ -267,12 +297,17 @@ export const defaultSyntheticHookEvents = {
|
|
|
267
297
|
runId: "run-fixture",
|
|
268
298
|
agentId: "agent-fixture",
|
|
269
299
|
conversationId: "conversation-fixture",
|
|
300
|
+
success: true,
|
|
301
|
+
durationMs: 1,
|
|
302
|
+
error: null,
|
|
303
|
+
messages: [{ role: "assistant", content: "[redacted fixture output]" }],
|
|
270
304
|
status: "completed",
|
|
271
305
|
transcript: [{ role: "assistant", content: "[redacted fixture output]" }],
|
|
272
306
|
},
|
|
273
307
|
before_agent_start: {
|
|
274
308
|
agentId: "agent-fixture",
|
|
275
309
|
runId: "run-fixture",
|
|
310
|
+
prompt: "fixture prompt",
|
|
276
311
|
config: { source: "plugin-inspector" },
|
|
277
312
|
},
|
|
278
313
|
before_prompt_build: {
|
|
@@ -303,6 +338,18 @@ export const defaultSyntheticHookEvents = {
|
|
|
303
338
|
model: "gpt-5.4",
|
|
304
339
|
output: { role: "assistant", content: "[redacted fixture output]" },
|
|
305
340
|
},
|
|
341
|
+
message_received: {
|
|
342
|
+
from: "fixture-user",
|
|
343
|
+
content: "fixture inbound message",
|
|
344
|
+
messageId: "message-fixture",
|
|
345
|
+
},
|
|
346
|
+
message_sent: {
|
|
347
|
+
to: "fixture-user",
|
|
348
|
+
content: "fixture outbound message",
|
|
349
|
+
success: true,
|
|
350
|
+
error: null,
|
|
351
|
+
messageId: "message-fixture-reply",
|
|
352
|
+
},
|
|
306
353
|
subagent_delivery_target: {
|
|
307
354
|
childSessionKey: "child-session",
|
|
308
355
|
agentId: "agent-child",
|
|
@@ -361,6 +408,18 @@ export const defaultSyntheticHookContexts = {
|
|
|
361
408
|
agentId: "agent-fixture",
|
|
362
409
|
sessionId: "session-fixture",
|
|
363
410
|
},
|
|
411
|
+
message_received: {
|
|
412
|
+
runId: "run-fixture",
|
|
413
|
+
agentId: "agent-fixture",
|
|
414
|
+
sessionId: "session-fixture",
|
|
415
|
+
channelId: "fixture-channel",
|
|
416
|
+
},
|
|
417
|
+
message_sent: {
|
|
418
|
+
runId: "run-fixture",
|
|
419
|
+
agentId: "agent-fixture",
|
|
420
|
+
sessionId: "session-fixture",
|
|
421
|
+
channelId: "fixture-channel",
|
|
422
|
+
},
|
|
364
423
|
subagent_delivery_target: {
|
|
365
424
|
runId: "run-fixture",
|
|
366
425
|
parentAgentId: "agent-parent",
|