Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1247,7 +1247,8 @@ class JsEngine(private val context: Context) {
targetContextKey: String,
targetRuntime: String,
channel: String,
payloadJson: String
payloadJson: String,
timeoutSec: Long = JsTimeoutConfig.TOOLPKG_IPC_TIMEOUT_SECONDS
): String {
val normalizedTarget = packageTarget.trim()
if (normalizedTarget.isEmpty()) {
Expand Down Expand Up @@ -1410,7 +1411,11 @@ class JsEngine(private val context: Context) {
"__operit_toolpkg_ipc_payload_json" to payloadJson.trim().ifEmpty { "null" },
"__operit_toolpkg_ipc_caller_context_key" to callerContextKey.trim()
),
timeoutSec = 15L
timeoutSec = if (timeoutSec <= 0L) {
JsTimeoutConfig.TOOLPKG_IPC_TIMEOUT_SECONDS
} else {
timeoutSec
}
)
val errorMessage = extractJsExecutionErrorMessage(result)
if (errorMessage != null) {
Expand Down Expand Up @@ -1687,6 +1692,29 @@ class JsEngine(private val context: Context) {
targetRuntime: String,
channel: String,
payloadJson: String
) {
invokeToolPkgIpcAsync(
callbackId = callbackId,
packageTarget = packageTarget,
callerContextKey = callerContextKey,
targetContextKey = targetContextKey,
targetRuntime = targetRuntime,
channel = channel,
payloadJson = payloadJson,
timeoutSec = JsTimeoutConfig.TOOLPKG_IPC_TIMEOUT_SECONDS
)
}

@JavascriptInterface
fun invokeToolPkgIpcAsync(
callbackId: String,
packageTarget: String,
callerContextKey: String,
targetContextKey: String,
targetRuntime: String,
channel: String,
payloadJson: String,
timeoutSec: Long
) {
val normalizedCallback = callbackId.trim()
if (normalizedCallback.isEmpty()) {
Expand All @@ -1701,7 +1729,8 @@ class JsEngine(private val context: Context) {
targetContextKey = targetContextKey,
targetRuntime = targetRuntime,
channel = channel,
payloadJson = payloadJson
payloadJson = payloadJson,
timeoutSec = timeoutSec
)
sendToolPkgIpcResult(normalizedCallback, resultJson, false)
} catch (error: Throwable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,10 @@ internal fun buildExecutionRuntimeBridgeScript(): String {
return Promise.reject(new Error('ToolPkg.ipc channel is required'));
}
var callOptions = options && typeof options === 'object' ? options : {};
var timeoutSec = null;
if (callOptions.timeoutMs !== undefined && callOptions.timeoutMs !== null && callOptions.timeoutMs !== '') {
timeoutSec = Math.max(1, Math.ceil((Number(callOptions.timeoutMs) || 0) / 1000));
}
var targetRuntime = text(callOptions.targetRuntime || '').trim().toLowerCase();
if (
targetRuntime &&
Expand Down Expand Up @@ -980,15 +984,28 @@ internal fun buildExecutionRuntimeBridgeScript(): String {
);
};
try {
NativeInterface.invokeToolPkgIpcAsync(
callbackId,
packageTarget,
currentContextKey,
targetContextKey,
targetRuntime,
normalizedChannel,
payloadJson
);
if (timeoutSec !== null) {
NativeInterface.invokeToolPkgIpcAsync(
callbackId,
packageTarget,
currentContextKey,
targetContextKey,
targetRuntime,
normalizedChannel,
payloadJson,
timeoutSec
);
} else {
NativeInterface.invokeToolPkgIpcAsync(
callbackId,
packageTarget,
currentContextKey,
targetContextKey,
targetRuntime,
normalizedChannel,
payloadJson
);
}
} catch (error) {
try {
delete root[callbackId];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ internal object JsTimeoutConfig {
const val PRE_TIMEOUT_LEAD_SECONDS = 5L
const val SCRIPT_TIMEOUT_MS = MAIN_TIMEOUT_SECONDS * 1000L
const val TOOL_CALL_TIMEOUT_MS = SCRIPT_TIMEOUT_MS
const val TOOLPKG_IPC_TIMEOUT_SECONDS = 15L
}
7 changes: 6 additions & 1 deletion examples/qqbot/dist/shared/qqbot_auto_reply.js
Original file line number Diff line number Diff line change
Expand Up @@ -1044,7 +1044,12 @@ async function onQQBotAutoReplyApplicationCreate() {
});
}
await stopAutoReplyLoopInternal("manual_stop");
await (0, qqbot_service_1.stopQQBotServiceInternalAsync)(8000);
try {
await (0, qqbot_service_1.stopQQBotServiceInternalAsync)(8000);
}
catch (stopError) {
console.error(`[qqbot_auto_reply] stop leftover gateway on create failed: ${(0, qqbot_common_1.safeErrorMessage)(stopError)}`);
}
}
else {
await (0, qqbot_service_1.ensureQQBotServiceStarted)({
Expand Down
5 changes: 3 additions & 2 deletions examples/qqbot/dist/shared/qqbot_common.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ENV_KEYS = exports.DEFAULT_GATEWAY_INTENTS = exports.SANDBOX_API_BASE_URL = exports.API_BASE_URL = exports.TOKEN_URL = exports.LOCAL_SERVICE_PORT = exports.TERMINAL_SESSION_NAME = exports.TERMINAL_SERVICE_OUTPUT_FILE_NAME = exports.TERMINAL_SERVICE_RESOURCE_KEY = exports.LOG_FILE_NAME = exports.CONFIG_FILE_NAME = exports.QQBOT_TOOLPKG_ID = exports.SERVICE_POLL_INTERVAL_MS = exports.MAX_RECEIVE_LIMIT = exports.DEFAULT_RECEIVE_LIMIT = exports.DEFAULT_SERVICE_WAIT_MS = exports.DEFAULT_TIMEOUT_MS = exports.PACKAGE_VERSION = void 0;
exports.ENV_KEYS = exports.DEFAULT_GATEWAY_INTENTS = exports.SANDBOX_API_BASE_URL = exports.API_BASE_URL = exports.TOKEN_URL = exports.LOCAL_SERVICE_PORT = exports.TERMINAL_SESSION_NAME = exports.TERMINAL_SERVICE_OUTPUT_FILE_NAME = exports.TERMINAL_SERVICE_RESOURCE_KEY = exports.LOG_FILE_NAME = exports.CONFIG_FILE_NAME = exports.QQBOT_TOOLPKG_ID = exports.SERVICE_POLL_INTERVAL_MS = exports.MAX_RECEIVE_LIMIT = exports.DEFAULT_RECEIVE_LIMIT = exports.LISTENER_TOGGLE_IPC_TIMEOUT_MS = exports.DEFAULT_SERVICE_WAIT_MS = exports.DEFAULT_TIMEOUT_MS = exports.PACKAGE_VERSION = void 0;
exports.asText = asText;
exports.hasOwn = hasOwn;
exports.isObject = isObject;
Expand All @@ -17,9 +17,10 @@ exports.toHttpTimeoutSeconds = toHttpTimeoutSeconds;
exports.maskSecret = maskSecret;
exports.shellQuote = shellQuote;
exports.createControlToken = createControlToken;
exports.PACKAGE_VERSION = "0.3.0";
exports.PACKAGE_VERSION = "0.3.1";
exports.DEFAULT_TIMEOUT_MS = 20000;
exports.DEFAULT_SERVICE_WAIT_MS = 8000;
exports.LISTENER_TOGGLE_IPC_TIMEOUT_MS = 45000;
exports.DEFAULT_RECEIVE_LIMIT = 20;
exports.MAX_RECEIVE_LIMIT = 100;
exports.SERVICE_POLL_INTERVAL_MS = 200;
Expand Down
9 changes: 5 additions & 4 deletions examples/qqbot/dist/shared/qqbot_ipc.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,15 @@ function registerQQBotContextRunner() {
registerQQBotContextRunner();
registerQQBotContextModule(QQBotRuntime);
registerQQBotContextModule(QQBotAutoReply);
async function runWithContext(kind, envs, runner) {
async function runWithContext(kind, envs, runner, timeoutMs) {
const payload = {
functionSource: runner.toString(),
envs
};
try {
return await ToolPkg.ipc.call(QQBOT_CONTEXT_RUN_IPC_CHANNEL, payload, {
targetRuntime: kind
targetRuntime: kind,
...(timeoutMs != null ? { timeoutMs } : {})
});
}
catch (error) {
Expand All @@ -145,11 +146,11 @@ async function runWithContext(kind, envs, runner) {
throw error;
}
}
function withContext(kind, envs, runner) {
function withContext(kind, envs, runner, timeoutMs) {
if (!runner) {
throw new Error("withContext requires runner");
}
return runWithContext(kind, envs, runner);
return runWithContext(kind, envs, runner, timeoutMs);
}
__exportStar(require("./qqbot_runtime"), exports);
__exportStar(require("./qqbot_auto_reply"), exports);
57 changes: 44 additions & 13 deletions examples/qqbot/dist/shared/qqbot_runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,27 @@ async function qqbot_service_start(params = {}) {
await (0, qqbot_state_1.updatePersistedConfigAsync)({
listenerEnabled: true
});
return {
success: true,
packageVersion: qqbot_common_1.PACKAGE_VERSION,
...(await (0, qqbot_service_1.ensureQQBotServiceStarted)({
restart: (0, qqbot_common_1.parseOptionalBoolean)(params.restart, "restart") === true,
timeout_ms: (0, qqbot_common_1.parsePositiveInt)(params.timeout_ms, "timeout_ms", qqbot_common_1.DEFAULT_SERVICE_WAIT_MS),
source: "qqbot_service_start"
}))
};
try {
return {
success: true,
packageVersion: qqbot_common_1.PACKAGE_VERSION,
listenerEnabled: true,
...(await (0, qqbot_service_1.ensureQQBotServiceStarted)({
restart: (0, qqbot_common_1.parseOptionalBoolean)(params.restart, "restart") === true,
timeout_ms: (0, qqbot_common_1.parsePositiveInt)(params.timeout_ms, "timeout_ms", qqbot_common_1.DEFAULT_SERVICE_WAIT_MS),
source: "qqbot_service_start"
}))
};
}
catch (startError) {
return {
success: true,
packageVersion: qqbot_common_1.PACKAGE_VERSION,
listenerEnabled: true,
warning: (0, qqbot_common_1.safeErrorMessage)(startError),
service: await (0, qqbot_service_1.buildServiceStatusAsync)()
};
}
}
catch (error) {
return {
Expand All @@ -208,12 +220,31 @@ async function qqbot_service_stop(params = {}) {
await (0, qqbot_state_1.updatePersistedConfigAsync)({
listenerEnabled: false
});
await (0, qqbot_auto_reply_1.qqbot_auto_reply_configure)({
enabled: false
});
const result = await (0, qqbot_service_1.stopQQBotServiceInternalAsync)(timeoutMs);
try {
await (0, qqbot_auto_reply_1.qqbot_auto_reply_configure)({
enabled: false
});
}
catch (autoReplyError) {
console.error(`[qqbot_runtime] disable auto-reply after listener stop failed: ${(0, qqbot_common_1.safeErrorMessage)(autoReplyError)}`);
}
let result;
try {
result = await (0, qqbot_service_1.stopQQBotServiceInternalAsync)(timeoutMs);
}
catch (stopError) {
console.error(`[qqbot_runtime] stop gateway after listener disable failed: ${(0, qqbot_common_1.safeErrorMessage)(stopError)}`);
return {
success: true,
packageVersion: qqbot_common_1.PACKAGE_VERSION,
listenerEnabled: false,
warning: (0, qqbot_common_1.safeErrorMessage)(stopError),
service: await (0, qqbot_service_1.buildServiceStatusAsync)()
};
}
return {
...result,
listenerEnabled: false,
service: await (0, qqbot_service_1.buildServiceStatusAsync)()
};
}
Expand Down
Loading