@twsxtd/hapi-openclaw 0.1.6 → 0.1.8
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/index.js +55 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -251,6 +251,8 @@ function stripReplyToCurrentPrefix(text) {
|
|
|
251
251
|
// src/openclawAdapter.ts
|
|
252
252
|
var CONVERSATION_TITLE = "OpenClaw";
|
|
253
253
|
var RUN_COMPLETION_SETTLE_MS = 50;
|
|
254
|
+
var DEFAULT_PROVIDER = "openai";
|
|
255
|
+
var DEFAULT_MODEL = "gpt-5.4";
|
|
254
256
|
|
|
255
257
|
class ConversationBusyError extends Error {
|
|
256
258
|
constructor() {
|
|
@@ -275,6 +277,42 @@ function getStateNamespace(sessionKey, fallbackNamespace) {
|
|
|
275
277
|
function delay(ms) {
|
|
276
278
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
277
279
|
}
|
|
280
|
+
function readPrimaryModelRef(value) {
|
|
281
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
282
|
+
return value.trim();
|
|
283
|
+
}
|
|
284
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
285
|
+
const primary = value.primary;
|
|
286
|
+
return typeof primary === "string" && primary.trim().length > 0 ? primary.trim() : null;
|
|
287
|
+
}
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
function resolvePreferredModelRef(config, agentId) {
|
|
291
|
+
const agents = typeof config.agents === "object" && config.agents !== null ? config.agents : null;
|
|
292
|
+
const list = Array.isArray(agents?.list) ? agents.list : [];
|
|
293
|
+
const matchedAgent = list.find((entry) => {
|
|
294
|
+
return typeof entry === "object" && entry !== null && entry.id === agentId;
|
|
295
|
+
});
|
|
296
|
+
const defaults = typeof agents?.defaults === "object" && agents.defaults !== null ? agents.defaults : null;
|
|
297
|
+
const rawRef = readPrimaryModelRef(matchedAgent?.model) ?? readPrimaryModelRef(defaults?.model);
|
|
298
|
+
if (!rawRef) {
|
|
299
|
+
return {
|
|
300
|
+
provider: DEFAULT_PROVIDER,
|
|
301
|
+
model: DEFAULT_MODEL
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
const separatorIndex = rawRef.indexOf("/");
|
|
305
|
+
if (separatorIndex <= 0 || separatorIndex === rawRef.length - 1) {
|
|
306
|
+
return {
|
|
307
|
+
provider: DEFAULT_PROVIDER,
|
|
308
|
+
model: rawRef
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
return {
|
|
312
|
+
provider: rawRef.slice(0, separatorIndex).trim() || DEFAULT_PROVIDER,
|
|
313
|
+
model: rawRef.slice(separatorIndex + 1).trim() || DEFAULT_MODEL
|
|
314
|
+
};
|
|
315
|
+
}
|
|
278
316
|
async function ensureSessionBinding(runtime, sessionKey, agentId) {
|
|
279
317
|
const storePath = runtime.agent.session.resolveStorePath(undefined, { agentId });
|
|
280
318
|
const store = runtime.agent.session.loadSessionStore(storePath);
|
|
@@ -302,11 +340,13 @@ class RealOpenClawAdapter {
|
|
|
302
340
|
namespace;
|
|
303
341
|
runtime;
|
|
304
342
|
callbackClient;
|
|
343
|
+
logger;
|
|
305
344
|
supportsApprovals = false;
|
|
306
|
-
constructor(namespace, runtime, callbackClient) {
|
|
345
|
+
constructor(namespace, runtime, callbackClient, logger) {
|
|
307
346
|
this.namespace = namespace;
|
|
308
347
|
this.runtime = runtime;
|
|
309
348
|
this.callbackClient = callbackClient;
|
|
349
|
+
this.logger = logger;
|
|
310
350
|
}
|
|
311
351
|
async ensureDefaultConversation(externalUserKey) {
|
|
312
352
|
return {
|
|
@@ -322,6 +362,7 @@ class RealOpenClawAdapter {
|
|
|
322
362
|
throw new ConversationBusyError;
|
|
323
363
|
}
|
|
324
364
|
const namespace = getStateNamespace(action.conversationId, this.namespace);
|
|
365
|
+
this.logger.info(`[${namespace}] hapi-openclaw send-message start conversation=${action.conversationId}`);
|
|
325
366
|
await this.callbackClient.postEvent(createStateEvent({
|
|
326
367
|
namespace,
|
|
327
368
|
conversationId: action.conversationId,
|
|
@@ -335,7 +376,9 @@ class RealOpenClawAdapter {
|
|
|
335
376
|
dir: this.runtime.agent.resolveAgentWorkspaceDir(config, agentId)
|
|
336
377
|
})).dir;
|
|
337
378
|
const agentDir = this.runtime.agent.resolveAgentDir(config, agentId);
|
|
379
|
+
const modelRef = resolvePreferredModelRef(config, agentId);
|
|
338
380
|
const { sessionId, sessionFile } = await ensureSessionBinding(this.runtime, action.conversationId, agentId);
|
|
381
|
+
this.logger.info(`[${namespace}] hapi-openclaw runEmbeddedPiAgent sessionId=${sessionId} agentId=${agentId} ` + `provider=${modelRef.provider} model=${modelRef.model}`);
|
|
339
382
|
const result = await this.runtime.agent.runEmbeddedPiAgent({
|
|
340
383
|
sessionId,
|
|
341
384
|
sessionKey: action.conversationId,
|
|
@@ -345,12 +388,15 @@ class RealOpenClawAdapter {
|
|
|
345
388
|
config,
|
|
346
389
|
agentId,
|
|
347
390
|
prompt: action.text,
|
|
391
|
+
provider: modelRef.provider,
|
|
392
|
+
model: modelRef.model,
|
|
348
393
|
timeoutMs: this.runtime.agent.resolveAgentTimeoutMs({ cfg: config }),
|
|
349
394
|
runId: randomUUID(),
|
|
350
395
|
trigger: "user"
|
|
351
396
|
});
|
|
352
397
|
const runError = result.meta.error?.message?.trim() || null;
|
|
353
398
|
if (runError) {
|
|
399
|
+
this.logger.warn(`[${namespace}] hapi-openclaw run failed conversation=${action.conversationId}: ${runError}`);
|
|
354
400
|
if (adapterState.finishRun(action.conversationId)) {
|
|
355
401
|
await this.callbackClient.postEvent(createStateEvent({
|
|
356
402
|
namespace,
|
|
@@ -361,6 +407,7 @@ class RealOpenClawAdapter {
|
|
|
361
407
|
}
|
|
362
408
|
return;
|
|
363
409
|
}
|
|
410
|
+
this.logger.info(`[${namespace}] hapi-openclaw run completed conversation=${action.conversationId}` + (result.meta.finalAssistantVisibleText ? ` finalText=${JSON.stringify(result.meta.finalAssistantVisibleText)}` : ""));
|
|
364
411
|
if (result.meta.finalAssistantVisibleText) {
|
|
365
412
|
await delay(RUN_COMPLETION_SETTLE_MS);
|
|
366
413
|
}
|
|
@@ -374,6 +421,7 @@ class RealOpenClawAdapter {
|
|
|
374
421
|
}
|
|
375
422
|
} catch (error2) {
|
|
376
423
|
const message = error2 instanceof Error ? error2.message : "OpenClaw embedded run failed";
|
|
424
|
+
this.logger.error(`[${namespace}] hapi-openclaw send-message error conversation=${action.conversationId}: ${message}`);
|
|
377
425
|
if (adapterState.finishRun(action.conversationId)) {
|
|
378
426
|
await this.callbackClient.postEvent(createStateEvent({
|
|
379
427
|
namespace,
|
|
@@ -2205,6 +2253,7 @@ function createPluginApp(deps) {
|
|
|
2205
2253
|
retryAfterMs: null
|
|
2206
2254
|
};
|
|
2207
2255
|
deps.idempotencyCache.set(idempotencyKey, ack);
|
|
2256
|
+
deps.logger.info(`[${deps.namespace}] hapi-openclaw accepted send-message conversation=${body.conversationId} localMessageId=${body.localMessageId}`);
|
|
2208
2257
|
queueMicrotask(() => {
|
|
2209
2258
|
deps.runtime.sendMessage({
|
|
2210
2259
|
kind: "send-message",
|
|
@@ -2215,8 +2264,10 @@ function createPluginApp(deps) {
|
|
|
2215
2264
|
await dispatchMaybeEvents(deps.callbackClient, events);
|
|
2216
2265
|
}).catch((error2) => {
|
|
2217
2266
|
if (error2 instanceof ConversationBusyError) {
|
|
2267
|
+
deps.logger.warn(`[${deps.namespace}] hapi-openclaw conversation busy conversation=${body.conversationId}`);
|
|
2218
2268
|
return;
|
|
2219
2269
|
}
|
|
2270
|
+
deps.logger.error(`[${deps.namespace}] hapi-openclaw send-message task failed conversation=${body.conversationId}: ` + (error2 instanceof Error ? error2.message : String(error2)));
|
|
2220
2271
|
});
|
|
2221
2272
|
});
|
|
2222
2273
|
return c.json(ack);
|
|
@@ -2311,7 +2362,7 @@ function resolveRegisteredPluginConfig(api) {
|
|
|
2311
2362
|
function registerPluginRoutes(api) {
|
|
2312
2363
|
const config = resolveRegisteredPluginConfig(api);
|
|
2313
2364
|
const callbackClient = new HapiCallbackClient(config.hapiBaseUrl, config.sharedSecret);
|
|
2314
|
-
const runtime = new RealOpenClawAdapter(config.namespace, api.runtime, callbackClient);
|
|
2365
|
+
const runtime = new RealOpenClawAdapter(config.namespace, api.runtime, callbackClient, api.logger);
|
|
2315
2366
|
const app = createPluginApp({
|
|
2316
2367
|
sharedSecret: config.sharedSecret,
|
|
2317
2368
|
namespace: config.namespace,
|
|
@@ -2319,7 +2370,8 @@ function registerPluginRoutes(api) {
|
|
|
2319
2370
|
runtime,
|
|
2320
2371
|
idempotencyCache: new Map,
|
|
2321
2372
|
prototypeCaptureSessionKey: config.prototypeCaptureSessionKey,
|
|
2322
|
-
prototypeCaptureFileName: config.prototypeCaptureFileName
|
|
2373
|
+
prototypeCaptureFileName: config.prototypeCaptureFileName,
|
|
2374
|
+
logger: api.logger
|
|
2323
2375
|
});
|
|
2324
2376
|
api.registerHttpRoute({
|
|
2325
2377
|
path: "/hapi",
|