Skip to content

Commit 97d1b88

Browse files
committed
fix(cycles): split plugin runtime contract leaf types
1 parent aaae1ae commit 97d1b88

14 files changed

Lines changed: 211 additions & 136 deletions
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { RunEmbeddedPiAgentParams } from "./pi-embedded-runner/run/params.js";
2+
import type { EmbeddedPiRunResult } from "./pi-embedded-runner/types.js";
3+
4+
export type RunEmbeddedPiAgentFn = (
5+
params: RunEmbeddedPiAgentParams,
6+
) => Promise<EmbeddedPiRunResult>;
7+
8+
export type RunEmbeddedAgentFn = RunEmbeddedPiAgentFn;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import type { ShouldHandleTextCommandsParams } from "./commands-registry.types.js";
2+
3+
export type ShouldHandleTextCommands = (params: ShouldHandleTextCommandsParams) => boolean;

src/auto-reply/reply/mentions.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ import {
1111
} from "../../shared/string-coerce.js";
1212
import { escapeRegExp } from "../../utils.js";
1313
import type { MsgContext } from "../templating.js";
14+
import type { ExplicitMentionSignal } from "./mentions.types.js";
15+
export type {
16+
BuildMentionRegexes,
17+
ExplicitMentionSignal,
18+
MatchesMentionPatterns,
19+
MatchesMentionWithExplicit,
20+
} from "./mentions.types.js";
1421

1522
function deriveMentionPatterns(identity?: { name?: string; emoji?: string }) {
1623
const patterns: string[] = [];
@@ -150,12 +157,6 @@ export function matchesMentionPatterns(text: string, mentionRegexes: RegExp[]):
150157
return mentionRegexes.some((re) => re.test(cleaned));
151158
}
152159

