Merge pull request #16 from openclaw/codex/capture-binding-resolved

[codex] fix runtime capture binding callbacks
This commit is contained in:
Patrick Erichsen 2026-04-28 02:17:08 -07:00 committed by GitHub
commit 768c3fc4d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 73 additions and 0 deletions

View File

@ -82,6 +82,24 @@ export function createCaptureApi(options = {}) {
}
return api;
},
onConversationBindingResolved(handler) {
const captureIndex =
captured.push({
kind: "hook",
name: "onConversationBindingResolved",
handlerType: typeof handler,
arguments: summarizeArguments([handler]),
}) - 1;
if (retainHandlers) {
retained.push({
kind: "hook",
name: "onConversationBindingResolved",
handler,
captureIndex,
});
}
return api;
},
},
{
get(target, property) {

View File

@ -50,6 +50,16 @@ test("capture API returns useful channel, gateway, and lifecycle descriptors", (
assert.equal(typeof service.dispose, "function");
});
test("capture API records conversation binding resolved callbacks", () => {
const api = createCaptureApi();
assert.equal(api.onConversationBindingResolved(() => undefined), api);
assert.deepEqual(
api.getCapturedContracts().map((entry) => `${entry.kind}:${entry.name}`),
["hook:onConversationBindingResolved"],
);
});
test("capture API accepts custom registrar return profiles", () => {
const api = createCaptureApi({
registrarProfiles: {

View File

@ -61,6 +61,51 @@ test("runtime capture report imports plugin entrypoints with mocked SDK", async
assert.match(await readFile(path.join(outDir, "capture.md"), "utf8"), /registerTool/);
});
test("runtime capture records conversation binding resolved callbacks", async () => {
const rootDir = await mkdtemp(path.join(os.tmpdir(), "plugin-inspector-runtime-binding-resolved-"));
await mkdir(path.join(rootDir, "src"), { recursive: true });
await writeFile(
path.join(rootDir, "package.json"),
`${JSON.stringify(
{
name: "openclaw-binding-resolved",
version: "1.0.0",
type: "module",
openclaw: {
extensions: ["src/index.mjs"],
compat: { pluginApi: "^1.0.0" },
},
},
null,
2,
)}\n`,
"utf8",
);
await writeFile(
path.join(rootDir, "src", "index.mjs"),
[
'import { definePluginEntry } from "openclaw/plugin-sdk";',
"",
"export default definePluginEntry((api) => {",
" api.onConversationBindingResolved(() => undefined);",
"});",
].join("\n"),
"utf8",
);
const config = await loadPluginRootConfig(null, { cwd: rootDir });
const compatibilityReport = await inspectCompatibilityFixtureSet(config, { openclawPath: false });
const captureReport = await buildRuntimeCaptureReport({ report: compatibilityReport, rootDir });
assert.equal(captureReport.summary.failedCount, 0);
assert.equal(captureReport.summary.capturedCount, 1);
assert.equal(captureReport.summary.hookCount, 1);
assert.deepEqual(
captureReport.results[0].captured.map((entry) => `${entry.kind}:${entry.name}`),
["hook:onConversationBindingResolved"],
);
});
test("runtime capture report classifies missing mocked SDK exports", async () => {
const rootDir = await mkdtemp(path.join(os.tmpdir(), "plugin-inspector-runtime-capture-missing-export-"));
await mkdir(path.join(rootDir, "src"), { recursive: true });