Skip to content

Commit 09253bf

Browse files
author
Eva
committed
feat(plugin-sdk): add generic SDK seam followups
Adds host runtime reads, derived tool paths, channel attachment hints, input-suppression descriptors, scheduler tag cleanup, session-entry slot projection, and channel helper exports on top of the workflow seams.
1 parent 9e8cf8c commit 09253bf

41 files changed

Lines changed: 2027 additions & 26 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/macos/Sources/OpenClawProtocol/GatewayModels.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4395,6 +4395,7 @@ public struct PluginControlUiDescriptor: Codable, Sendable {
43954395
public let renderer: String?
43964396
public let statenamespace: String?
43974397
public let actionids: [String]?
4398+
public let suppresshostinputwhile: [String: AnyCodable]?
43984399
public let schema: AnyCodable?
43994400
public let requiredscopes: [String]?
44004401

@@ -4409,6 +4410,7 @@ public struct PluginControlUiDescriptor: Codable, Sendable {
44094410
renderer: String?,
44104411
statenamespace: String?,
44114412
actionids: [String]?,
4413+
suppresshostinputwhile: [String: AnyCodable]?,
44124414
schema: AnyCodable?,
44134415
requiredscopes: [String]?)
44144416
{
@@ -4422,6 +4424,7 @@ public struct PluginControlUiDescriptor: Codable, Sendable {
44224424
self.renderer = renderer
44234425
self.statenamespace = statenamespace
44244426
self.actionids = actionids
4427+
self.suppresshostinputwhile = suppresshostinputwhile
44254428
self.schema = schema
44264429
self.requiredscopes = requiredscopes
44274430
}
@@ -4437,6 +4440,7 @@ public struct PluginControlUiDescriptor: Codable, Sendable {
44374440
case renderer
44384441
case statenamespace = "stateNamespace"
44394442
case actionids = "actionIds"
4443+
case suppresshostinputwhile = "suppressHostInputWhile"
44404444
case schema
44414445
case requiredscopes = "requiredScopes"
44424446
}

apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4395,6 +4395,7 @@ public struct PluginControlUiDescriptor: Codable, Sendable {
43954395
public let renderer: String?
43964396
public let statenamespace: String?
43974397
public let actionids: [String]?
4398+
public let suppresshostinputwhile: [String: AnyCodable]?
43984399
public let schema: AnyCodable?
43994400
public let requiredscopes: [String]?
44004401

@@ -4409,6 +4410,7 @@ public struct PluginControlUiDescriptor: Codable, Sendable {
44094410
renderer: String?,
44104411
statenamespace: String?,
44114412
actionids: [String]?,
4413+
suppresshostinputwhile: [String: AnyCodable]?,
44124414
schema: AnyCodable?,
44134415
requiredscopes: [String]?)
44144416
{
@@ -4422,6 +4424,7 @@ public struct PluginControlUiDescriptor: Codable, Sendable {
44224424
self.renderer = renderer
44234425
self.statenamespace = statenamespace
44244426
self.actionids = actionids
4427+
self.suppresshostinputwhile = suppresshostinputwhile
44254428
self.schema = schema
44264429
self.requiredscopes = requiredscopes
44274430
}
@@ -4437,6 +4440,7 @@ public struct PluginControlUiDescriptor: Codable, Sendable {
44374440
case renderer
44384441
case statenamespace = "stateNamespace"
44394442
case actionids = "actionIds"
4443+
case suppresshostinputwhile = "suppressHostInputWhile"
44404444
case schema
44414445
case requiredscopes = "requiredScopes"
44424446
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
4d9d95b378019e6dc0c533af87bac2251b426ccc2c63b36a941101161bb81e95 plugin-sdk-api-baseline.json
2-
7cb657a117e1c5c227a0b6b8ae5c4c371ca4f4f97a7b4f57a9f980573deb4c76 plugin-sdk-api-baseline.jsonl
1+
93a24eda968062d28c5bda33e1d6eaec8cb252d4b3bde9ead1e5fe46756b1e4a plugin-sdk-api-baseline.json
2+
0ceea424a909b5c059d47384ebf36a5912c51c40e30b5cae6cd1a0c92b4e7f18 plugin-sdk-api-baseline.jsonl

extensions/qa-lab/src/runtime-api.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export {
2020
searchQaBusMessages,
2121
sendQaBusMessage,
2222
setQaChannelRuntime,
23-
} from "openclaw/plugin-sdk/qa-channel";
23+
} from "@openclaw/qa-channel/api.js";
2424
export type {
2525
QaBusAttachment,
2626
QaBusConversation,
@@ -39,4 +39,4 @@ export type {
3939
QaBusStateSnapshot,
4040
QaBusThread,
4141
QaBusWaitForInput,
42-
} from "./protocol.js";
42+
} from "@openclaw/qa-channel/api.js";

extensions/telegram/api.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { describe, expect, it } from "vitest";
2+
import { escapeTelegramHtml, markdownToTelegramHtml } from "./api.js";
3+
4+
describe("@openclaw/telegram api re-exports", () => {
5+
it("re-exports markdownToTelegramHtml as a working function", () => {
6+
expect(typeof markdownToTelegramHtml).toBe("function");
7+
const rendered = markdownToTelegramHtml("**bold** plain");
8+
expect(rendered).toContain("<b>");
9+
expect(rendered).toContain("plain");
10+
});
11+
12+
it("re-exports escapeTelegramHtml that escapes the three Telegram-reserved characters", () => {
13+
expect(typeof escapeTelegramHtml).toBe("function");
14+
expect(escapeTelegramHtml("<b>x & y</b>")).toBe("&lt;b&gt;x &amp; y&lt;/b&gt;");
15+
});
16+
});

extensions/telegram/api.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,11 @@ export {
182182
export type { TelegramButtonStyle, TelegramInlineButtons } from "./src/button-types.js";
183183
export type { StickerMetadata } from "./src/bot/types.js";
184184
export type { TelegramTokenResolution } from "./src/token.js";
185+
export {
186+
escapeTelegramHtml,
187+
markdownToTelegramChunks,
188+
markdownToTelegramHtml,
189+
markdownToTelegramHtmlChunks,
190+
splitTelegramHtmlChunks,
191+
type TelegramFormattedChunk,
192+
} from "./src/format.js";

extensions/telegram/src/channel.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ function buildTelegramSendOptions(params: {
170170
threadId?: string | number | null;
171171
silent?: boolean | null;
172172
forceDocument?: boolean | null;
173+
parseMode?: "HTML" | "MarkdownV2" | null;
173174
gatewayClientScopes?: readonly string[] | null;
174175
}): TelegramSendOptions {
175176
return {
@@ -182,6 +183,7 @@ function buildTelegramSendOptions(params: {
182183
accountId: params.accountId ?? undefined,
183184
silent: params.silent ?? undefined,
184185
forceDocument: params.forceDocument ?? undefined,
186+
textMode: params.parseMode === "MarkdownV2" ? "markdown" : "html",
185187
...(Array.isArray(params.gatewayClientScopes)
186188
? { gatewayClientScopes: [...params.gatewayClientScopes] }
187189
: {}),
@@ -199,6 +201,7 @@ async function sendTelegramOutbound(params: {
199201
replyToId?: string | null;
200202
threadId?: string | number | null;
201203
silent?: boolean | null;
204+
parseMode?: "HTML" | "MarkdownV2" | null;
202205
gatewayClientScopes?: readonly string[] | null;
203206
}) {
204207
const send = await resolveTelegramSend(params.deps);
@@ -213,6 +216,7 @@ async function sendTelegramOutbound(params: {
213216
replyToId: params.replyToId,
214217
threadId: params.threadId,
215218
silent: params.silent,
219+
parseMode: params.parseMode,
216220
gatewayClientScopes: params.gatewayClientScopes,
217221
}),
218222
);
@@ -1098,6 +1102,7 @@ export const telegramPlugin = createChatChannelPlugin({
10981102
replyToId,
10991103
threadId,
11001104
silent,
1105+
formatting,
11011106
gatewayClientScopes,
11021107
}) =>
11031108
await sendTelegramOutbound({
@@ -1109,6 +1114,7 @@ export const telegramPlugin = createChatChannelPlugin({
11091114
replyToId,
11101115
threadId,
11111116
silent,
1117+
parseMode: formatting?.parseMode,
11121118
gatewayClientScopes,
11131119
}),
11141120
sendMedia: async ({
@@ -1122,6 +1128,7 @@ export const telegramPlugin = createChatChannelPlugin({
11221128
replyToId,
11231129
threadId,
11241130
silent,
1131+
formatting,
11251132
gatewayClientScopes,
11261133
}) =>
11271134
await sendTelegramOutbound({
@@ -1135,6 +1142,7 @@ export const telegramPlugin = createChatChannelPlugin({
11351142
replyToId,
11361143
threadId,
11371144
silent,
1145+
parseMode: formatting?.parseMode,
11381146
gatewayClientScopes,
11391147
}),
11401148
sendPoll: async ({

extensions/telegram/src/format.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,20 @@ export type TelegramFormattedChunk = {
1515
text: string;
1616
};
1717

18-
function escapeHtml(text: string): string {
18+
/**
19+
* Escape a plain string for safe insertion inside Telegram HTML messages.
20+
*
21+
* Public alias used by `@openclaw/telegram/api` so plugin authors can render
22+
* Telegram-safe captions without re-implementing the escape rules.
23+
*/
24+
export function escapeTelegramHtml(text: string): string {
1925
return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
2026
}
2127

28+
function escapeHtml(text: string): string {
29+
return escapeTelegramHtml(text);
30+
}
31+
2232
function escapeHtmlAttr(text: string): string {
2333
return escapeHtml(text).replace(/"/g, "&quot;");
2434
}

extensions/telegram/src/outbound-adapter.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ async function resolveTelegramSendContext(params: {
4848
baseOpts: {
4949
cfg: NonNullable<TelegramSendOpts>["cfg"];
5050
verbose: false;
51-
textMode: "html";
51+
textMode: "html" | "markdown";
5252
messageThreadId?: number;
5353
replyToMessageId?: number;
5454
accountId?: string;
@@ -161,6 +161,7 @@ export const telegramOutbound: ChannelOutboundAdapter = {
161161
replyToId,
162162
threadId,
163163
gatewayClientScopes,
164+
formatting,
164165
}) => {
165166
const { send, baseOpts } = await resolveTelegramSendContext({
166167
cfg,
@@ -172,6 +173,7 @@ export const telegramOutbound: ChannelOutboundAdapter = {
172173
});
173174
return await send(to, text, {
174175
...baseOpts,
176+
textMode: formatting?.parseMode === "MarkdownV2" ? "markdown" : "html",
175177
});
176178
},
177179
sendMedia: async ({
@@ -187,6 +189,7 @@ export const telegramOutbound: ChannelOutboundAdapter = {
187189
threadId,
188190
forceDocument,
189191
gatewayClientScopes,
192+
formatting,
190193
}) => {
191194
const { send, baseOpts } = await resolveTelegramSendContext({
192195
cfg,
@@ -198,6 +201,7 @@ export const telegramOutbound: ChannelOutboundAdapter = {
198201
});
199202
return await send(to, text, {
200203
...baseOpts,
204+
textMode: formatting?.parseMode === "MarkdownV2" ? "markdown" : "html",
201205
mediaUrl,
202206
mediaLocalRoots,
203207
mediaReadFile,

src/agents/agent-command.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,7 @@ async function agentCommandInternal(
479479
const startedAt = Date.now();
480480
registerAgentRunContext(runId, {
481481
sessionKey,
482+
...(opts.parentRunId ? { parentRunId: opts.parentRunId } : {}),
482483
});
483484
attemptExecutionRuntime.emitAcpLifecycleStart({ runId, startedAt });
484485

@@ -605,6 +606,7 @@ async function agentCommandInternal(
605606
registerAgentRunContext(runId, {
606607
sessionKey,
607608
verboseLevel: resolvedVerboseLevel,
609+
...(opts.parentRunId ? { parentRunId: opts.parentRunId } : {}),
608610
});
609611
}
610612

0 commit comments

Comments
 (0)