@maudecode/openclaw-cowtail 0.9.1 → 0.11.0
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 +284 -16
- package/dist/setup-entry.js +284 -16
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13728,6 +13728,7 @@ var openclawEventTypes = [
|
|
|
13728
13728
|
"thread_created",
|
|
13729
13729
|
"thread_updated",
|
|
13730
13730
|
"message_created",
|
|
13731
|
+
"message_updated",
|
|
13731
13732
|
"message_acknowledged",
|
|
13732
13733
|
"reply_created",
|
|
13733
13734
|
"action_submitted",
|
|
@@ -13742,12 +13743,24 @@ var openclawTargetAgentSchema = exports_external.literal("default");
|
|
|
13742
13743
|
var openclawMessageDirectionSchema = exports_external.enum(["openclaw_to_user", "user_to_openclaw"]);
|
|
13743
13744
|
var openclawDeliveryStateSchema = exports_external.enum(["pending", "sent", "failed"]);
|
|
13744
13745
|
var openclawActionStateSchema = exports_external.enum(["pending", "submitted", "failed", "expired"]);
|
|
13746
|
+
var openclawToolCallStatusSchema = exports_external.enum(["pending", "running", "complete", "error"]);
|
|
13745
13747
|
var openclawEventTypeSchema = exports_external.enum(openclawEventTypes);
|
|
13746
13748
|
var openclawSequenceSchema = exports_external.number().int().nonnegative();
|
|
13747
13749
|
var openclawLinkSchema = exports_external.object({
|
|
13748
13750
|
label: nonEmptyStringSchema,
|
|
13749
13751
|
url: nonEmptyStringSchema
|
|
13750
13752
|
});
|
|
13753
|
+
var openclawToolCallRecordSchema = exports_external.object({
|
|
13754
|
+
id: nonEmptyStringSchema,
|
|
13755
|
+
name: nonEmptyStringSchema,
|
|
13756
|
+
args: jsonObjectSchema.optional(),
|
|
13757
|
+
result: exports_external.unknown().optional(),
|
|
13758
|
+
status: openclawToolCallStatusSchema,
|
|
13759
|
+
startedAt: timestampSchema.optional(),
|
|
13760
|
+
completedAt: timestampSchema.optional(),
|
|
13761
|
+
insertedAtContentLength: exports_external.number().int().nonnegative().optional(),
|
|
13762
|
+
contentSnapshotAtStart: exports_external.string().optional()
|
|
13763
|
+
});
|
|
13751
13764
|
var openclawPluginClientHelloSchema = exports_external.object({
|
|
13752
13765
|
protocolVersion: openclawProtocolVersionSchema,
|
|
13753
13766
|
clientKind: exports_external.literal("openclaw_plugin"),
|
|
@@ -13782,6 +13795,7 @@ var openclawMessageRecordSchema = exports_external.object({
|
|
|
13782
13795
|
authorLabel: nonEmptyStringSchema.optional(),
|
|
13783
13796
|
text: nonEmptyStringSchema,
|
|
13784
13797
|
links: exports_external.array(openclawLinkSchema).default([]),
|
|
13798
|
+
toolCalls: exports_external.array(openclawToolCallRecordSchema).default([]),
|
|
13785
13799
|
deliveryState: openclawDeliveryStateSchema,
|
|
13786
13800
|
createdAt: timestampSchema,
|
|
13787
13801
|
updatedAt: timestampSchema
|
|
@@ -13832,7 +13846,19 @@ var openclawPluginMessageCommandSchema = exports_external.object({
|
|
|
13832
13846
|
text: nonEmptyStringSchema,
|
|
13833
13847
|
authorLabel: nonEmptyStringSchema.optional(),
|
|
13834
13848
|
links: exports_external.array(openclawLinkSchema).default([]),
|
|
13835
|
-
|
|
13849
|
+
toolCalls: exports_external.array(openclawToolCallRecordSchema).default([]),
|
|
13850
|
+
actions: exports_external.array(openclawActionDraftSchema).default([]),
|
|
13851
|
+
deliveryState: openclawDeliveryStateSchema.optional()
|
|
13852
|
+
});
|
|
13853
|
+
var openclawPluginMessageUpdateCommandSchema = exports_external.object({
|
|
13854
|
+
type: exports_external.literal("openclaw_message_update"),
|
|
13855
|
+
requestId: openclawRequestIdSchema,
|
|
13856
|
+
messageId: nonEmptyStringSchema,
|
|
13857
|
+
text: nonEmptyStringSchema,
|
|
13858
|
+
links: exports_external.array(openclawLinkSchema).optional(),
|
|
13859
|
+
toolCalls: exports_external.array(openclawToolCallRecordSchema).optional(),
|
|
13860
|
+
actions: exports_external.array(openclawActionDraftSchema).optional(),
|
|
13861
|
+
deliveryState: openclawDeliveryStateSchema.optional()
|
|
13836
13862
|
});
|
|
13837
13863
|
var openclawIosNewThreadCommandSchema = exports_external.object({
|
|
13838
13864
|
type: exports_external.literal("ios_new_thread"),
|
|
@@ -13883,6 +13909,7 @@ var openclawActionResultCommandSchema = exports_external.object({
|
|
|
13883
13909
|
});
|
|
13884
13910
|
var openclawRealtimeClientMessageSchema = exports_external.discriminatedUnion("type", [
|
|
13885
13911
|
openclawPluginMessageCommandSchema,
|
|
13912
|
+
openclawPluginMessageUpdateCommandSchema,
|
|
13886
13913
|
openclawIosNewThreadCommandSchema,
|
|
13887
13914
|
openclawIosReplyCommandSchema,
|
|
13888
13915
|
openclawIosActionCommandSchema,
|
|
@@ -13895,7 +13922,8 @@ var openclawRealtimeClientMessageSchema = exports_external.discriminatedUnion("t
|
|
|
13895
13922
|
var openclawRealtimeAckSchema = exports_external.object({
|
|
13896
13923
|
type: exports_external.literal("ack"),
|
|
13897
13924
|
requestId: openclawRequestIdSchema,
|
|
13898
|
-
sequence: openclawSequenceSchema.optional()
|
|
13925
|
+
sequence: openclawSequenceSchema.optional(),
|
|
13926
|
+
payload: jsonObjectSchema.optional()
|
|
13899
13927
|
});
|
|
13900
13928
|
var openclawRealtimeErrorSchema = exports_external.object({
|
|
13901
13929
|
type: exports_external.literal("realtime_error"),
|
|
@@ -14129,9 +14157,19 @@ class CowtailRealtimeClient {
|
|
|
14129
14157
|
...command,
|
|
14130
14158
|
requestId: this.#requestIdFactory(),
|
|
14131
14159
|
links: command.links ?? [],
|
|
14160
|
+
toolCalls: command.toolCalls ?? [],
|
|
14132
14161
|
actions: command.actions ?? []
|
|
14133
14162
|
});
|
|
14134
14163
|
}
|
|
14164
|
+
sendOpenClawMessageUpdate(command) {
|
|
14165
|
+
return this.#sendCommand({
|
|
14166
|
+
...command,
|
|
14167
|
+
requestId: this.#requestIdFactory(),
|
|
14168
|
+
...command.links ? { links: command.links } : {},
|
|
14169
|
+
...command.toolCalls ? { toolCalls: command.toolCalls } : {},
|
|
14170
|
+
...command.actions ? { actions: command.actions } : {}
|
|
14171
|
+
});
|
|
14172
|
+
}
|
|
14135
14173
|
sendSessionBound(command) {
|
|
14136
14174
|
return this.#sendCommand({
|
|
14137
14175
|
...command,
|
|
@@ -14236,7 +14274,7 @@ class CowtailRealtimeClient {
|
|
|
14236
14274
|
}
|
|
14237
14275
|
const message = parsed.data;
|
|
14238
14276
|
if (message.type === "ack") {
|
|
14239
|
-
this.#resolvePendingRequest(message.requestId, message.sequence);
|
|
14277
|
+
this.#resolvePendingRequest(message.requestId, message.sequence, message.payload);
|
|
14240
14278
|
return;
|
|
14241
14279
|
}
|
|
14242
14280
|
if (message.type === "realtime_error") {
|
|
@@ -14319,13 +14357,17 @@ class CowtailRealtimeClient {
|
|
|
14319
14357
|
}
|
|
14320
14358
|
});
|
|
14321
14359
|
}
|
|
14322
|
-
#resolvePendingRequest(requestId, sequence) {
|
|
14360
|
+
#resolvePendingRequest(requestId, sequence, payload) {
|
|
14323
14361
|
const pending = this.#pendingRequests.get(requestId);
|
|
14324
14362
|
if (!pending) {
|
|
14325
14363
|
return;
|
|
14326
14364
|
}
|
|
14327
14365
|
this.#pendingRequests.delete(requestId);
|
|
14328
|
-
pending.resolve({
|
|
14366
|
+
pending.resolve({
|
|
14367
|
+
requestId,
|
|
14368
|
+
sequence,
|
|
14369
|
+
...payload ? { payload } : {}
|
|
14370
|
+
});
|
|
14329
14371
|
}
|
|
14330
14372
|
#rejectPendingRequest(message) {
|
|
14331
14373
|
if (!message.requestId) {
|
|
@@ -14399,7 +14441,8 @@ class CowtailRealtimeClient {
|
|
|
14399
14441
|
}
|
|
14400
14442
|
|
|
14401
14443
|
// src/inbound.ts
|
|
14402
|
-
import {
|
|
14444
|
+
import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";
|
|
14445
|
+
import { normalizeOutboundReplyPayload } from "openclaw/plugin-sdk/reply-payload";
|
|
14403
14446
|
|
|
14404
14447
|
// src/session-keys.ts
|
|
14405
14448
|
function normalizeCowtailTarget(raw) {
|
|
@@ -14548,19 +14591,24 @@ async function dispatchCowtailTextTurn(params) {
|
|
|
14548
14591
|
body,
|
|
14549
14592
|
timestamp: message.createdAt
|
|
14550
14593
|
});
|
|
14551
|
-
|
|
14594
|
+
const streamState = { text: "", toolCalls: [] };
|
|
14595
|
+
await recordCowtailInboundSessionAndDispatchReply({
|
|
14552
14596
|
cfg: runtime.config.loadConfig(),
|
|
14553
14597
|
channel: CHANNEL_ID,
|
|
14554
14598
|
accountId: account.accountId,
|
|
14599
|
+
agentId: route.agentId,
|
|
14555
14600
|
route,
|
|
14556
14601
|
storePath,
|
|
14557
14602
|
ctxPayload,
|
|
14558
|
-
|
|
14559
|
-
deliver: async (payload) => deliverCowtailReply({
|
|
14603
|
+
runtime,
|
|
14604
|
+
deliver: async (payload, info, rawPayload) => deliverCowtailReply({
|
|
14560
14605
|
client,
|
|
14561
14606
|
route,
|
|
14562
14607
|
thread,
|
|
14563
|
-
payload
|
|
14608
|
+
payload,
|
|
14609
|
+
rawPayload,
|
|
14610
|
+
info,
|
|
14611
|
+
streamState
|
|
14564
14612
|
}),
|
|
14565
14613
|
onRecordError: (error48) => {
|
|
14566
14614
|
logger?.error?.(`Cowtail inbound session record failed: ${errorMessage(error48)}`);
|
|
@@ -14595,19 +14643,24 @@ async function dispatchCowtailActionTurn(params) {
|
|
|
14595
14643
|
timestamp
|
|
14596
14644
|
});
|
|
14597
14645
|
let dispatchFailed = false;
|
|
14598
|
-
|
|
14646
|
+
const streamState = { text: "", toolCalls: [] };
|
|
14647
|
+
await recordCowtailInboundSessionAndDispatchReply({
|
|
14599
14648
|
cfg: runtime.config.loadConfig(),
|
|
14600
14649
|
channel: CHANNEL_ID,
|
|
14601
14650
|
accountId: account.accountId,
|
|
14651
|
+
agentId: route.agentId,
|
|
14602
14652
|
route,
|
|
14603
14653
|
storePath,
|
|
14604
14654
|
ctxPayload,
|
|
14605
|
-
|
|
14606
|
-
deliver: async (replyPayload) => deliverCowtailReply({
|
|
14655
|
+
runtime,
|
|
14656
|
+
deliver: async (replyPayload, info, rawPayload) => deliverCowtailReply({
|
|
14607
14657
|
client,
|
|
14608
14658
|
route,
|
|
14609
14659
|
thread,
|
|
14610
|
-
payload: replyPayload
|
|
14660
|
+
payload: replyPayload,
|
|
14661
|
+
rawPayload,
|
|
14662
|
+
info,
|
|
14663
|
+
streamState
|
|
14611
14664
|
}),
|
|
14612
14665
|
onRecordError: (error48) => {
|
|
14613
14666
|
logger?.error?.(`Cowtail inbound session record failed: ${errorMessage(error48)}`);
|
|
@@ -14619,21 +14672,141 @@ async function dispatchCowtailActionTurn(params) {
|
|
|
14619
14672
|
});
|
|
14620
14673
|
return !dispatchFailed;
|
|
14621
14674
|
}
|
|
14675
|
+
async function recordCowtailInboundSessionAndDispatchReply(params) {
|
|
14676
|
+
await params.runtime.channel.session.recordInboundSession({
|
|
14677
|
+
storePath: params.storePath,
|
|
14678
|
+
sessionKey: typeof params.ctxPayload.SessionKey === "string" ? params.ctxPayload.SessionKey : params.route.sessionKey,
|
|
14679
|
+
ctx: params.ctxPayload,
|
|
14680
|
+
onRecordError: params.onRecordError
|
|
14681
|
+
});
|
|
14682
|
+
const { onModelSelected, ...replyPipeline } = createChannelReplyPipeline({
|
|
14683
|
+
cfg: params.cfg,
|
|
14684
|
+
agentId: params.agentId,
|
|
14685
|
+
channel: params.channel,
|
|
14686
|
+
accountId: params.accountId
|
|
14687
|
+
});
|
|
14688
|
+
await params.runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
|
|
14689
|
+
ctx: params.ctxPayload,
|
|
14690
|
+
cfg: params.cfg,
|
|
14691
|
+
dispatcherOptions: {
|
|
14692
|
+
...replyPipeline,
|
|
14693
|
+
deliver: async (payload, info) => {
|
|
14694
|
+
try {
|
|
14695
|
+
await params.deliver(normalizeCowtailReplyPayload(payload), info, payload);
|
|
14696
|
+
} catch (error48) {
|
|
14697
|
+
params.onDispatchError(error48, { kind: info?.kind ?? "final" });
|
|
14698
|
+
}
|
|
14699
|
+
},
|
|
14700
|
+
onError: params.onDispatchError
|
|
14701
|
+
},
|
|
14702
|
+
replyOptions: {
|
|
14703
|
+
onModelSelected
|
|
14704
|
+
}
|
|
14705
|
+
});
|
|
14706
|
+
}
|
|
14622
14707
|
async function deliverCowtailReply(params) {
|
|
14708
|
+
if (params.streamState.failed) {
|
|
14709
|
+
return;
|
|
14710
|
+
}
|
|
14623
14711
|
const text = params.payload.text;
|
|
14712
|
+
const kind = params.info?.kind ?? "final";
|
|
14713
|
+
const links = resolveCowtailReplyLinks(params.payload);
|
|
14714
|
+
if (kind === "tool") {
|
|
14715
|
+
const { toolCall, summary } = buildCowtailToolCall({
|
|
14716
|
+
payload: params.payload,
|
|
14717
|
+
rawPayload: params.rawPayload,
|
|
14718
|
+
streamState: params.streamState
|
|
14719
|
+
});
|
|
14720
|
+
params.streamState.toolCalls = [...params.streamState.toolCalls, toolCall];
|
|
14721
|
+
const messageText = params.streamState.text || summary || "Tool activity";
|
|
14722
|
+
if (!params.streamState.messageId) {
|
|
14723
|
+
const result = await params.client.sendOpenClawMessage({
|
|
14724
|
+
type: "openclaw_message",
|
|
14725
|
+
sessionKey: params.thread.sessionKey ?? params.route.sessionKey,
|
|
14726
|
+
title: params.thread.title,
|
|
14727
|
+
text: messageText,
|
|
14728
|
+
authorLabel: "OpenClaw",
|
|
14729
|
+
links,
|
|
14730
|
+
toolCalls: params.streamState.toolCalls,
|
|
14731
|
+
actions: [],
|
|
14732
|
+
deliveryState: "pending"
|
|
14733
|
+
});
|
|
14734
|
+
params.streamState.messageId = recordCreatedOpenClawMessageId(params.streamState, result);
|
|
14735
|
+
return;
|
|
14736
|
+
}
|
|
14737
|
+
await params.client.sendOpenClawMessageUpdate({
|
|
14738
|
+
type: "openclaw_message_update",
|
|
14739
|
+
messageId: params.streamState.messageId,
|
|
14740
|
+
text: messageText,
|
|
14741
|
+
links,
|
|
14742
|
+
toolCalls: params.streamState.toolCalls,
|
|
14743
|
+
deliveryState: "pending"
|
|
14744
|
+
});
|
|
14745
|
+
return;
|
|
14746
|
+
}
|
|
14624
14747
|
if (typeof text !== "string" || !text.trim()) {
|
|
14625
14748
|
return;
|
|
14626
14749
|
}
|
|
14750
|
+
if (kind === "block") {
|
|
14751
|
+
params.streamState.text = appendReplyBlock(params.streamState.text, text);
|
|
14752
|
+
if (!params.streamState.messageId) {
|
|
14753
|
+
const result = await params.client.sendOpenClawMessage({
|
|
14754
|
+
type: "openclaw_message",
|
|
14755
|
+
sessionKey: params.thread.sessionKey ?? params.route.sessionKey,
|
|
14756
|
+
title: params.thread.title,
|
|
14757
|
+
text: params.streamState.text,
|
|
14758
|
+
authorLabel: "OpenClaw",
|
|
14759
|
+
links,
|
|
14760
|
+
toolCalls: params.streamState.toolCalls,
|
|
14761
|
+
actions: [],
|
|
14762
|
+
deliveryState: "pending"
|
|
14763
|
+
});
|
|
14764
|
+
params.streamState.messageId = recordCreatedOpenClawMessageId(params.streamState, result);
|
|
14765
|
+
return;
|
|
14766
|
+
}
|
|
14767
|
+
await params.client.sendOpenClawMessageUpdate({
|
|
14768
|
+
type: "openclaw_message_update",
|
|
14769
|
+
messageId: params.streamState.messageId,
|
|
14770
|
+
text: params.streamState.text,
|
|
14771
|
+
links,
|
|
14772
|
+
toolCalls: params.streamState.toolCalls,
|
|
14773
|
+
deliveryState: "pending"
|
|
14774
|
+
});
|
|
14775
|
+
return;
|
|
14776
|
+
}
|
|
14777
|
+
if (params.streamState.messageId) {
|
|
14778
|
+
params.streamState.text = text;
|
|
14779
|
+
await params.client.sendOpenClawMessageUpdate({
|
|
14780
|
+
type: "openclaw_message_update",
|
|
14781
|
+
messageId: params.streamState.messageId,
|
|
14782
|
+
text,
|
|
14783
|
+
links,
|
|
14784
|
+
toolCalls: params.streamState.toolCalls,
|
|
14785
|
+
actions: [],
|
|
14786
|
+
deliveryState: "sent"
|
|
14787
|
+
});
|
|
14788
|
+
return;
|
|
14789
|
+
}
|
|
14627
14790
|
await params.client.sendOpenClawMessage({
|
|
14628
14791
|
type: "openclaw_message",
|
|
14629
14792
|
sessionKey: params.thread.sessionKey ?? params.route.sessionKey,
|
|
14630
14793
|
title: params.thread.title,
|
|
14631
14794
|
text,
|
|
14632
14795
|
authorLabel: "OpenClaw",
|
|
14633
|
-
links
|
|
14634
|
-
|
|
14796
|
+
links,
|
|
14797
|
+
toolCalls: params.streamState.toolCalls,
|
|
14798
|
+
actions: [],
|
|
14799
|
+
deliveryState: "sent"
|
|
14635
14800
|
});
|
|
14636
14801
|
}
|
|
14802
|
+
function recordCreatedOpenClawMessageId(streamState, result) {
|
|
14803
|
+
const messageId = result.payload?.messageId;
|
|
14804
|
+
if (typeof messageId === "string" && messageId.trim()) {
|
|
14805
|
+
return messageId;
|
|
14806
|
+
}
|
|
14807
|
+
streamState.failed = true;
|
|
14808
|
+
throw new Error("Cowtail realtime ack missing messageId for streamed OpenClaw reply");
|
|
14809
|
+
}
|
|
14637
14810
|
function resolveCowtailReplyLinks(payload) {
|
|
14638
14811
|
const urls = [
|
|
14639
14812
|
...Array.isArray(payload.mediaUrls) ? payload.mediaUrls : [],
|
|
@@ -14644,6 +14817,101 @@ function resolveCowtailReplyLinks(payload) {
|
|
|
14644
14817
|
url: url2
|
|
14645
14818
|
}));
|
|
14646
14819
|
}
|
|
14820
|
+
function normalizeCowtailReplyPayload(payload) {
|
|
14821
|
+
if (!payload || typeof payload !== "object") {
|
|
14822
|
+
return {};
|
|
14823
|
+
}
|
|
14824
|
+
return normalizeOutboundReplyPayload(payload);
|
|
14825
|
+
}
|
|
14826
|
+
function buildCowtailToolCall(params) {
|
|
14827
|
+
const rawToolCall = readRawToolCall(params.rawPayload);
|
|
14828
|
+
const summary = resolveToolCallSummary(params.payload, rawToolCall);
|
|
14829
|
+
const index = params.streamState.toolCalls.length + 1;
|
|
14830
|
+
const toolCall = {
|
|
14831
|
+
id: rawToolCall.id ?? `tool-${index}`,
|
|
14832
|
+
name: rawToolCall.name ?? "tool_result",
|
|
14833
|
+
...rawToolCall.args ? { args: rawToolCall.args } : {},
|
|
14834
|
+
result: rawToolCall.result !== undefined ? rawToolCall.result : params.payload.text ?? params.payload,
|
|
14835
|
+
status: rawToolCall.status ?? "complete",
|
|
14836
|
+
...rawToolCall.startedAt !== undefined ? { startedAt: rawToolCall.startedAt } : {},
|
|
14837
|
+
completedAt: rawToolCall.completedAt ?? Date.now(),
|
|
14838
|
+
insertedAtContentLength: params.streamState.text.length,
|
|
14839
|
+
contentSnapshotAtStart: params.streamState.text
|
|
14840
|
+
};
|
|
14841
|
+
return {
|
|
14842
|
+
toolCall,
|
|
14843
|
+
...summary ? { summary } : {}
|
|
14844
|
+
};
|
|
14845
|
+
}
|
|
14846
|
+
function readRawToolCall(payload) {
|
|
14847
|
+
if (!payload || typeof payload !== "object") {
|
|
14848
|
+
return {};
|
|
14849
|
+
}
|
|
14850
|
+
const candidate = payload;
|
|
14851
|
+
const channelData = candidate.channelData;
|
|
14852
|
+
const toolCall = channelData && typeof channelData === "object" ? channelData.toolCall : undefined;
|
|
14853
|
+
const source = toolCall && typeof toolCall === "object" ? toolCall : candidate;
|
|
14854
|
+
const name = readString(source.name) ?? readString(source.toolName) ?? readString(source.tool);
|
|
14855
|
+
const id = readString(source.id) ?? readString(source.toolCallId);
|
|
14856
|
+
const status = readToolCallStatus(source.status);
|
|
14857
|
+
const args = readRecord(source.args) ?? readRecord(source.input);
|
|
14858
|
+
const startedAt = readTimestamp(source.startedAt);
|
|
14859
|
+
const completedAt = readTimestamp(source.completedAt);
|
|
14860
|
+
const insertedAtContentLength = readNonnegativeInteger(source.insertedAtContentLength);
|
|
14861
|
+
const contentSnapshotAtStart = readString(source.contentSnapshotAtStart);
|
|
14862
|
+
const result = source.result ?? source.output;
|
|
14863
|
+
return {
|
|
14864
|
+
...id ? { id } : {},
|
|
14865
|
+
...name ? { name } : {},
|
|
14866
|
+
...args ? { args } : {},
|
|
14867
|
+
...result !== undefined ? { result } : {},
|
|
14868
|
+
...status ? { status } : {},
|
|
14869
|
+
...startedAt !== undefined ? { startedAt } : {},
|
|
14870
|
+
...completedAt !== undefined ? { completedAt } : {},
|
|
14871
|
+
...insertedAtContentLength !== undefined ? { insertedAtContentLength } : {},
|
|
14872
|
+
...contentSnapshotAtStart !== undefined ? { contentSnapshotAtStart } : {}
|
|
14873
|
+
};
|
|
14874
|
+
}
|
|
14875
|
+
function resolveToolCallSummary(payload, toolCall) {
|
|
14876
|
+
if (typeof payload.text === "string" && payload.text.trim()) {
|
|
14877
|
+
return payload.text.trim().split(`
|
|
14878
|
+
`)[0];
|
|
14879
|
+
}
|
|
14880
|
+
if (toolCall.name) {
|
|
14881
|
+
return toolCall.name;
|
|
14882
|
+
}
|
|
14883
|
+
return;
|
|
14884
|
+
}
|
|
14885
|
+
function readString(value) {
|
|
14886
|
+
return typeof value === "string" && value.trim() ? value : undefined;
|
|
14887
|
+
}
|
|
14888
|
+
function readRecord(value) {
|
|
14889
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
14890
|
+
return;
|
|
14891
|
+
}
|
|
14892
|
+
return value;
|
|
14893
|
+
}
|
|
14894
|
+
function readToolCallStatus(value) {
|
|
14895
|
+
return value === "pending" || value === "running" || value === "complete" || value === "error" ? value : undefined;
|
|
14896
|
+
}
|
|
14897
|
+
function readTimestamp(value) {
|
|
14898
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : undefined;
|
|
14899
|
+
}
|
|
14900
|
+
function readNonnegativeInteger(value) {
|
|
14901
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : undefined;
|
|
14902
|
+
}
|
|
14903
|
+
function appendReplyBlock(current, next) {
|
|
14904
|
+
if (!next.trim()) {
|
|
14905
|
+
return current;
|
|
14906
|
+
}
|
|
14907
|
+
if (!current) {
|
|
14908
|
+
return next;
|
|
14909
|
+
}
|
|
14910
|
+
if (next.startsWith(current)) {
|
|
14911
|
+
return next;
|
|
14912
|
+
}
|
|
14913
|
+
return `${current}${next}`;
|
|
14914
|
+
}
|
|
14647
14915
|
function buildCowtailInboundBody(params) {
|
|
14648
14916
|
const cfg = params.runtime.config.loadConfig();
|
|
14649
14917
|
const storePath = params.runtime.agent.session.resolveStorePath(cfg.session?.store, {
|
package/dist/setup-entry.js
CHANGED
|
@@ -13728,6 +13728,7 @@ var openclawEventTypes = [
|
|
|
13728
13728
|
"thread_created",
|
|
13729
13729
|
"thread_updated",
|
|
13730
13730
|
"message_created",
|
|
13731
|
+
"message_updated",
|
|
13731
13732
|
"message_acknowledged",
|
|
13732
13733
|
"reply_created",
|
|
13733
13734
|
"action_submitted",
|
|
@@ -13742,12 +13743,24 @@ var openclawTargetAgentSchema = exports_external.literal("default");
|
|
|
13742
13743
|
var openclawMessageDirectionSchema = exports_external.enum(["openclaw_to_user", "user_to_openclaw"]);
|
|
13743
13744
|
var openclawDeliveryStateSchema = exports_external.enum(["pending", "sent", "failed"]);
|
|
13744
13745
|
var openclawActionStateSchema = exports_external.enum(["pending", "submitted", "failed", "expired"]);
|
|
13746
|
+
var openclawToolCallStatusSchema = exports_external.enum(["pending", "running", "complete", "error"]);
|
|
13745
13747
|
var openclawEventTypeSchema = exports_external.enum(openclawEventTypes);
|
|
13746
13748
|
var openclawSequenceSchema = exports_external.number().int().nonnegative();
|
|
13747
13749
|
var openclawLinkSchema = exports_external.object({
|
|
13748
13750
|
label: nonEmptyStringSchema,
|
|
13749
13751
|
url: nonEmptyStringSchema
|
|
13750
13752
|
});
|
|
13753
|
+
var openclawToolCallRecordSchema = exports_external.object({
|
|
13754
|
+
id: nonEmptyStringSchema,
|
|
13755
|
+
name: nonEmptyStringSchema,
|
|
13756
|
+
args: jsonObjectSchema.optional(),
|
|
13757
|
+
result: exports_external.unknown().optional(),
|
|
13758
|
+
status: openclawToolCallStatusSchema,
|
|
13759
|
+
startedAt: timestampSchema.optional(),
|
|
13760
|
+
completedAt: timestampSchema.optional(),
|
|
13761
|
+
insertedAtContentLength: exports_external.number().int().nonnegative().optional(),
|
|
13762
|
+
contentSnapshotAtStart: exports_external.string().optional()
|
|
13763
|
+
});
|
|
13751
13764
|
var openclawPluginClientHelloSchema = exports_external.object({
|
|
13752
13765
|
protocolVersion: openclawProtocolVersionSchema,
|
|
13753
13766
|
clientKind: exports_external.literal("openclaw_plugin"),
|
|
@@ -13782,6 +13795,7 @@ var openclawMessageRecordSchema = exports_external.object({
|
|
|
13782
13795
|
authorLabel: nonEmptyStringSchema.optional(),
|
|
13783
13796
|
text: nonEmptyStringSchema,
|
|
13784
13797
|
links: exports_external.array(openclawLinkSchema).default([]),
|
|
13798
|
+
toolCalls: exports_external.array(openclawToolCallRecordSchema).default([]),
|
|
13785
13799
|
deliveryState: openclawDeliveryStateSchema,
|
|
13786
13800
|
createdAt: timestampSchema,
|
|
13787
13801
|
updatedAt: timestampSchema
|
|
@@ -13832,7 +13846,19 @@ var openclawPluginMessageCommandSchema = exports_external.object({
|
|
|
13832
13846
|
text: nonEmptyStringSchema,
|
|
13833
13847
|
authorLabel: nonEmptyStringSchema.optional(),
|
|
13834
13848
|
links: exports_external.array(openclawLinkSchema).default([]),
|
|
13835
|
-
|
|
13849
|
+
toolCalls: exports_external.array(openclawToolCallRecordSchema).default([]),
|
|
13850
|
+
actions: exports_external.array(openclawActionDraftSchema).default([]),
|
|
13851
|
+
deliveryState: openclawDeliveryStateSchema.optional()
|
|
13852
|
+
});
|
|
13853
|
+
var openclawPluginMessageUpdateCommandSchema = exports_external.object({
|
|
13854
|
+
type: exports_external.literal("openclaw_message_update"),
|
|
13855
|
+
requestId: openclawRequestIdSchema,
|
|
13856
|
+
messageId: nonEmptyStringSchema,
|
|
13857
|
+
text: nonEmptyStringSchema,
|
|
13858
|
+
links: exports_external.array(openclawLinkSchema).optional(),
|
|
13859
|
+
toolCalls: exports_external.array(openclawToolCallRecordSchema).optional(),
|
|
13860
|
+
actions: exports_external.array(openclawActionDraftSchema).optional(),
|
|
13861
|
+
deliveryState: openclawDeliveryStateSchema.optional()
|
|
13836
13862
|
});
|
|
13837
13863
|
var openclawIosNewThreadCommandSchema = exports_external.object({
|
|
13838
13864
|
type: exports_external.literal("ios_new_thread"),
|
|
@@ -13883,6 +13909,7 @@ var openclawActionResultCommandSchema = exports_external.object({
|
|
|
13883
13909
|
});
|
|
13884
13910
|
var openclawRealtimeClientMessageSchema = exports_external.discriminatedUnion("type", [
|
|
13885
13911
|
openclawPluginMessageCommandSchema,
|
|
13912
|
+
openclawPluginMessageUpdateCommandSchema,
|
|
13886
13913
|
openclawIosNewThreadCommandSchema,
|
|
13887
13914
|
openclawIosReplyCommandSchema,
|
|
13888
13915
|
openclawIosActionCommandSchema,
|
|
@@ -13895,7 +13922,8 @@ var openclawRealtimeClientMessageSchema = exports_external.discriminatedUnion("t
|
|
|
13895
13922
|
var openclawRealtimeAckSchema = exports_external.object({
|
|
13896
13923
|
type: exports_external.literal("ack"),
|
|
13897
13924
|
requestId: openclawRequestIdSchema,
|
|
13898
|
-
sequence: openclawSequenceSchema.optional()
|
|
13925
|
+
sequence: openclawSequenceSchema.optional(),
|
|
13926
|
+
payload: jsonObjectSchema.optional()
|
|
13899
13927
|
});
|
|
13900
13928
|
var openclawRealtimeErrorSchema = exports_external.object({
|
|
13901
13929
|
type: exports_external.literal("realtime_error"),
|
|
@@ -14129,9 +14157,19 @@ class CowtailRealtimeClient {
|
|
|
14129
14157
|
...command,
|
|
14130
14158
|
requestId: this.#requestIdFactory(),
|
|
14131
14159
|
links: command.links ?? [],
|
|
14160
|
+
toolCalls: command.toolCalls ?? [],
|
|
14132
14161
|
actions: command.actions ?? []
|
|
14133
14162
|
});
|
|
14134
14163
|
}
|
|
14164
|
+
sendOpenClawMessageUpdate(command) {
|
|
14165
|
+
return this.#sendCommand({
|
|
14166
|
+
...command,
|
|
14167
|
+
requestId: this.#requestIdFactory(),
|
|
14168
|
+
...command.links ? { links: command.links } : {},
|
|
14169
|
+
...command.toolCalls ? { toolCalls: command.toolCalls } : {},
|
|
14170
|
+
...command.actions ? { actions: command.actions } : {}
|
|
14171
|
+
});
|
|
14172
|
+
}
|
|
14135
14173
|
sendSessionBound(command) {
|
|
14136
14174
|
return this.#sendCommand({
|
|
14137
14175
|
...command,
|
|
@@ -14236,7 +14274,7 @@ class CowtailRealtimeClient {
|
|
|
14236
14274
|
}
|
|
14237
14275
|
const message = parsed.data;
|
|
14238
14276
|
if (message.type === "ack") {
|
|
14239
|
-
this.#resolvePendingRequest(message.requestId, message.sequence);
|
|
14277
|
+
this.#resolvePendingRequest(message.requestId, message.sequence, message.payload);
|
|
14240
14278
|
return;
|
|
14241
14279
|
}
|
|
14242
14280
|
if (message.type === "realtime_error") {
|
|
@@ -14319,13 +14357,17 @@ class CowtailRealtimeClient {
|
|
|
14319
14357
|
}
|
|
14320
14358
|
});
|
|
14321
14359
|
}
|
|
14322
|
-
#resolvePendingRequest(requestId, sequence) {
|
|
14360
|
+
#resolvePendingRequest(requestId, sequence, payload) {
|
|
14323
14361
|
const pending = this.#pendingRequests.get(requestId);
|
|
14324
14362
|
if (!pending) {
|
|
14325
14363
|
return;
|
|
14326
14364
|
}
|
|
14327
14365
|
this.#pendingRequests.delete(requestId);
|
|
14328
|
-
pending.resolve({
|
|
14366
|
+
pending.resolve({
|
|
14367
|
+
requestId,
|
|
14368
|
+
sequence,
|
|
14369
|
+
...payload ? { payload } : {}
|
|
14370
|
+
});
|
|
14329
14371
|
}
|
|
14330
14372
|
#rejectPendingRequest(message) {
|
|
14331
14373
|
if (!message.requestId) {
|
|
@@ -14399,7 +14441,8 @@ class CowtailRealtimeClient {
|
|
|
14399
14441
|
}
|
|
14400
14442
|
|
|
14401
14443
|
// src/inbound.ts
|
|
14402
|
-
import {
|
|
14444
|
+
import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";
|
|
14445
|
+
import { normalizeOutboundReplyPayload } from "openclaw/plugin-sdk/reply-payload";
|
|
14403
14446
|
|
|
14404
14447
|
// src/session-keys.ts
|
|
14405
14448
|
function normalizeCowtailTarget(raw) {
|
|
@@ -14548,19 +14591,24 @@ async function dispatchCowtailTextTurn(params) {
|
|
|
14548
14591
|
body,
|
|
14549
14592
|
timestamp: message.createdAt
|
|
14550
14593
|
});
|
|
14551
|
-
|
|
14594
|
+
const streamState = { text: "", toolCalls: [] };
|
|
14595
|
+
await recordCowtailInboundSessionAndDispatchReply({
|
|
14552
14596
|
cfg: runtime.config.loadConfig(),
|
|
14553
14597
|
channel: CHANNEL_ID,
|
|
14554
14598
|
accountId: account.accountId,
|
|
14599
|
+
agentId: route.agentId,
|
|
14555
14600
|
route,
|
|
14556
14601
|
storePath,
|
|
14557
14602
|
ctxPayload,
|
|
14558
|
-
|
|
14559
|
-
deliver: async (payload) => deliverCowtailReply({
|
|
14603
|
+
runtime,
|
|
14604
|
+
deliver: async (payload, info, rawPayload) => deliverCowtailReply({
|
|
14560
14605
|
client,
|
|
14561
14606
|
route,
|
|
14562
14607
|
thread,
|
|
14563
|
-
payload
|
|
14608
|
+
payload,
|
|
14609
|
+
rawPayload,
|
|
14610
|
+
info,
|
|
14611
|
+
streamState
|
|
14564
14612
|
}),
|
|
14565
14613
|
onRecordError: (error48) => {
|
|
14566
14614
|
logger?.error?.(`Cowtail inbound session record failed: ${errorMessage(error48)}`);
|
|
@@ -14595,19 +14643,24 @@ async function dispatchCowtailActionTurn(params) {
|
|
|
14595
14643
|
timestamp
|
|
14596
14644
|
});
|
|
14597
14645
|
let dispatchFailed = false;
|
|
14598
|
-
|
|
14646
|
+
const streamState = { text: "", toolCalls: [] };
|
|
14647
|
+
await recordCowtailInboundSessionAndDispatchReply({
|
|
14599
14648
|
cfg: runtime.config.loadConfig(),
|
|
14600
14649
|
channel: CHANNEL_ID,
|
|
14601
14650
|
accountId: account.accountId,
|
|
14651
|
+
agentId: route.agentId,
|
|
14602
14652
|
route,
|
|
14603
14653
|
storePath,
|
|
14604
14654
|
ctxPayload,
|
|
14605
|
-
|
|
14606
|
-
deliver: async (replyPayload) => deliverCowtailReply({
|
|
14655
|
+
runtime,
|
|
14656
|
+
deliver: async (replyPayload, info, rawPayload) => deliverCowtailReply({
|
|
14607
14657
|
client,
|
|
14608
14658
|
route,
|
|
14609
14659
|
thread,
|
|
14610
|
-
payload: replyPayload
|
|
14660
|
+
payload: replyPayload,
|
|
14661
|
+
rawPayload,
|
|
14662
|
+
info,
|
|
14663
|
+
streamState
|
|
14611
14664
|
}),
|
|
14612
14665
|
onRecordError: (error48) => {
|
|
14613
14666
|
logger?.error?.(`Cowtail inbound session record failed: ${errorMessage(error48)}`);
|
|
@@ -14619,21 +14672,141 @@ async function dispatchCowtailActionTurn(params) {
|
|
|
14619
14672
|
});
|
|
14620
14673
|
return !dispatchFailed;
|
|
14621
14674
|
}
|
|
14675
|
+
async function recordCowtailInboundSessionAndDispatchReply(params) {
|
|
14676
|
+
await params.runtime.channel.session.recordInboundSession({
|
|
14677
|
+
storePath: params.storePath,
|
|
14678
|
+
sessionKey: typeof params.ctxPayload.SessionKey === "string" ? params.ctxPayload.SessionKey : params.route.sessionKey,
|
|
14679
|
+
ctx: params.ctxPayload,
|
|
14680
|
+
onRecordError: params.onRecordError
|
|
14681
|
+
});
|
|
14682
|
+
const { onModelSelected, ...replyPipeline } = createChannelReplyPipeline({
|
|
14683
|
+
cfg: params.cfg,
|
|
14684
|
+
agentId: params.agentId,
|
|
14685
|
+
channel: params.channel,
|
|
14686
|
+
accountId: params.accountId
|
|
14687
|
+
});
|
|
14688
|
+
await params.runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
|
|
14689
|
+
ctx: params.ctxPayload,
|
|
14690
|
+
cfg: params.cfg,
|
|
14691
|
+
dispatcherOptions: {
|
|
14692
|
+
...replyPipeline,
|
|
14693
|
+
deliver: async (payload, info) => {
|
|
14694
|
+
try {
|
|
14695
|
+
await params.deliver(normalizeCowtailReplyPayload(payload), info, payload);
|
|
14696
|
+
} catch (error48) {
|
|
14697
|
+
params.onDispatchError(error48, { kind: info?.kind ?? "final" });
|
|
14698
|
+
}
|
|
14699
|
+
},
|
|
14700
|
+
onError: params.onDispatchError
|
|
14701
|
+
},
|
|
14702
|
+
replyOptions: {
|
|
14703
|
+
onModelSelected
|
|
14704
|
+
}
|
|
14705
|
+
});
|
|
14706
|
+
}
|
|
14622
14707
|
async function deliverCowtailReply(params) {
|
|
14708
|
+
if (params.streamState.failed) {
|
|
14709
|
+
return;
|
|
14710
|
+
}
|
|
14623
14711
|
const text = params.payload.text;
|
|
14712
|
+
const kind = params.info?.kind ?? "final";
|
|
14713
|
+
const links = resolveCowtailReplyLinks(params.payload);
|
|
14714
|
+
if (kind === "tool") {
|
|
14715
|
+
const { toolCall, summary } = buildCowtailToolCall({
|
|
14716
|
+
payload: params.payload,
|
|
14717
|
+
rawPayload: params.rawPayload,
|
|
14718
|
+
streamState: params.streamState
|
|
14719
|
+
});
|
|
14720
|
+
params.streamState.toolCalls = [...params.streamState.toolCalls, toolCall];
|
|
14721
|
+
const messageText = params.streamState.text || summary || "Tool activity";
|
|
14722
|
+
if (!params.streamState.messageId) {
|
|
14723
|
+
const result = await params.client.sendOpenClawMessage({
|
|
14724
|
+
type: "openclaw_message",
|
|
14725
|
+
sessionKey: params.thread.sessionKey ?? params.route.sessionKey,
|
|
14726
|
+
title: params.thread.title,
|
|
14727
|
+
text: messageText,
|
|
14728
|
+
authorLabel: "OpenClaw",
|
|
14729
|
+
links,
|
|
14730
|
+
toolCalls: params.streamState.toolCalls,
|
|
14731
|
+
actions: [],
|
|
14732
|
+
deliveryState: "pending"
|
|
14733
|
+
});
|
|
14734
|
+
params.streamState.messageId = recordCreatedOpenClawMessageId(params.streamState, result);
|
|
14735
|
+
return;
|
|
14736
|
+
}
|
|
14737
|
+
await params.client.sendOpenClawMessageUpdate({
|
|
14738
|
+
type: "openclaw_message_update",
|
|
14739
|
+
messageId: params.streamState.messageId,
|
|
14740
|
+
text: messageText,
|
|
14741
|
+
links,
|
|
14742
|
+
toolCalls: params.streamState.toolCalls,
|
|
14743
|
+
deliveryState: "pending"
|
|
14744
|
+
});
|
|
14745
|
+
return;
|
|
14746
|
+
}
|
|
14624
14747
|
if (typeof text !== "string" || !text.trim()) {
|
|
14625
14748
|
return;
|
|
14626
14749
|
}
|
|
14750
|
+
if (kind === "block") {
|
|
14751
|
+
params.streamState.text = appendReplyBlock(params.streamState.text, text);
|
|
14752
|
+
if (!params.streamState.messageId) {
|
|
14753
|
+
const result = await params.client.sendOpenClawMessage({
|
|
14754
|
+
type: "openclaw_message",
|
|
14755
|
+
sessionKey: params.thread.sessionKey ?? params.route.sessionKey,
|
|
14756
|
+
title: params.thread.title,
|
|
14757
|
+
text: params.streamState.text,
|
|
14758
|
+
authorLabel: "OpenClaw",
|
|
14759
|
+
links,
|
|
14760
|
+
toolCalls: params.streamState.toolCalls,
|
|
14761
|
+
actions: [],
|
|
14762
|
+
deliveryState: "pending"
|
|
14763
|
+
});
|
|
14764
|
+
params.streamState.messageId = recordCreatedOpenClawMessageId(params.streamState, result);
|
|
14765
|
+
return;
|
|
14766
|
+
}
|
|
14767
|
+
await params.client.sendOpenClawMessageUpdate({
|
|
14768
|
+
type: "openclaw_message_update",
|
|
14769
|
+
messageId: params.streamState.messageId,
|
|
14770
|
+
text: params.streamState.text,
|
|
14771
|
+
links,
|
|
14772
|
+
toolCalls: params.streamState.toolCalls,
|
|
14773
|
+
deliveryState: "pending"
|
|
14774
|
+
});
|
|
14775
|
+
return;
|
|
14776
|
+
}
|
|
14777
|
+
if (params.streamState.messageId) {
|
|
14778
|
+
params.streamState.text = text;
|
|
14779
|
+
await params.client.sendOpenClawMessageUpdate({
|
|
14780
|
+
type: "openclaw_message_update",
|
|
14781
|
+
messageId: params.streamState.messageId,
|
|
14782
|
+
text,
|
|
14783
|
+
links,
|
|
14784
|
+
toolCalls: params.streamState.toolCalls,
|
|
14785
|
+
actions: [],
|
|
14786
|
+
deliveryState: "sent"
|
|
14787
|
+
});
|
|
14788
|
+
return;
|
|
14789
|
+
}
|
|
14627
14790
|
await params.client.sendOpenClawMessage({
|
|
14628
14791
|
type: "openclaw_message",
|
|
14629
14792
|
sessionKey: params.thread.sessionKey ?? params.route.sessionKey,
|
|
14630
14793
|
title: params.thread.title,
|
|
14631
14794
|
text,
|
|
14632
14795
|
authorLabel: "OpenClaw",
|
|
14633
|
-
links
|
|
14634
|
-
|
|
14796
|
+
links,
|
|
14797
|
+
toolCalls: params.streamState.toolCalls,
|
|
14798
|
+
actions: [],
|
|
14799
|
+
deliveryState: "sent"
|
|
14635
14800
|
});
|
|
14636
14801
|
}
|
|
14802
|
+
function recordCreatedOpenClawMessageId(streamState, result) {
|
|
14803
|
+
const messageId = result.payload?.messageId;
|
|
14804
|
+
if (typeof messageId === "string" && messageId.trim()) {
|
|
14805
|
+
return messageId;
|
|
14806
|
+
}
|
|
14807
|
+
streamState.failed = true;
|
|
14808
|
+
throw new Error("Cowtail realtime ack missing messageId for streamed OpenClaw reply");
|
|
14809
|
+
}
|
|
14637
14810
|
function resolveCowtailReplyLinks(payload) {
|
|
14638
14811
|
const urls = [
|
|
14639
14812
|
...Array.isArray(payload.mediaUrls) ? payload.mediaUrls : [],
|
|
@@ -14644,6 +14817,101 @@ function resolveCowtailReplyLinks(payload) {
|
|
|
14644
14817
|
url: url2
|
|
14645
14818
|
}));
|
|
14646
14819
|
}
|
|
14820
|
+
function normalizeCowtailReplyPayload(payload) {
|
|
14821
|
+
if (!payload || typeof payload !== "object") {
|
|
14822
|
+
return {};
|
|
14823
|
+
}
|
|
14824
|
+
return normalizeOutboundReplyPayload(payload);
|
|
14825
|
+
}
|
|
14826
|
+
function buildCowtailToolCall(params) {
|
|
14827
|
+
const rawToolCall = readRawToolCall(params.rawPayload);
|
|
14828
|
+
const summary = resolveToolCallSummary(params.payload, rawToolCall);
|
|
14829
|
+
const index = params.streamState.toolCalls.length + 1;
|
|
14830
|
+
const toolCall = {
|
|
14831
|
+
id: rawToolCall.id ?? `tool-${index}`,
|
|
14832
|
+
name: rawToolCall.name ?? "tool_result",
|
|
14833
|
+
...rawToolCall.args ? { args: rawToolCall.args } : {},
|
|
14834
|
+
result: rawToolCall.result !== undefined ? rawToolCall.result : params.payload.text ?? params.payload,
|
|
14835
|
+
status: rawToolCall.status ?? "complete",
|
|
14836
|
+
...rawToolCall.startedAt !== undefined ? { startedAt: rawToolCall.startedAt } : {},
|
|
14837
|
+
completedAt: rawToolCall.completedAt ?? Date.now(),
|
|
14838
|
+
insertedAtContentLength: params.streamState.text.length,
|
|
14839
|
+
contentSnapshotAtStart: params.streamState.text
|
|
14840
|
+
};
|
|
14841
|
+
return {
|
|
14842
|
+
toolCall,
|
|
14843
|
+
...summary ? { summary } : {}
|
|
14844
|
+
};
|
|
14845
|
+
}
|
|
14846
|
+
function readRawToolCall(payload) {
|
|
14847
|
+
if (!payload || typeof payload !== "object") {
|
|
14848
|
+
return {};
|
|
14849
|
+
}
|
|
14850
|
+
const candidate = payload;
|
|
14851
|
+
const channelData = candidate.channelData;
|
|
14852
|
+
const toolCall = channelData && typeof channelData === "object" ? channelData.toolCall : undefined;
|
|
14853
|
+
const source = toolCall && typeof toolCall === "object" ? toolCall : candidate;
|
|
14854
|
+
const name = readString(source.name) ?? readString(source.toolName) ?? readString(source.tool);
|
|
14855
|
+
const id = readString(source.id) ?? readString(source.toolCallId);
|
|
14856
|
+
const status = readToolCallStatus(source.status);
|
|
14857
|
+
const args = readRecord(source.args) ?? readRecord(source.input);
|
|
14858
|
+
const startedAt = readTimestamp(source.startedAt);
|
|
14859
|
+
const completedAt = readTimestamp(source.completedAt);
|
|
14860
|
+
const insertedAtContentLength = readNonnegativeInteger(source.insertedAtContentLength);
|
|
14861
|
+
const contentSnapshotAtStart = readString(source.contentSnapshotAtStart);
|
|
14862
|
+
const result = source.result ?? source.output;
|
|
14863
|
+
return {
|
|
14864
|
+
...id ? { id } : {},
|
|
14865
|
+
...name ? { name } : {},
|
|
14866
|
+
...args ? { args } : {},
|
|
14867
|
+
...result !== undefined ? { result } : {},
|
|
14868
|
+
...status ? { status } : {},
|
|
14869
|
+
...startedAt !== undefined ? { startedAt } : {},
|
|
14870
|
+
...completedAt !== undefined ? { completedAt } : {},
|
|
14871
|
+
...insertedAtContentLength !== undefined ? { insertedAtContentLength } : {},
|
|
14872
|
+
...contentSnapshotAtStart !== undefined ? { contentSnapshotAtStart } : {}
|
|
14873
|
+
};
|
|
14874
|
+
}
|
|
14875
|
+
function resolveToolCallSummary(payload, toolCall) {
|
|
14876
|
+
if (typeof payload.text === "string" && payload.text.trim()) {
|
|
14877
|
+
return payload.text.trim().split(`
|
|
14878
|
+
`)[0];
|
|
14879
|
+
}
|
|
14880
|
+
if (toolCall.name) {
|
|
14881
|
+
return toolCall.name;
|
|
14882
|
+
}
|
|
14883
|
+
return;
|
|
14884
|
+
}
|
|
14885
|
+
function readString(value) {
|
|
14886
|
+
return typeof value === "string" && value.trim() ? value : undefined;
|
|
14887
|
+
}
|
|
14888
|
+
function readRecord(value) {
|
|
14889
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
14890
|
+
return;
|
|
14891
|
+
}
|
|
14892
|
+
return value;
|
|
14893
|
+
}
|
|
14894
|
+
function readToolCallStatus(value) {
|
|
14895
|
+
return value === "pending" || value === "running" || value === "complete" || value === "error" ? value : undefined;
|
|
14896
|
+
}
|
|
14897
|
+
function readTimestamp(value) {
|
|
14898
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : undefined;
|
|
14899
|
+
}
|
|
14900
|
+
function readNonnegativeInteger(value) {
|
|
14901
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : undefined;
|
|
14902
|
+
}
|
|
14903
|
+
function appendReplyBlock(current, next) {
|
|
14904
|
+
if (!next.trim()) {
|
|
14905
|
+
return current;
|
|
14906
|
+
}
|
|
14907
|
+
if (!current) {
|
|
14908
|
+
return next;
|
|
14909
|
+
}
|
|
14910
|
+
if (next.startsWith(current)) {
|
|
14911
|
+
return next;
|
|
14912
|
+
}
|
|
14913
|
+
return `${current}${next}`;
|
|
14914
|
+
}
|
|
14647
14915
|
function buildCowtailInboundBody(params) {
|
|
14648
14916
|
const cfg = params.runtime.config.loadConfig();
|
|
14649
14917
|
const storePath = params.runtime.agent.session.resolveStorePath(cfg.session?.store, {
|