153-
export type ExplicitMentionSignal = {
154-
hasAnyMention: boolean;
155-
isExplicitlyMentioned: boolean;
156-
canResolveExplicit: boolean;
157-
};
158-
159160
export function matchesMentionWithExplicit(params: {
160161
text: string;
161162
mentionRegexes: RegExp[];
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { OpenClawConfig } from "../../config/types.openclaw.js";
2+
3+
export type BuildMentionRegexes = (cfg: OpenClawConfig | undefined, agentId?: string) => RegExp[];
4+
5+
export type MatchesMentionPatterns = (text: string, mentionRegexes: RegExp[]) => boolean;
6+
7+
export type ExplicitMentionSignal = {
8+
hasAnyMention: boolean;
9+
isExplicitlyMentioned: boolean;
10+
canResolveExplicit: boolean;
11+
};
12+
13+
export type MatchesMentionWithExplicit = (params: {
14+
text: string;
15+
mentionRegexes: RegExp[];
16+
explicit?: ExplicitMentionSignal;
17+
transcript?: string;
18+
}) => boolean;

src/channels/session.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type { MsgContext } from "../auto-reply/templating.js";
2-
import type { GroupKeyResolution, SessionEntry } from "../config/sessions/types.js";
2+
import type { GroupKeyResolution } from "../config/sessions/types.js";
33
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
4+
import type { InboundLastRouteUpdate } from "./session.types.js";
5+
export type { InboundLastRouteUpdate, RecordInboundSession } from "./session.types.js";
46

57
let inboundSessionRuntimePromise: Promise<
68
typeof import("../config/sessions/inbound.runtime.js")
@@ -11,19 +13,6 @@ function loadInboundSessionRuntime() {
1113
return inboundSessionRuntimePromise;
1214
}
1315

14-
export type InboundLastRouteUpdate = {
15-
sessionKey: string;
16-
channel: SessionEntry["lastChannel"];
17-
to: string;
18-
accountId?: string;
19-
threadId?: string | number;
20-
mainDmOwnerPin?: {
21-
ownerRecipient: string;
22-
senderRecipient: string;
23-
onSkip?: (params: { ownerRecipient: string; senderRecipient: string }) => void;
24-
};
25-
};
26-
2716
function shouldSkipPinnedMainDmRouteUpdate(
2817
pin: InboundLastRouteUpdate["mainDmOwnerPin"] | undefined,
2918
): boolean {

src/channels/session.types.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import type { MsgContext } from "../auto-reply/templating.js";
2+
import type { GroupKeyResolution, SessionEntry } from "../config/sessions/types.js";
3+
4+
export type InboundLastRouteUpdate = {
5+
sessionKey: string;
6+
channel: SessionEntry["lastChannel"];
7+
to: string;
8+
accountId?: string;
9+
threadId?: string | number;
10+
mainDmOwnerPin?: {
11+
ownerRecipient: string;
12+
senderRecipient: string;
13+
onSkip?: (params: { ownerRecipient: string; senderRecipient: string }) => void;
14+
};
15+
};
16+
17+
export type RecordInboundSession = (params: {
18+
storePath: string;
19+
sessionKey: string;
20+
ctx: MsgContext;
21+
groupResolution?: GroupKeyResolution | null;
22+
createIfMissing?: boolean;
23+
updateLastRoute?: InboundLastRouteUpdate;
24+
onRecordError: (err: unknown) => void;
25+
}) => Promise<void>;

src/hooks/hooks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export * from "./internal-hooks.js";
22

33
export type HookEventType = import("./internal-hooks.js").InternalHookEventType;
44
export type HookEvent = import("./internal-hooks.js").InternalHookEvent;
5-
export type HookHandler = import("./internal-hooks.js").InternalHookHandler;
5+
export type HookHandler = import("./internal-hook-types.js").InternalHookHandler;
66

77
export {
88
registerInternalHook as registerHook,

src/hooks/internal-hook-types.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export type InternalHookEventType = "command" | "session" | "agent" | "gateway" | "message";
2+
3+
export interface InternalHookEvent {
4+
/** The type of event (command, session, agent, gateway, etc.) */
5+
type: InternalHookEventType;
6+
/** The specific action within the type (e.g., 'new', 'reset', 'stop') */
7+
action: string;
8+
/** The session key this event relates to */
9+
sessionKey: string;
10+
/** Additional context specific to the event */
11+
context: Record<string, unknown>;
12+
/** Timestamp when the event occurred */
13+
timestamp: Date;
14+
/** Messages to send back to the user (hooks can push to this array) */
15+
messages: string[];
16+
}
17+
18+
export type InternalHookHandler = (event: InternalHookEvent) => Promise<void> | void;

src/hooks/internal-hooks.ts

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,16 @@ import type { WorkspaceBootstrapFile } from "../agents/workspace.js";
99
import type { CliDeps } from "../cli/outbound-send-deps.js";
1010
import type { SessionEntry } from "../config/sessions/types.js";
1111
import type { OpenClawConfig } from "../config/types.openclaw.js";
12-
import type { SessionsPatchParams } from "../gateway/protocol/index.js";
12+
import type { SessionsPatchParams } from "../gateway/protocol/schema/types.js";
1313
import { formatErrorMessage } from "../infra/errors.js";
1414
import { createSubsystemLogger } from "../logging/subsystem.js";
1515
import { resolveGlobalSingleton } from "../shared/global-singleton.js";
16-
17-
export type InternalHookEventType = "command" | "session" | "agent" | "gateway" | "message";
16+
import type {
17+
InternalHookEvent,
18+
InternalHookEventType,
19+
InternalHookHandler,
20+
} from "./internal-hook-types.js";
21+
export type { InternalHookEvent, InternalHookEventType, InternalHookHandler };
1822

1923
export type AgentBootstrapHookContext = {
2024
workspaceDir: string;
@@ -172,23 +176,6 @@ export type SessionPatchHookEvent = InternalHookEvent & {
172176
context: SessionPatchHookContext;
173177
};
174178

175-
export interface InternalHookEvent {
176-
/** The type of event (command, session, agent, gateway, etc.) */
177-
type: InternalHookEventType;
178-
/** The specific action within the type (e.g., 'new', 'reset', 'stop') */
179-
action: string;
180-
/** The session key this event relates to */
181-
sessionKey: string;
182-
/** Additional context specific to the event */
183-
context: Record<string, unknown>;
184-
/** Timestamp when the event occurred */
185-
timestamp: Date;
186-
/** Messages to send back to the user (hooks can push to this array) */
187-
messages: string[];
188-
}
189-
190-
export type InternalHookHandler = (event: InternalHookEvent) => Promise<void> | void;
191-
192179
/**
193180
* Registry of hook handlers by event key.
194181
*

src/plugins/cli-backend.types.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import type { CliBackendConfig } from "../config/types.js";
2+
import type { OpenClawConfig } from "../config/types.openclaw.js";
3+
4+
export type PluginTextReplacement = {
5+
from: string | RegExp;
6+
to: string;
7+
};
8+
9+
export type PluginTextTransforms = {
10+
/** Rewrites applied to outbound prompt text before provider/CLI transport. */
11+
input?: PluginTextReplacement[];
12+
/** Rewrites applied to inbound assistant text before OpenClaw consumes it. */
13+
output?: PluginTextReplacement[];
14+
};
15+
16+
export type CliBundleMcpMode =
17+
| "claude-config-file"
18+
| "codex-config-overrides"
19+
| "gemini-system-settings";
20+
21+
/** Plugin-owned CLI backend defaults used by the text-only CLI runner. */
22+
export type CliBackendPlugin = {
23+
/** Provider id used in model refs, for example `claude-cli/opus`. */
24+
id: string;
25+
/** Default backend config before user overrides from `agents.defaults.cliBackends`. */
26+
config: CliBackendConfig;
27+
/**
28+
* Optional live-smoke metadata owned by the backend plugin.
29+
*
30+
* Keep provider-specific test wiring here instead of scattering it across
31+
* Docker wrappers, docs, and gateway live tests.
32+
*/
33+
liveTest?: {
34+
defaultModelRef?: string;
35+
defaultImageProbe?: boolean;
36+
defaultMcpProbe?: boolean;
37+
docker?: {
38+
npmPackage?: string;
39+
binaryName?: string;
40+
};
41+
};
42+
/**
43+
* Whether OpenClaw should inject bundle MCP config for this backend.
44+
*
45+
* Keep this opt-in. Only backends that explicitly consume OpenClaw's bundle
46+
* MCP bridge should enable it.
47+
*/
48+
bundleMcp?: boolean;
49+
/**
50+
* Provider-owned bundle MCP integration strategy.
51+
*
52+
* Different CLIs wire MCP through different surfaces:
53+
* - Claude: `--strict-mcp-config --mcp-config`
54+
* - Codex: `-c mcp_servers=...`
55+
* - Gemini: system-level `settings.json`
56+
*/
57+
bundleMcpMode?: CliBundleMcpMode;
58+
/**
59+
* Optional config normalizer applied after user overrides merge.
60+
*
61+
* Use this for backend-specific compatibility rewrites when old config
62+
* shapes need to stay working.
63+
*/
64+
normalizeConfig?: (config: CliBackendConfig) => CliBackendConfig;
65+
/**
66+
* Backend-owned final system-prompt transform.
67+
*
68+
* Use this for tiny CLI-specific compatibility rewrites without replacing
69+
* the generic CLI runner or prompt builder.
70+
*/
71+
transformSystemPrompt?: (ctx: {
72+
config?: OpenClawConfig;
73+
workspaceDir?: string;
74+
provider: string;
75+
modelId: string;
76+
modelDisplay: string;
77+
agentId?: string;
78+
systemPrompt: string;
79+
}) => string | null | undefined;
80+
/**
81+
* Backend-owned bidirectional text replacements.
82+
*
83+
* `input` applies to the system prompt and user prompt passed to the CLI.
84+
* `output` applies to parsed/streamed assistant text from the CLI.
85+
*/
86+
textTransforms?: PluginTextTransforms;
87+
};

0 commit comments

Comments
 (0)