@openclaw/acpx 2026.9.1-beta.1 → 2026.9.2
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-v8M2tNu6.js +185 -0
- package/dist/doctor-contract-api.js +15 -2
- package/dist/index.js +6 -3
- package/dist/{pi-session-catalog-runtime-BIu-8uRZ.js → pi-session-catalog-runtime-C0HodUWT.js} +42 -38
- package/dist/{register.runtime-Dj29TKFy.js → register.runtime-Ba7FPMGu.js} +3 -2
- package/dist/register.runtime.js +1 -1
- package/dist/rolldown-runtime-8H4AJuhK.js +14 -0
- package/dist/{runtime-BmOxa15I.js → runtime-memQfUBo.js} +137 -75
- package/dist/{service-PRlUtXMf.js → service-COMUTA5A.js} +347 -6
- package/dist/session-owner-migration-CistlQKM.js +200 -0
- package/dist/session-resource-UWe7qD3m.js +17 -0
- package/openclaw.plugin.json +12 -0
- package/package.json +5 -5
- package/skills/acp-router/SKILL.md +1 -1
- package/dist/process-reaper-DduWm_7N.js +0 -511
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { t as AcpxPluginConfigSchema } from "./config-schema-DN_uAi4R.js";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { formatPluginConfigIssue } from "openclaw/plugin-sdk/extension-shared";
|
|
8
|
+
//#region extensions/acpx/src/config.ts
|
|
9
|
+
/**
|
|
10
|
+
* Resolves ACPX plugin config from raw user configuration. It locates the
|
|
11
|
+
* plugin root, injects optional MCP bridge servers, and applies runtime defaults.
|
|
12
|
+
*/
|
|
13
|
+
const ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME = "openclaw-plugin-tools";
|
|
14
|
+
const ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME = "openclaw-tools";
|
|
15
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
16
|
+
function isAcpxPluginRoot(dir) {
|
|
17
|
+
return fs.existsSync(path.join(dir, "openclaw.plugin.json")) && fs.existsSync(path.join(dir, "package.json"));
|
|
18
|
+
}
|
|
19
|
+
function resolveNearestAcpxPluginRoot(moduleUrl) {
|
|
20
|
+
let cursor = path.dirname(fileURLToPath(moduleUrl));
|
|
21
|
+
for (let i = 0; i < 3; i += 1) {
|
|
22
|
+
if (isAcpxPluginRoot(cursor)) return cursor;
|
|
23
|
+
const parent = path.dirname(cursor);
|
|
24
|
+
if (parent === cursor) break;
|
|
25
|
+
cursor = parent;
|
|
26
|
+
}
|
|
27
|
+
return path.resolve(path.dirname(fileURLToPath(moduleUrl)), "..");
|
|
28
|
+
}
|
|
29
|
+
function resolveWorkspaceAcpxPluginRoot(currentRoot) {
|
|
30
|
+
if (path.basename(currentRoot) !== "acpx" || path.basename(path.dirname(currentRoot)) !== "extensions" || path.basename(path.dirname(path.dirname(currentRoot))) !== "dist") return null;
|
|
31
|
+
const workspaceRoot = path.resolve(currentRoot, "..", "..", "..", "extensions", "acpx");
|
|
32
|
+
return isAcpxPluginRoot(workspaceRoot) ? workspaceRoot : null;
|
|
33
|
+
}
|
|
34
|
+
function resolveRepoAcpxPluginRoot(currentRoot) {
|
|
35
|
+
const workspaceRoot = path.join(currentRoot, "extensions", "acpx");
|
|
36
|
+
return isAcpxPluginRoot(workspaceRoot) ? workspaceRoot : null;
|
|
37
|
+
}
|
|
38
|
+
function resolveAcpxPluginRootFromOpenClawLayout(moduleUrl) {
|
|
39
|
+
let cursor = path.dirname(fileURLToPath(moduleUrl));
|
|
40
|
+
for (let i = 0; i < 5; i += 1) {
|
|
41
|
+
const candidates = [
|
|
42
|
+
path.join(cursor, "extensions", "acpx"),
|
|
43
|
+
path.join(cursor, "dist", "extensions", "acpx"),
|
|
44
|
+
path.join(cursor, "dist-runtime", "extensions", "acpx")
|
|
45
|
+
];
|
|
46
|
+
for (const candidate of candidates) if (isAcpxPluginRoot(candidate)) return candidate;
|
|
47
|
+
const parent = path.dirname(cursor);
|
|
48
|
+
if (parent === cursor) break;
|
|
49
|
+
cursor = parent;
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
/** Resolve the ACPX plugin root across source, dist, and dist-runtime layouts. */
|
|
54
|
+
function resolveAcpxPluginRoot(moduleUrl = import.meta.url) {
|
|
55
|
+
const resolvedRoot = resolveNearestAcpxPluginRoot(moduleUrl);
|
|
56
|
+
return resolveWorkspaceAcpxPluginRoot(resolvedRoot) ?? resolveRepoAcpxPluginRoot(resolvedRoot) ?? resolveAcpxPluginRootFromOpenClawLayout(moduleUrl) ?? resolvedRoot;
|
|
57
|
+
}
|
|
58
|
+
const DEFAULT_PERMISSION_MODE = "approve-reads";
|
|
59
|
+
const DEFAULT_NON_INTERACTIVE_POLICY = "fail";
|
|
60
|
+
function parseAcpxPluginConfig(value) {
|
|
61
|
+
if (value === void 0) return {
|
|
62
|
+
ok: true,
|
|
63
|
+
value: void 0
|
|
64
|
+
};
|
|
65
|
+
const parsed = AcpxPluginConfigSchema.safeParse(value);
|
|
66
|
+
if (!parsed.success) return {
|
|
67
|
+
ok: false,
|
|
68
|
+
message: formatPluginConfigIssue(parsed.error.issues[0])
|
|
69
|
+
};
|
|
70
|
+
return {
|
|
71
|
+
ok: true,
|
|
72
|
+
value: parsed.data
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function resolveOpenClawRoot(currentRoot) {
|
|
76
|
+
if (path.basename(currentRoot) === "acpx" && path.basename(path.dirname(currentRoot)) === "extensions") {
|
|
77
|
+
const parent = path.dirname(path.dirname(currentRoot));
|
|
78
|
+
if (path.basename(parent) === "dist") return path.dirname(parent);
|
|
79
|
+
return parent;
|
|
80
|
+
}
|
|
81
|
+
return path.resolve(currentRoot, "..");
|
|
82
|
+
}
|
|
83
|
+
function resolveTsxImportSpecifier() {
|
|
84
|
+
try {
|
|
85
|
+
return requireFromHere.resolve("tsx");
|
|
86
|
+
} catch {
|
|
87
|
+
return "tsx";
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function shellQuoteCommandArg(arg) {
|
|
91
|
+
if (!/[\s'"\\$|&;<>{}()*?[\]~`]/.test(arg)) return arg;
|
|
92
|
+
return `'${arg.replace(/'/g, "'\"'\"'")}'`;
|
|
93
|
+
}
|
|
94
|
+
function resolvePluginToolsMcpServerConfig(moduleUrl = import.meta.url) {
|
|
95
|
+
const openClawRoot = resolveOpenClawRoot(resolveAcpxPluginRoot(moduleUrl));
|
|
96
|
+
const distEntry = path.join(openClawRoot, "dist", "mcp", "plugin-tools-serve.js");
|
|
97
|
+
if (fs.existsSync(distEntry)) return {
|
|
98
|
+
command: process.execPath,
|
|
99
|
+
args: [distEntry]
|
|
100
|
+
};
|
|
101
|
+
const sourceEntry = path.join(openClawRoot, "src", "mcp", "plugin-tools-serve.ts");
|
|
102
|
+
return {
|
|
103
|
+
command: process.execPath,
|
|
104
|
+
args: [
|
|
105
|
+
"--import",
|
|
106
|
+
resolveTsxImportSpecifier(),
|
|
107
|
+
sourceEntry
|
|
108
|
+
]
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function resolveOpenClawToolsMcpServerConfig(moduleUrl = import.meta.url) {
|
|
112
|
+
const openClawRoot = resolveOpenClawRoot(resolveAcpxPluginRoot(moduleUrl));
|
|
113
|
+
const distEntry = path.join(openClawRoot, "dist", "mcp", "openclaw-tools-serve.js");
|
|
114
|
+
if (fs.existsSync(distEntry)) return {
|
|
115
|
+
command: process.execPath,
|
|
116
|
+
args: [distEntry]
|
|
117
|
+
};
|
|
118
|
+
const sourceEntry = path.join(openClawRoot, "src", "mcp", "openclaw-tools-serve.ts");
|
|
119
|
+
return {
|
|
120
|
+
command: process.execPath,
|
|
121
|
+
args: [
|
|
122
|
+
"--import",
|
|
123
|
+
resolveTsxImportSpecifier(),
|
|
124
|
+
sourceEntry
|
|
125
|
+
]
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function resolveConfiguredMcpServers(params) {
|
|
129
|
+
const resolved = { ...params.mcpServers };
|
|
130
|
+
if (params.pluginToolsMcpBridge && resolved[ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME]) throw new Error(`mcpServers.${ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME} is reserved when pluginToolsMcpBridge=true`);
|
|
131
|
+
if (params.openClawToolsMcpBridge && resolved[ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME]) throw new Error(`mcpServers.${ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME} is reserved when openClawToolsMcpBridge=true`);
|
|
132
|
+
if (params.pluginToolsMcpBridge) resolved[ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME] = resolvePluginToolsMcpServerConfig(params.moduleUrl);
|
|
133
|
+
if (params.openClawToolsMcpBridge) resolved[ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME] = resolveOpenClawToolsMcpServerConfig(params.moduleUrl);
|
|
134
|
+
return resolved;
|
|
135
|
+
}
|
|
136
|
+
/** Convert OpenClaw MCP server config into ACPX runtime MCP server entries. */
|
|
137
|
+
function toAcpMcpServers(mcpServers) {
|
|
138
|
+
return Object.entries(mcpServers).map(([name, server]) => ({
|
|
139
|
+
name,
|
|
140
|
+
command: server.command,
|
|
141
|
+
args: [...server.args ?? []],
|
|
142
|
+
env: Object.entries(server.env ?? {}).map(([envName, value]) => ({
|
|
143
|
+
name: envName,
|
|
144
|
+
value
|
|
145
|
+
}))
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
/** Validate and normalize raw ACPX plugin config for runtime startup. */
|
|
149
|
+
function resolveAcpxPluginConfig(params) {
|
|
150
|
+
const parsed = parseAcpxPluginConfig(params.rawConfig);
|
|
151
|
+
if (!parsed.ok) throw new Error(parsed.message);
|
|
152
|
+
const normalized = parsed.value ?? {};
|
|
153
|
+
const workspaceDir = params.workspaceDir?.trim() || process.cwd();
|
|
154
|
+
const fallbackCwd = workspaceDir;
|
|
155
|
+
const cwd = path.resolve(normalized.cwd?.trim() || fallbackCwd);
|
|
156
|
+
const stateDir = path.resolve(normalized.stateDir?.trim() || path.join(workspaceDir, "state"));
|
|
157
|
+
const pluginToolsMcpBridge = normalized.pluginToolsMcpBridge === true;
|
|
158
|
+
const openClawToolsMcpBridge = normalized.openClawToolsMcpBridge === true;
|
|
159
|
+
const mcpServers = resolveConfiguredMcpServers({
|
|
160
|
+
mcpServers: normalized.mcpServers,
|
|
161
|
+
pluginToolsMcpBridge,
|
|
162
|
+
openClawToolsMcpBridge,
|
|
163
|
+
moduleUrl: params.moduleUrl
|
|
164
|
+
});
|
|
165
|
+
const agents = Object.fromEntries(Object.entries(normalized.agents ?? {}).map(([name, entry]) => {
|
|
166
|
+
const cmd = entry.command.trim();
|
|
167
|
+
const cmdArgs = entry.args ?? [];
|
|
168
|
+
const fullCommand = cmdArgs.length > 0 ? `${cmd} ${cmdArgs.map(shellQuoteCommandArg).join(" ")}` : cmd;
|
|
169
|
+
return [normalizeLowercaseStringOrEmpty(name), fullCommand];
|
|
170
|
+
}));
|
|
171
|
+
return {
|
|
172
|
+
cwd,
|
|
173
|
+
stateDir,
|
|
174
|
+
probeAgent: normalized.probeAgent,
|
|
175
|
+
permissionMode: normalized.permissionMode ?? DEFAULT_PERMISSION_MODE,
|
|
176
|
+
nonInteractivePermissions: normalized.nonInteractivePermissions ?? DEFAULT_NON_INTERACTIVE_POLICY,
|
|
177
|
+
pluginToolsMcpBridge,
|
|
178
|
+
openClawToolsMcpBridge,
|
|
179
|
+
timeoutSeconds: normalized.timeoutSeconds ?? 120,
|
|
180
|
+
mcpServers,
|
|
181
|
+
agents
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
//#endregion
|
|
185
|
+
export { resolveAcpxPluginRoot as n, toAcpMcpServers as r, resolveAcpxPluginConfig as t };
|
|
@@ -17,14 +17,16 @@ const legacyConfigRules = RETIRED_ACPX_CONFIG_KEYS.map((key) => ({
|
|
|
17
17
|
}));
|
|
18
18
|
/** Removes retired plugin-owned config without keeping runtime compatibility keys. */
|
|
19
19
|
function normalizeCompatibilityConfig({ cfg }) {
|
|
20
|
-
const
|
|
20
|
+
const entry = asObjectRecord(cfg.plugins?.entries?.acpx);
|
|
21
|
+
const pluginConfig = asObjectRecord(entry?.config);
|
|
21
22
|
const retiredKeys = RETIRED_ACPX_CONFIG_KEYS.filter((key) => Object.hasOwn(pluginConfig ?? {}, key));
|
|
22
23
|
if (!pluginConfig || retiredKeys.length === 0) return {
|
|
23
24
|
config: cfg,
|
|
24
25
|
changes: []
|
|
25
26
|
};
|
|
26
27
|
const nextConfig = structuredClone(cfg);
|
|
27
|
-
const
|
|
28
|
+
const nextEntry = asObjectRecord(nextConfig.plugins?.entries?.acpx);
|
|
29
|
+
const nextPluginConfig = asObjectRecord(nextEntry?.config);
|
|
28
30
|
if (!nextPluginConfig) return {
|
|
29
31
|
config: cfg,
|
|
30
32
|
changes: []
|
|
@@ -129,6 +131,17 @@ const stateMigrations = [{
|
|
|
129
131
|
warnings
|
|
130
132
|
};
|
|
131
133
|
}
|
|
134
|
+
}, {
|
|
135
|
+
id: "acpx-session-owner-resources",
|
|
136
|
+
label: "ACP session owners",
|
|
137
|
+
doctorOnly: true,
|
|
138
|
+
phase: "after-session-repair",
|
|
139
|
+
async detectLegacyState(input) {
|
|
140
|
+
return (await import("./session-owner-migration-CistlQKM.js")).acpxSessionOwnerMigration.detectLegacyState(input);
|
|
141
|
+
},
|
|
142
|
+
async migrateLegacyState(input) {
|
|
143
|
+
return (await import("./session-owner-migration-CistlQKM.js")).acpxSessionOwnerMigration.migrateLegacyState(input);
|
|
144
|
+
}
|
|
132
145
|
}];
|
|
133
146
|
//#endregion
|
|
134
147
|
export { legacyConfigRules, normalizeCompatibilityConfig, stateMigrations };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as createAcpxRuntimeService } from "./register.runtime-
|
|
1
|
+
import { t as createAcpxRuntimeService } from "./register.runtime-Ba7FPMGu.js";
|
|
2
2
|
import "./config-schema-DN_uAi4R.js";
|
|
3
3
|
import { a as PI_SESSIONS_CAPABILITY, c as PI_SESSION_READ_COMMAND, l as PI_TERMINAL_RESUME_COMMAND, o as PI_SESSIONS_LIST_COMMAND, r as piSessionStoreAvailable, s as PI_SESSION_ID_PATTERN } from "./pi-session-paths-EMbd4Hkz.js";
|
|
4
4
|
import { tryDispatchAcpReplyHook } from "openclaw/plugin-sdk/acp-runtime-backend";
|
|
@@ -8,7 +8,7 @@ import { resolveNodeHostExecutable } from "openclaw/plugin-sdk/node-host";
|
|
|
8
8
|
import { createSessionCatalogNodeHostBindings } from "openclaw/plugin-sdk/session-catalog";
|
|
9
9
|
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
10
10
|
//#region extensions/acpx/src/pi-session-catalog-plugin.ts
|
|
11
|
-
const loadPiSessionCatalogModule = createLazyRuntimeModule(() => import("./pi-session-catalog-runtime-
|
|
11
|
+
const loadPiSessionCatalogModule = createLazyRuntimeModule(() => import("./pi-session-catalog-runtime-C0HodUWT.js"));
|
|
12
12
|
function fullConfigCatalogEnabled(config) {
|
|
13
13
|
if (!isRecord(config) || !isRecord(config.plugins) || !isRecord(config.plugins.entries)) return true;
|
|
14
14
|
const entry = config.plugins.entries.acpx;
|
|
@@ -105,7 +105,10 @@ const plugin = {
|
|
|
105
105
|
pluginConfig: api.pluginConfig,
|
|
106
106
|
openKeyedStore: (options) => api.runtime.state.openKeyedStore(options)
|
|
107
107
|
}));
|
|
108
|
-
api.on("reply_dispatch", (event, ctx) => tryDispatchAcpReplyHookWithTimeout(event, ctx, replyDispatchTimeoutMs), {
|
|
108
|
+
api.on("reply_dispatch", (event, ctx) => tryDispatchAcpReplyHookWithTimeout(event, ctx, replyDispatchTimeoutMs), {
|
|
109
|
+
timeoutMs: replyDispatchTimeoutMs,
|
|
110
|
+
eligibleDispatchKinds: ["acp"]
|
|
111
|
+
});
|
|
109
112
|
}
|
|
110
113
|
};
|
|
111
114
|
//#endregion
|
package/dist/{pi-session-catalog-runtime-BIu-8uRZ.js → pi-session-catalog-runtime-C0HodUWT.js}
RENAMED
|
@@ -8,8 +8,9 @@ import path from "node:path";
|
|
|
8
8
|
import fs$1 from "node:fs/promises";
|
|
9
9
|
import process from "node:process";
|
|
10
10
|
import { resolveAcpSessionAvailability } from "openclaw/plugin-sdk/acp-runtime";
|
|
11
|
-
import {
|
|
11
|
+
import { resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
|
|
12
12
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
13
|
+
import { runTasksWithConcurrency } from "openclaw/plugin-sdk/concurrency-runtime";
|
|
13
14
|
import { isPathStrictlyInside } from "openclaw/plugin-sdk/file-access-runtime";
|
|
14
15
|
//#region extensions/acpx/src/pi-session-timestamp.ts
|
|
15
16
|
/** Preserve Pi JSONL's date-first string contract while accepting numeric millisecond values. */
|
|
@@ -21,9 +22,9 @@ function parsePiSessionTimestampMs(value) {
|
|
|
21
22
|
const MAX_DISCOVERY_FILES = 1e4;
|
|
22
23
|
const SUMMARY_SCAN_BATCH_SIZE = 100;
|
|
23
24
|
const MAX_SUMMARY_CACHE_ENTRIES = 256;
|
|
24
|
-
const MAX_SESSION_BYTES =
|
|
25
|
-
const MAX_SUMMARY_LINE_BYTES =
|
|
26
|
-
const APPEND_PROOF_EDGE_BYTES =
|
|
25
|
+
const MAX_SESSION_BYTES = 33554432;
|
|
26
|
+
const MAX_SUMMARY_LINE_BYTES = 1048576;
|
|
27
|
+
const APPEND_PROOF_EDGE_BYTES = 65536;
|
|
27
28
|
const IO_CONCURRENCY = 8;
|
|
28
29
|
const PI_FILE_CANDIDATE_CACHE_TTL_MS = 32e3;
|
|
29
30
|
const PI_FILE_CANDIDATE_CACHE_MAX_ENTRIES = 8;
|
|
@@ -95,38 +96,30 @@ async function realpathOrResolve(value) {
|
|
|
95
96
|
return path.resolve(value);
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
|
-
async function mapConcurrent(values, limit, mapper) {
|
|
99
|
-
const results = [];
|
|
100
|
-
results.length = values.length;
|
|
101
|
-
let nextIndex = 0;
|
|
102
|
-
const workers = Array.from({ length: Math.min(limit, values.length) }, async () => {
|
|
103
|
-
while (nextIndex < values.length) {
|
|
104
|
-
const index = nextIndex++;
|
|
105
|
-
results[index] = await mapper(values[index]);
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
await Promise.all(workers);
|
|
109
|
-
return results;
|
|
110
|
-
}
|
|
111
99
|
async function scanPiFileCandidates(env) {
|
|
112
100
|
const { root, files } = await discoverPiSessionFiles(env);
|
|
113
101
|
const configuredAcpRoot = piAcpSessionStoreRoot(env);
|
|
114
102
|
const acpRoot = configuredAcpRoot ? await realpathOrResolve(configuredAcpRoot) : void 0;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
103
|
+
const { results: candidates } = await runTasksWithConcurrency({
|
|
104
|
+
tasks: files.map((file) => async () => {
|
|
105
|
+
try {
|
|
106
|
+
const stats = await fs$1.stat(file);
|
|
107
|
+
return stats.isFile() ? {
|
|
108
|
+
file,
|
|
109
|
+
storeRoot: root,
|
|
110
|
+
identity: `${String(stats.dev)}:${String(stats.ino)}:${String(stats.birthtimeMs)}`,
|
|
111
|
+
mtimeMs: stats.mtimeMs,
|
|
112
|
+
size: stats.size,
|
|
113
|
+
resumable: acpRoot ? isPathStrictlyInside(acpRoot, file) : false
|
|
114
|
+
} : void 0;
|
|
115
|
+
} catch {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
}),
|
|
119
|
+
limit: IO_CONCURRENCY,
|
|
120
|
+
throwOnError: true
|
|
121
|
+
});
|
|
122
|
+
return candidates.filter((candidate) => candidate !== void 0).toSorted((left, right) => right.mtimeMs - left.mtimeMs);
|
|
130
123
|
}
|
|
131
124
|
async function piFileCandidates(env) {
|
|
132
125
|
const store = piSessionStore(env);
|
|
@@ -323,7 +316,12 @@ async function listPiSummaryPage(env, params) {
|
|
|
323
316
|
const matches = [];
|
|
324
317
|
const needle = params.searchTerm?.toLocaleLowerCase();
|
|
325
318
|
for (let index = 0; index < candidates.length && matches.length < target; index += SUMMARY_SCAN_BATCH_SIZE) {
|
|
326
|
-
const
|
|
319
|
+
const batch = candidates.slice(index, index + SUMMARY_SCAN_BATCH_SIZE);
|
|
320
|
+
const { results: summaries } = await runTasksWithConcurrency({
|
|
321
|
+
tasks: batch.map((candidate) => () => readPiSessionSummary(candidate)),
|
|
322
|
+
limit: IO_CONCURRENCY,
|
|
323
|
+
throwOnError: true
|
|
324
|
+
});
|
|
327
325
|
for (const summary of summaries) if (summary && summaryMatches(summary, needle)) {
|
|
328
326
|
matches.push(summary);
|
|
329
327
|
if (matches.length >= target) break;
|
|
@@ -337,7 +335,12 @@ async function listPiSummaryPage(env, params) {
|
|
|
337
335
|
async function findPiSummary(threadId, env) {
|
|
338
336
|
const candidates = await piFileCandidates(env);
|
|
339
337
|
for (let index = 0; index < candidates.length; index += SUMMARY_SCAN_BATCH_SIZE) {
|
|
340
|
-
const
|
|
338
|
+
const { results: summaries } = await runTasksWithConcurrency({
|
|
339
|
+
tasks: candidates.slice(index, index + SUMMARY_SCAN_BATCH_SIZE).map((candidate) => () => readPiSessionSummary(candidate)),
|
|
340
|
+
limit: IO_CONCURRENCY,
|
|
341
|
+
throwOnError: true
|
|
342
|
+
});
|
|
343
|
+
const match = summaries.find((summary) => summary?.threadId === threadId);
|
|
341
344
|
if (match) return match;
|
|
342
345
|
}
|
|
343
346
|
}
|
|
@@ -582,7 +585,7 @@ async function readLocalPiTranscriptPage(value) {
|
|
|
582
585
|
}
|
|
583
586
|
//#endregion
|
|
584
587
|
//#region extensions/acpx/src/pi-session-upstream-activity.ts
|
|
585
|
-
const MAX_PI_UPSTREAM_SCAN_BYTES =
|
|
588
|
+
const MAX_PI_UPSTREAM_SCAN_BYTES = 1048576;
|
|
586
589
|
async function readFileRange(handle, position, length) {
|
|
587
590
|
const buffer = Buffer.alloc(length);
|
|
588
591
|
let offset = 0;
|
|
@@ -669,7 +672,8 @@ async function checkPiSessionUpstreamActivity(probe) {
|
|
|
669
672
|
let occurredAt;
|
|
670
673
|
for (const entry of entries) {
|
|
671
674
|
if (entry.type !== "message" || !isRecord(entry.message) || entry.message.role !== "user") continue;
|
|
672
|
-
|
|
675
|
+
const text = textFromContent(entry.message.content);
|
|
676
|
+
if (!isExternalUserText(probe, text)) continue;
|
|
673
677
|
humanTurns += 1;
|
|
674
678
|
occurredAt = Math.max(occurredAt ?? 0, parsePiSessionTimestampMs(entry.message.timestamp) ?? parsePiSessionTimestampMs(entry.timestamp) ?? stat.mtimeMs);
|
|
675
679
|
}
|
|
@@ -754,7 +758,7 @@ async function createAdoptedPiSession(params) {
|
|
|
754
758
|
key: sessionCatalogAdoptedSessionKey(PI_ADOPTED_SESSION_KEY_PREFIX, params.threadId),
|
|
755
759
|
agentId: params.agentId,
|
|
756
760
|
recoverMatchingInitialEntry: true,
|
|
757
|
-
...params.session.name ? {
|
|
761
|
+
...params.session.name ? { displayName: params.session.name } : {},
|
|
758
762
|
...params.session.cwd ? { spawnedCwd: params.session.cwd } : {},
|
|
759
763
|
initialEntry: {
|
|
760
764
|
acpBackendId: ACPX_BACKEND_ID,
|
|
@@ -856,7 +860,7 @@ function createPiSessionCatalogRuntime(api) {
|
|
|
856
860
|
sessionUnavailable: "Pi session is unavailable"
|
|
857
861
|
},
|
|
858
862
|
continuation: {
|
|
859
|
-
resolveAgentId: (agentId) =>
|
|
863
|
+
resolveAgentId: (agentId) => resolveSessionAgentIdsStrict({
|
|
860
864
|
config: api.config,
|
|
861
865
|
agentId
|
|
862
866
|
}).sessionAgentId,
|
|
@@ -24,6 +24,7 @@ function lazyStartRuntimeTurn(resolveRuntime, input) {
|
|
|
24
24
|
/** Create an ACP runtime facade backed by an async runtime resolver. */
|
|
25
25
|
function createLazyAcpRuntimeProxy(resolveRuntime) {
|
|
26
26
|
return {
|
|
27
|
+
ownerAwareSessions: 1,
|
|
27
28
|
async ensureSession(input) {
|
|
28
29
|
return await (await resolveRuntime()).ensureSession(input);
|
|
29
30
|
},
|
|
@@ -43,7 +44,7 @@ function createLazyAcpRuntimeProxy(resolveRuntime) {
|
|
|
43
44
|
await (await resolveRuntime()).setMode(input);
|
|
44
45
|
},
|
|
45
46
|
async setConfigOption(input) {
|
|
46
|
-
await (await resolveRuntime()).setConfigOption(input);
|
|
47
|
+
return await (await resolveRuntime()).setConfigOption(input);
|
|
47
48
|
},
|
|
48
49
|
async doctor() {
|
|
49
50
|
return await (await resolveRuntime()).doctor();
|
|
@@ -66,7 +67,7 @@ function createLazyAcpRuntimeProxy(resolveRuntime) {
|
|
|
66
67
|
* immediately, then imports the heavier service only when a session needs it.
|
|
67
68
|
*/
|
|
68
69
|
const ACPX_BACKEND_ID = "acpx";
|
|
69
|
-
const loadServiceModule = createLazyRuntimeModule(() => import("./service-
|
|
70
|
+
const loadServiceModule = createLazyRuntimeModule(() => import("./service-COMUTA5A.js").then((n) => n.t));
|
|
70
71
|
function unregisterOwnedRuntime(runtime) {
|
|
71
72
|
if (runtime && getAcpRuntimeBackend(ACPX_BACKEND_ID)?.runtime === runtime) unregisterAcpRuntimeBackend(ACPX_BACKEND_ID);
|
|
72
73
|
}
|
package/dist/register.runtime.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createAcpxRuntimeService } from "./register.runtime-
|
|
1
|
+
import { t as createAcpxRuntimeService } from "./register.runtime-Ba7FPMGu.js";
|
|
2
2
|
export { createAcpxRuntimeService };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __exportAll = (all, no_symbols) => {
|
|
5
|
+
let target = {};
|
|
6
|
+
for (var name in all) __defProp(target, name, {
|
|
7
|
+
get: all[name],
|
|
8
|
+
enumerable: true
|
|
9
|
+
});
|
|
10
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
11
|
+
return target;
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { __exportAll as t };
|