mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
refactor(packages): DM-policy contract suite, dead routes, package folds (#114776)
* test(channels): share DM policy contract suite * refactor(memory): remove dead host CLI routes * refactor(acp): use canonical normalization helpers * refactor(web): fold provider runtime into core * refactor(packages): remove dead runtime exports * chore(knip): drop retired ACP entry roots
This commit is contained in:
committed by
GitHub
parent
83fa3ce993
commit
a1e0c9ea09
@@ -20,7 +20,7 @@ paths:
|
||||
- src/agents/tools/web-shared.ts
|
||||
- src/plugin-sdk/ssrf-policy.ts
|
||||
- src/web-fetch
|
||||
- packages/web-content-core/src/provider-runtime-shared.ts
|
||||
- src/web/provider-runtime-shared.ts
|
||||
- packages/memory-host-sdk/src/host/ssrf-policy.ts
|
||||
- packages/net-policy/src
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ query-filters:
|
||||
paths:
|
||||
- src/web-fetch
|
||||
- src/web-search
|
||||
- packages/web-content-core/src/provider-runtime-shared.ts
|
||||
- src/web/provider-runtime-shared.ts
|
||||
- src/media
|
||||
- src/media-understanding
|
||||
- src/image-generation
|
||||
|
||||
@@ -243,7 +243,6 @@
|
||||
"packages/terminal-core/**/*.ts",
|
||||
"packages/normalization-core/**/*.ts",
|
||||
"packages/model-catalog-core/**/*.ts",
|
||||
"packages/web-content-core/**/*.ts",
|
||||
"packages/agent-core/**/*.ts",
|
||||
"packages/acp-core/**/*.ts",
|
||||
"packages/ai/**/*.ts",
|
||||
|
||||
@@ -562,10 +562,7 @@ const config = {
|
||||
"packages/acp-core": {
|
||||
entry: [
|
||||
"src/index.ts!",
|
||||
"src/normalize-text.ts!",
|
||||
"src/meta.ts!",
|
||||
"src/numeric-options.ts!",
|
||||
"src/record-shared.ts!",
|
||||
"src/session.ts!",
|
||||
"src/session-interaction-mode.ts!",
|
||||
"src/session-lineage-meta.ts!",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Discord tests cover setup surface plugin behavior.
|
||||
import { installChannelDmPolicyContractSuite } from "openclaw/plugin-sdk/channel-test-helpers";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { createDiscordSetupWizardBase } from "./setup-core.js";
|
||||
@@ -19,55 +20,17 @@ const discordSetupWizard = createDiscordSetupWizardBase({
|
||||
});
|
||||
|
||||
describe("discordSetupWizard.dmPolicy", () => {
|
||||
it("reads the named-account DM policy instead of the channel root", () => {
|
||||
expect(
|
||||
discordSetupWizard.dmPolicy?.getCurrent(
|
||||
{
|
||||
channels: {
|
||||
discord: {
|
||||
dmPolicy: "disabled",
|
||||
accounts: {
|
||||
alerts: {
|
||||
dmPolicy: "allowlist",
|
||||
token: "discord-token",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
"alerts",
|
||||
),
|
||||
).toBe("allowlist");
|
||||
});
|
||||
|
||||
it("reports account-scoped config keys for named accounts", () => {
|
||||
expect(discordSetupWizard.dmPolicy?.resolveConfigKeys?.({}, "alerts")).toEqual({
|
||||
policyKey: "channels.discord.accounts.alerts.dmPolicy",
|
||||
allowFromKey: "channels.discord.accounts.alerts.allowFrom",
|
||||
});
|
||||
});
|
||||
|
||||
it('writes open policy state to the named account and preserves inherited allowFrom with "*"', () => {
|
||||
const next = discordSetupWizard.dmPolicy?.setPolicy(
|
||||
installChannelDmPolicyContractSuite({
|
||||
dmPolicy: discordSetupWizard.dmPolicy!,
|
||||
cases: [
|
||||
{
|
||||
channels: {
|
||||
discord: {
|
||||
allowFrom: ["123"],
|
||||
accounts: {
|
||||
alerts: {
|
||||
token: "discord-token",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
"open",
|
||||
"alerts",
|
||||
);
|
||||
|
||||
expect(next?.channels?.discord?.dmPolicy).toBeUndefined();
|
||||
expect(next?.channels?.discord?.accounts?.alerts?.dmPolicy).toBe("open");
|
||||
expect(next?.channels?.discord?.accounts?.alerts?.allowFrom).toEqual(["123", "*"]);
|
||||
name: "Discord named accounts",
|
||||
channel: "discord",
|
||||
accountId: "alerts",
|
||||
accountConfig: { token: "discord-token" },
|
||||
inheritedAllowFrom: ["123"],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
createStartAccountContext,
|
||||
expectLifecyclePatch,
|
||||
expectPendingUntilAbort,
|
||||
installChannelDmPolicyContractSuite,
|
||||
startAccountAndTrackLifecycle,
|
||||
} from "openclaw/plugin-sdk/channel-test-helpers";
|
||||
import {
|
||||
@@ -252,25 +253,18 @@ describe("googlechat setup", () => {
|
||||
expect(result.cfg.channels?.googlechat?.audience).toBe("https://example.com/googlechat");
|
||||
});
|
||||
|
||||
it("reads the named-account DM policy instead of the channel root", () => {
|
||||
expect(
|
||||
googlechatSetupWizard.dmPolicy?.getCurrent(
|
||||
{
|
||||
channels: {
|
||||
googlechat: {
|
||||
dmPolicy: "disabled",
|
||||
accounts: {
|
||||
alerts: {
|
||||
serviceAccount: { client_email: "bot@example.com" },
|
||||
dmPolicy: "allowlist",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
"alerts",
|
||||
),
|
||||
).toBe("allowlist");
|
||||
installChannelDmPolicyContractSuite({
|
||||
dmPolicy: googlechatSetupWizard.dmPolicy!,
|
||||
cases: [
|
||||
{
|
||||
name: "Google Chat named accounts",
|
||||
channel: "googlechat",
|
||||
accountId: "alerts",
|
||||
accountConfig: { serviceAccount: { client_email: "bot@example.com" } },
|
||||
inheritedAllowFrom: ["users/123"],
|
||||
defaultAccount: {},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
it("reports configured state for the selected account instead of any account", async () => {
|
||||
@@ -318,40 +312,6 @@ describe("googlechat setup", () => {
|
||||
expect(status.configured).toBe(false);
|
||||
});
|
||||
|
||||
it("reports account-scoped config keys for named accounts", () => {
|
||||
expect(googlechatSetupWizard.dmPolicy?.resolveConfigKeys?.({}, "alerts")).toEqual({
|
||||
policyKey: "channels.googlechat.accounts.alerts.dmPolicy",
|
||||
allowFromKey: "channels.googlechat.accounts.alerts.allowFrom",
|
||||
});
|
||||
});
|
||||
|
||||
it("uses configured defaultAccount for omitted DM policy account context", () => {
|
||||
const cfg = {
|
||||
channels: {
|
||||
googlechat: {
|
||||
defaultAccount: "alerts",
|
||||
dmPolicy: "disabled",
|
||||
accounts: {
|
||||
alerts: {
|
||||
serviceAccount: { client_email: "bot@example.com" },
|
||||
dmPolicy: "allowlist",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
|
||||
expect(googlechatSetupWizard.dmPolicy?.getCurrent(cfg)).toBe("allowlist");
|
||||
expect(googlechatSetupWizard.dmPolicy?.resolveConfigKeys?.(cfg)).toEqual({
|
||||
policyKey: "channels.googlechat.accounts.alerts.dmPolicy",
|
||||
allowFromKey: "channels.googlechat.accounts.alerts.allowFrom",
|
||||
});
|
||||
|
||||
const next = googlechatSetupWizard.dmPolicy?.setPolicy(cfg, "open");
|
||||
expect(next?.channels?.googlechat?.dmPolicy).toBe("disabled");
|
||||
expect(next?.channels?.googlechat?.accounts?.alerts?.dmPolicy).toBe("open");
|
||||
});
|
||||
|
||||
it("uses configured defaultAccount for omitted allowFrom prompt context", async () => {
|
||||
const prompter = createTestWizardPrompter({
|
||||
note: vi.fn(async () => {}),
|
||||
@@ -380,29 +340,6 @@ describe("googlechat setup", () => {
|
||||
expect(next?.channels?.googlechat?.accounts?.alerts?.allowFrom).toEqual(["users/123456789"]);
|
||||
});
|
||||
|
||||
it('writes open DM policy to the named account and preserves inherited allowFrom with "*"', () => {
|
||||
const next = googlechatSetupWizard.dmPolicy?.setPolicy(
|
||||
{
|
||||
channels: {
|
||||
googlechat: {
|
||||
allowFrom: ["users/123"],
|
||||
accounts: {
|
||||
alerts: {
|
||||
serviceAccount: { client_email: "bot@example.com" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
"open",
|
||||
"alerts",
|
||||
);
|
||||
|
||||
expect(next?.channels?.googlechat?.dmPolicy).toBeUndefined();
|
||||
expect(next?.channels?.googlechat?.accounts?.alerts?.dmPolicy).toBe("open");
|
||||
expect(next?.channels?.googlechat?.accounts?.alerts?.allowFrom).toEqual(["users/123", "*"]);
|
||||
});
|
||||
|
||||
it("keeps startAccount pending until abort, then unregisters", async () => {
|
||||
const unregister = vi.fn();
|
||||
hoisted.startGoogleChatMonitor.mockResolvedValue(unregister);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
|
||||
// Imessage tests cover targets plugin behavior.
|
||||
import { installChannelDmPolicyContractSuite } from "openclaw/plugin-sdk/channel-test-helpers";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
resolveIMessageGroupRequireMention,
|
||||
@@ -254,86 +255,20 @@ describe("parseIMessageAllowFromEntries", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("reads the named-account DM policy instead of the channel root", () => {
|
||||
expect(
|
||||
imessageDmPolicy.getCurrent(
|
||||
{
|
||||
channels: {
|
||||
imessage: {
|
||||
dmPolicy: "disabled",
|
||||
accounts: {
|
||||
work: {
|
||||
cliPath: "imsg",
|
||||
dmPolicy: "allowlist",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"work",
|
||||
),
|
||||
).toBe("allowlist");
|
||||
});
|
||||
|
||||
it("reports account-scoped config keys for named accounts", () => {
|
||||
expect(imessageDmPolicy.resolveConfigKeys?.({ channels: { imessage: {} } }, "work")).toEqual({
|
||||
policyKey: "channels.imessage.accounts.work.dmPolicy",
|
||||
allowFromKey: "channels.imessage.accounts.work.allowFrom",
|
||||
});
|
||||
});
|
||||
|
||||
it('writes open policy state to the named account and stores inherited allowFrom with "*"', () => {
|
||||
const next = imessageDmPolicy.setPolicy(
|
||||
installChannelDmPolicyContractSuite({
|
||||
dmPolicy: imessageDmPolicy,
|
||||
cases: [
|
||||
{
|
||||
channels: {
|
||||
imessage: {
|
||||
allowFrom: ["+15555550123"],
|
||||
accounts: {
|
||||
work: {
|
||||
cliPath: "imsg",
|
||||
},
|
||||
},
|
||||
},
|
||||
name: "iMessage named accounts",
|
||||
channel: "imessage",
|
||||
accountId: "work",
|
||||
accountConfig: { cliPath: "imsg" },
|
||||
inheritedAllowFrom: ["+15555550123"],
|
||||
defaultAccount: {
|
||||
rootAllowFrom: ["+15555550123"],
|
||||
accountAllowFrom: ["chat_id:123"],
|
||||
},
|
||||
},
|
||||
"open",
|
||||
"work",
|
||||
);
|
||||
|
||||
expect(next.channels?.imessage?.dmPolicy).toBeUndefined();
|
||||
expect(next.channels?.imessage?.allowFrom).toEqual(["+15555550123"]);
|
||||
expect(next.channels?.imessage?.accounts?.work?.dmPolicy).toBe("open");
|
||||
expect(next.channels?.imessage?.accounts?.work?.allowFrom).toEqual(["+15555550123", "*"]);
|
||||
});
|
||||
|
||||
it("uses the configured default account for omitted-account DM policy reads, keys, and writes", () => {
|
||||
const cfg = {
|
||||
channels: {
|
||||
imessage: {
|
||||
allowFrom: ["+15555550123"],
|
||||
defaultAccount: "work",
|
||||
accounts: {
|
||||
work: {
|
||||
cliPath: "imsg",
|
||||
dmPolicy: "allowlist" as const,
|
||||
allowFrom: ["chat_id:123"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
expect(imessageDmPolicy.getCurrent(cfg)).toBe("allowlist");
|
||||
expect(imessageDmPolicy.resolveConfigKeys?.(cfg)).toEqual({
|
||||
policyKey: "channels.imessage.accounts.work.dmPolicy",
|
||||
allowFromKey: "channels.imessage.accounts.work.allowFrom",
|
||||
});
|
||||
|
||||
const next = imessageDmPolicy.setPolicy(cfg, "open");
|
||||
|
||||
expect(next.channels?.imessage?.dmPolicy).toBeUndefined();
|
||||
expect(next.channels?.imessage?.allowFrom).toEqual(["+15555550123"]);
|
||||
expect(next.channels?.imessage?.accounts?.work?.dmPolicy).toBe("open");
|
||||
expect(next.channels?.imessage?.accounts?.work?.allowFrom).toEqual(["chat_id:123", "*"]);
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
// Line tests cover setup surface plugin behavior.
|
||||
import { readFileSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import { createStartAccountContext } from "openclaw/plugin-sdk/channel-test-helpers";
|
||||
import {
|
||||
createStartAccountContext,
|
||||
installChannelDmPolicyContractSuite,
|
||||
} from "openclaw/plugin-sdk/channel-test-helpers";
|
||||
import {
|
||||
createPluginSetupWizardConfigure,
|
||||
createTestWizardPrompter,
|
||||
@@ -186,98 +189,18 @@ describe("line setup wizard", () => {
|
||||
expect(result.cfg.channels?.line?.channelSecret).toBe("line-secret");
|
||||
});
|
||||
|
||||
it("reads the named-account DM policy instead of the channel root", () => {
|
||||
expect(
|
||||
lineSetupWizard.dmPolicy?.getCurrent(
|
||||
{
|
||||
channels: {
|
||||
line: {
|
||||
dmPolicy: "disabled",
|
||||
accounts: {
|
||||
work: {
|
||||
channelAccessToken: "token",
|
||||
channelSecret: "secret",
|
||||
dmPolicy: "allowlist",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
"work",
|
||||
),
|
||||
).toBe("allowlist");
|
||||
});
|
||||
|
||||
it("reports account-scoped config keys for named accounts", () => {
|
||||
expect(lineSetupWizard.dmPolicy?.resolveConfigKeys?.({} as OpenClawConfig, "work")).toEqual({
|
||||
policyKey: "channels.line.accounts.work.dmPolicy",
|
||||
allowFromKey: "channels.line.accounts.work.allowFrom",
|
||||
});
|
||||
});
|
||||
|
||||
it("uses configured defaultAccount for omitted DM policy account context", () => {
|
||||
const cfg = {
|
||||
channels: {
|
||||
line: {
|
||||
defaultAccount: "work",
|
||||
dmPolicy: "disabled",
|
||||
allowFrom: ["Uroot"],
|
||||
accounts: {
|
||||
work: {
|
||||
channelAccessToken: "token",
|
||||
channelSecret: "secret",
|
||||
dmPolicy: "allowlist",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
|
||||
expect(lineSetupWizard.dmPolicy?.getCurrent(cfg)).toBe("allowlist");
|
||||
expect(lineSetupWizard.dmPolicy?.resolveConfigKeys?.(cfg)).toEqual({
|
||||
policyKey: "channels.line.accounts.work.dmPolicy",
|
||||
allowFromKey: "channels.line.accounts.work.allowFrom",
|
||||
});
|
||||
|
||||
const next = lineSetupWizard.dmPolicy?.setPolicy(cfg, "open");
|
||||
const workAccount = next?.channels?.line?.accounts?.work as
|
||||
| {
|
||||
dmPolicy?: string;
|
||||
}
|
||||
| undefined;
|
||||
expect(next?.channels?.line?.dmPolicy).toBe("disabled");
|
||||
expect(workAccount?.dmPolicy).toBe("open");
|
||||
});
|
||||
|
||||
it('writes open policy state to the named account and preserves inherited allowFrom with "*"', () => {
|
||||
const next = lineSetupWizard.dmPolicy?.setPolicy(
|
||||
installChannelDmPolicyContractSuite({
|
||||
dmPolicy: lineSetupWizard.dmPolicy!,
|
||||
cases: [
|
||||
{
|
||||
channels: {
|
||||
line: {
|
||||
allowFrom: ["Uroot"],
|
||||
accounts: {
|
||||
work: {
|
||||
channelAccessToken: "token",
|
||||
channelSecret: "secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
"open",
|
||||
"work",
|
||||
);
|
||||
|
||||
const workAccount = next?.channels?.line?.accounts?.work as
|
||||
| {
|
||||
dmPolicy?: string;
|
||||
allowFrom?: string[];
|
||||
}
|
||||
| undefined;
|
||||
expect(next?.channels?.line?.dmPolicy).toBeUndefined();
|
||||
expect(next?.channels?.line?.allowFrom).toEqual(["Uroot"]);
|
||||
expect(workAccount?.dmPolicy).toBe("open");
|
||||
expect(workAccount?.allowFrom).toEqual(["Uroot", "*"]);
|
||||
name: "LINE named accounts",
|
||||
channel: "line",
|
||||
accountId: "work",
|
||||
accountConfig: { channelAccessToken: "token", channelSecret: "secret" },
|
||||
inheritedAllowFrom: ["Uroot"],
|
||||
defaultAccount: { rootAllowFrom: ["Uroot"] },
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
it("uses configured defaultAccount for omitted setup configured state", async () => {
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
createMessageReceiptFromOutboundResults,
|
||||
verifyChannelMessageAdapterCapabilityProofs,
|
||||
} from "openclaw/plugin-sdk/channel-outbound";
|
||||
import { installChannelDmPolicyContractSuite } from "openclaw/plugin-sdk/channel-test-helpers";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
|
||||
import {
|
||||
createPluginSetupWizardStatus,
|
||||
@@ -1270,84 +1271,18 @@ describe("signal setup parsing", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("reads the named-account DM policy instead of the channel root", () => {
|
||||
expect(
|
||||
signalDmPolicy.getCurrent(
|
||||
{
|
||||
channels: {
|
||||
signal: {
|
||||
dmPolicy: "disabled",
|
||||
accounts: {
|
||||
work: {
|
||||
account: "+15555550123",
|
||||
dmPolicy: "allowlist",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"work",
|
||||
),
|
||||
).toBe("allowlist");
|
||||
});
|
||||
|
||||
it("reports account-scoped config keys for named accounts", () => {
|
||||
expect(signalDmPolicy.resolveConfigKeys?.({ channels: { signal: {} } }, "work")).toEqual({
|
||||
policyKey: "channels.signal.accounts.work.dmPolicy",
|
||||
allowFromKey: "channels.signal.accounts.work.allowFrom",
|
||||
});
|
||||
});
|
||||
|
||||
it("uses configured defaultAccount for omitted DM policy account context", () => {
|
||||
const cfg: OpenClawConfig = {
|
||||
channels: {
|
||||
signal: {
|
||||
defaultAccount: "work",
|
||||
dmPolicy: "disabled",
|
||||
allowFrom: ["+15555550123"],
|
||||
accounts: {
|
||||
work: {
|
||||
account: "+15555550999",
|
||||
dmPolicy: "allowlist",
|
||||
},
|
||||
},
|
||||
},
|
||||
installChannelDmPolicyContractSuite({
|
||||
dmPolicy: signalDmPolicy,
|
||||
cases: [
|
||||
{
|
||||
name: "Signal named accounts",
|
||||
channel: "signal",
|
||||
accountId: "work",
|
||||
accountConfig: { account: "+15555550999" },
|
||||
inheritedAllowFrom: ["+15555550123"],
|
||||
defaultAccount: { rootAllowFrom: ["+15555550123"] },
|
||||
},
|
||||
};
|
||||
|
||||
expect(signalDmPolicy.getCurrent(cfg)).toBe("allowlist");
|
||||
expect(signalDmPolicy.resolveConfigKeys?.(cfg)).toEqual({
|
||||
policyKey: "channels.signal.accounts.work.dmPolicy",
|
||||
allowFromKey: "channels.signal.accounts.work.allowFrom",
|
||||
});
|
||||
|
||||
const next = signalDmPolicy.setPolicy(cfg, "open");
|
||||
expect(next.channels?.signal?.dmPolicy).toBe("disabled");
|
||||
expect(next.channels?.signal?.allowFrom).toEqual(["+15555550123"]);
|
||||
expect(next.channels?.signal?.accounts?.work?.dmPolicy).toBe("open");
|
||||
expect(next.channels?.signal?.accounts?.work?.allowFrom).toEqual(["+15555550123", "*"]);
|
||||
});
|
||||
|
||||
it('writes open policy state to the named account and stores inherited allowFrom with "*"', () => {
|
||||
const cfg: OpenClawConfig = {
|
||||
channels: {
|
||||
signal: {
|
||||
allowFrom: ["+15555550123"],
|
||||
accounts: {
|
||||
work: {
|
||||
account: "+15555550999",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const next = signalDmPolicy.setPolicy(cfg, "open", "work");
|
||||
|
||||
expect(next.channels?.signal?.dmPolicy).toBeUndefined();
|
||||
expect(next.channels?.signal?.allowFrom).toEqual(["+15555550123"]);
|
||||
expect(next.channels?.signal?.accounts?.work?.dmPolicy).toBe("open");
|
||||
expect(next.channels?.signal?.accounts?.work?.allowFrom).toEqual(["+15555550123", "*"]);
|
||||
],
|
||||
});
|
||||
});
|
||||
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { installChannelDmPolicyContractSuite } from "openclaw/plugin-sdk/channel-test-helpers";
|
||||
// Slack tests cover setup surface plugin behavior.
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
|
||||
import {
|
||||
@@ -427,57 +428,17 @@ describe("slackSetupWizard.prepare", () => {
|
||||
});
|
||||
|
||||
describe("slackSetupWizard.dmPolicy", () => {
|
||||
it("reads the named-account DM policy instead of the channel root", () => {
|
||||
expect(
|
||||
slackSetupWizard.dmPolicy?.getCurrent(
|
||||
{
|
||||
channels: {
|
||||
slack: {
|
||||
dmPolicy: "disabled",
|
||||
accounts: {
|
||||
alerts: {
|
||||
dmPolicy: "allowlist",
|
||||
botToken: "xoxb-alerts",
|
||||
appToken: "xapp-alerts",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
"alerts",
|
||||
),
|
||||
).toBe("allowlist");
|
||||
});
|
||||
|
||||
it("reports account-scoped config keys for named accounts", () => {
|
||||
expect(slackSetupWizard.dmPolicy?.resolveConfigKeys?.({}, "alerts")).toEqual({
|
||||
policyKey: "channels.slack.accounts.alerts.dmPolicy",
|
||||
allowFromKey: "channels.slack.accounts.alerts.allowFrom",
|
||||
});
|
||||
});
|
||||
|
||||
it('writes open policy state to the named account and preserves inherited allowFrom with "*"', () => {
|
||||
const next = slackSetupWizard.dmPolicy?.setPolicy(
|
||||
installChannelDmPolicyContractSuite({
|
||||
dmPolicy: slackSetupWizard.dmPolicy!,
|
||||
cases: [
|
||||
{
|
||||
channels: {
|
||||
slack: {
|
||||
allowFrom: ["U123"],
|
||||
accounts: {
|
||||
alerts: {
|
||||
botToken: "xoxb-alerts",
|
||||
appToken: "xapp-alerts",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
"open",
|
||||
"alerts",
|
||||
);
|
||||
|
||||
expect(next?.channels?.slack?.dmPolicy).toBeUndefined();
|
||||
expect(next?.channels?.slack?.accounts?.alerts?.dmPolicy).toBe("open");
|
||||
expect(next?.channels?.slack?.accounts?.alerts?.allowFrom).toEqual(["U123", "*"]);
|
||||
name: "Slack named accounts",
|
||||
channel: "slack",
|
||||
accountId: "alerts",
|
||||
accountConfig: { botToken: "xoxb-alerts", appToken: "xapp-alerts" },
|
||||
inheritedAllowFrom: ["U123"],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Telegram tests cover setup surface plugin behavior.
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
|
||||
import { installChannelDmPolicyContractSuite } from "openclaw/plugin-sdk/channel-test-helpers";
|
||||
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/setup";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { promptTelegramAllowFromForAccount, telegramSetupAdapter } from "./setup-core.js";
|
||||
@@ -98,81 +98,18 @@ describe("telegram DM access warning helpers", () => {
|
||||
});
|
||||
|
||||
describe("telegramSetupDmPolicy", () => {
|
||||
it("reads the named-account DM policy instead of the channel root", () => {
|
||||
expect(
|
||||
telegramSetupDmPolicy.getCurrent?.(
|
||||
{
|
||||
channels: {
|
||||
telegram: {
|
||||
dmPolicy: "disabled",
|
||||
accounts: {
|
||||
alerts: {
|
||||
dmPolicy: "allowlist",
|
||||
botToken: "tok",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"alerts",
|
||||
),
|
||||
).toBe("allowlist");
|
||||
});
|
||||
|
||||
it("reports account-scoped config keys for named accounts", () => {
|
||||
expect(telegramSetupDmPolicy.resolveConfigKeys?.({}, "alerts")).toEqual({
|
||||
policyKey: "channels.telegram.accounts.alerts.dmPolicy",
|
||||
allowFromKey: "channels.telegram.accounts.alerts.allowFrom",
|
||||
});
|
||||
});
|
||||
|
||||
it("uses configured defaultAccount for omitted DM policy account context", () => {
|
||||
const cfg: OpenClawConfig = {
|
||||
channels: {
|
||||
telegram: {
|
||||
defaultAccount: "alerts",
|
||||
dmPolicy: "disabled",
|
||||
allowFrom: ["123"],
|
||||
accounts: {
|
||||
alerts: {
|
||||
dmPolicy: "allowlist",
|
||||
botToken: "tok",
|
||||
},
|
||||
},
|
||||
},
|
||||
installChannelDmPolicyContractSuite({
|
||||
dmPolicy: telegramSetupDmPolicy,
|
||||
cases: [
|
||||
{
|
||||
name: "Telegram named accounts",
|
||||
channel: "telegram",
|
||||
accountId: "alerts",
|
||||
accountConfig: { botToken: "tok" },
|
||||
inheritedAllowFrom: ["123"],
|
||||
defaultAccount: { rootAllowFrom: ["123"] },
|
||||
},
|
||||
};
|
||||
|
||||
expect(telegramSetupDmPolicy.getCurrent?.(cfg)).toBe("allowlist");
|
||||
expect(telegramSetupDmPolicy.resolveConfigKeys?.(cfg)).toEqual({
|
||||
policyKey: "channels.telegram.accounts.alerts.dmPolicy",
|
||||
allowFromKey: "channels.telegram.accounts.alerts.allowFrom",
|
||||
});
|
||||
|
||||
const next = telegramSetupDmPolicy.setPolicy?.(cfg, "open");
|
||||
expect(next?.channels?.telegram?.dmPolicy).toBe("disabled");
|
||||
expect(next?.channels?.telegram?.accounts?.alerts?.dmPolicy).toBe("open");
|
||||
});
|
||||
|
||||
it('writes open policy state to the named account and preserves inherited allowFrom with "*"', () => {
|
||||
const cfg: OpenClawConfig = {
|
||||
channels: {
|
||||
telegram: {
|
||||
allowFrom: ["123"],
|
||||
accounts: {
|
||||
alerts: {
|
||||
botToken: "tok",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const next = telegramSetupDmPolicy.setPolicy?.(cfg, "open", "alerts");
|
||||
|
||||
expect(next?.channels?.telegram?.dmPolicy).toBeUndefined();
|
||||
expect(next?.channels?.telegram?.accounts?.alerts?.dmPolicy).toBe("open");
|
||||
expect(next?.channels?.telegram?.accounts?.alerts?.allowFrom).toEqual(["123", "*"]);
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -752,18 +752,9 @@
|
||||
"@openclaw/acp-core": [
|
||||
"../dist/plugin-sdk/packages/acp-core/src/index.d.ts"
|
||||
],
|
||||
"@openclaw/acp-core/normalize-text": [
|
||||
"../dist/plugin-sdk/packages/acp-core/src/normalize-text.d.ts"
|
||||
],
|
||||
"@openclaw/acp-core/meta": [
|
||||
"../dist/plugin-sdk/packages/acp-core/src/meta.d.ts"
|
||||
],
|
||||
"@openclaw/acp-core/numeric-options": [
|
||||
"../dist/plugin-sdk/packages/acp-core/src/numeric-options.d.ts"
|
||||
],
|
||||
"@openclaw/acp-core/record-shared": [
|
||||
"../dist/plugin-sdk/packages/acp-core/src/record-shared.d.ts"
|
||||
],
|
||||
"@openclaw/acp-core/session": [
|
||||
"../dist/plugin-sdk/packages/acp-core/src/session.d.ts"
|
||||
],
|
||||
|
||||
@@ -732,18 +732,9 @@
|
||||
"@openclaw/acp-core": [
|
||||
"../../dist/plugin-sdk/packages/acp-core/src/index.d.ts"
|
||||
],
|
||||
"@openclaw/acp-core/normalize-text": [
|
||||
"../../dist/plugin-sdk/packages/acp-core/src/normalize-text.d.ts"
|
||||
],
|
||||
"@openclaw/acp-core/meta": [
|
||||
"../../dist/plugin-sdk/packages/acp-core/src/meta.d.ts"
|
||||
],
|
||||
"@openclaw/acp-core/numeric-options": [
|
||||
"../../dist/plugin-sdk/packages/acp-core/src/numeric-options.d.ts"
|
||||
],
|
||||
"@openclaw/acp-core/record-shared": [
|
||||
"../../dist/plugin-sdk/packages/acp-core/src/record-shared.d.ts"
|
||||
],
|
||||
"@openclaw/acp-core/session": [
|
||||
"../../dist/plugin-sdk/packages/acp-core/src/session.d.ts"
|
||||
],
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Zalo tests cover setup surface plugin behavior.
|
||||
import { adaptScopedAccountAccessor } from "openclaw/plugin-sdk/channel-config-helpers";
|
||||
import { installChannelDmPolicyContractSuite } from "openclaw/plugin-sdk/channel-test-helpers";
|
||||
import {
|
||||
createPluginSetupWizardConfigure,
|
||||
createTestWizardPrompter,
|
||||
@@ -70,103 +71,18 @@ describe("zalo setup wizard", () => {
|
||||
expect(zaloConfig.webhookUrl).toBeUndefined();
|
||||
});
|
||||
|
||||
it("reads the named-account DM policy instead of the channel root", () => {
|
||||
expect(
|
||||
zaloDmPolicy.getCurrent(
|
||||
{
|
||||
channels: {
|
||||
zalo: {
|
||||
dmPolicy: "disabled",
|
||||
accounts: {
|
||||
work: {
|
||||
botToken: "12345689:abc-xyz",
|
||||
dmPolicy: "allowlist",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
"work",
|
||||
),
|
||||
).toBe("allowlist");
|
||||
});
|
||||
|
||||
it("reports account-scoped config keys for named accounts", () => {
|
||||
expect(zaloDmPolicy.resolveConfigKeys?.({} as OpenClawConfig, "work")).toEqual({
|
||||
policyKey: "channels.zalo.accounts.work.dmPolicy",
|
||||
allowFromKey: "channels.zalo.accounts.work.allowFrom",
|
||||
});
|
||||
});
|
||||
|
||||
it("uses configured defaultAccount for omitted DM policy account context", () => {
|
||||
const cfg = {
|
||||
channels: {
|
||||
zalo: {
|
||||
defaultAccount: "work",
|
||||
dmPolicy: "disabled",
|
||||
allowFrom: ["123456789"],
|
||||
accounts: {
|
||||
work: {
|
||||
botToken: "12345689:abc-xyz",
|
||||
dmPolicy: "allowlist",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
|
||||
expect(zaloDmPolicy.getCurrent(cfg)).toBe("allowlist");
|
||||
expect(zaloDmPolicy.resolveConfigKeys?.(cfg)).toEqual({
|
||||
policyKey: "channels.zalo.accounts.work.dmPolicy",
|
||||
allowFromKey: "channels.zalo.accounts.work.allowFrom",
|
||||
});
|
||||
|
||||
const next = zaloDmPolicy.setPolicy(cfg, "open");
|
||||
const zaloConfig = next.channels?.zalo;
|
||||
if (!zaloConfig) {
|
||||
throw new Error("expected Zalo config");
|
||||
}
|
||||
expect(zaloConfig.dmPolicy).toBe("disabled");
|
||||
const workAccount = next.channels?.zalo?.accounts?.work as
|
||||
| { dmPolicy?: string; allowFrom?: Array<string | number> }
|
||||
| undefined;
|
||||
if (!workAccount) {
|
||||
throw new Error("expected Zalo work account");
|
||||
}
|
||||
expect(workAccount.dmPolicy).toBe("open");
|
||||
});
|
||||
|
||||
it('writes open policy state to the named account and preserves inherited allowFrom with "*"', () => {
|
||||
const next = zaloDmPolicy.setPolicy(
|
||||
installChannelDmPolicyContractSuite({
|
||||
dmPolicy: zaloDmPolicy,
|
||||
cases: [
|
||||
{
|
||||
channels: {
|
||||
zalo: {
|
||||
allowFrom: ["123456789"],
|
||||
accounts: {
|
||||
work: {
|
||||
botToken: "12345689:abc-xyz",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
"open",
|
||||
"work",
|
||||
);
|
||||
|
||||
const zaloConfig = next.channels?.zalo;
|
||||
if (!zaloConfig) {
|
||||
throw new Error("expected Zalo config");
|
||||
}
|
||||
expect(zaloConfig.dmPolicy).toBeUndefined();
|
||||
const workAccount = next.channels?.zalo?.accounts?.work as
|
||||
| { dmPolicy?: string; allowFrom?: Array<string | number> }
|
||||
| undefined;
|
||||
if (!workAccount) {
|
||||
throw new Error("expected Zalo work account");
|
||||
}
|
||||
expect(workAccount.dmPolicy).toBe("open");
|
||||
expect(workAccount.allowFrom).toEqual(["123456789", "*"]);
|
||||
name: "Zalo named accounts",
|
||||
channel: "zalo",
|
||||
accountId: "work",
|
||||
accountConfig: { botToken: "12345689:abc-xyz" },
|
||||
inheritedAllowFrom: ["123456789"],
|
||||
defaultAccount: { rootAllowFrom: ["123456789"] },
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
it("uses configured defaultAccount for omitted setup configured state", async () => {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Zalouser tests cover setup surface plugin behavior.
|
||||
import { installChannelDmPolicyContractSuite } from "openclaw/plugin-sdk/channel-test-helpers";
|
||||
import {
|
||||
createPluginSetupWizardConfigure,
|
||||
createTestWizardPrompter,
|
||||
@@ -374,91 +375,18 @@ describe("zalouser setup wizard", () => {
|
||||
expect(result.cfg.plugins?.allow).toEqual(["telegram", "zalouser"]);
|
||||
});
|
||||
|
||||
it("reads the named-account DM policy instead of the channel root", () => {
|
||||
expect(
|
||||
zalouserSetupWizard.dmPolicy?.getCurrent(
|
||||
{
|
||||
channels: {
|
||||
zalouser: {
|
||||
dmPolicy: "disabled",
|
||||
accounts: {
|
||||
work: {
|
||||
profile: "work",
|
||||
dmPolicy: "allowlist",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
"work",
|
||||
),
|
||||
).toBe("allowlist");
|
||||
});
|
||||
|
||||
it("reports account-scoped config keys for named accounts", () => {
|
||||
expect(zalouserSetupWizard.dmPolicy?.resolveConfigKeys?.({} as OpenClawConfig, "work")).toEqual(
|
||||
installChannelDmPolicyContractSuite({
|
||||
dmPolicy: zalouserSetupWizard.dmPolicy!,
|
||||
cases: [
|
||||
{
|
||||
policyKey: "channels.zalouser.accounts.work.dmPolicy",
|
||||
allowFromKey: "channels.zalouser.accounts.work.allowFrom",
|
||||
name: "Zalo Personal named accounts",
|
||||
channel: "zalouser",
|
||||
accountId: "work",
|
||||
accountConfig: { profile: "work" },
|
||||
inheritedAllowFrom: ["123456789"],
|
||||
defaultAccount: { rootAllowFrom: ["123456789"] },
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("uses configured defaultAccount for omitted DM policy account context", () => {
|
||||
const cfg = {
|
||||
channels: {
|
||||
zalouser: {
|
||||
defaultAccount: "work",
|
||||
dmPolicy: "disabled",
|
||||
allowFrom: ["123456789"],
|
||||
accounts: {
|
||||
work: {
|
||||
dmPolicy: "allowlist",
|
||||
profile: "work-profile",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
|
||||
expect(zalouserSetupWizard.dmPolicy?.getCurrent(cfg)).toBe("allowlist");
|
||||
expect(zalouserSetupWizard.dmPolicy?.resolveConfigKeys?.(cfg)).toEqual({
|
||||
policyKey: "channels.zalouser.accounts.work.dmPolicy",
|
||||
allowFromKey: "channels.zalouser.accounts.work.allowFrom",
|
||||
});
|
||||
|
||||
const next = zalouserSetupWizard.dmPolicy?.setPolicy(cfg, "open");
|
||||
expect(next?.channels?.zalouser?.dmPolicy).toBe("disabled");
|
||||
const workAccount = next?.channels?.zalouser?.accounts?.work as
|
||||
| { dmPolicy?: string; allowFrom?: Array<string | number> }
|
||||
| undefined;
|
||||
expect(workAccount?.dmPolicy).toBe("open");
|
||||
});
|
||||
|
||||
it('writes open policy state to the named account and preserves inherited allowFrom with "*"', () => {
|
||||
const next = zalouserSetupWizard.dmPolicy?.setPolicy(
|
||||
{
|
||||
channels: {
|
||||
zalouser: {
|
||||
allowFrom: ["123456789"],
|
||||
accounts: {
|
||||
work: {
|
||||
profile: "work",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
"open",
|
||||
"work",
|
||||
);
|
||||
|
||||
expect(next?.channels?.zalouser?.dmPolicy).toBeUndefined();
|
||||
const workAccount = next?.channels?.zalouser?.accounts?.work as
|
||||
| { dmPolicy?: string; allowFrom?: Array<string | number> }
|
||||
| undefined;
|
||||
expect(workAccount?.dmPolicy).toBe("open");
|
||||
expect(workAccount?.allowFrom).toEqual(["123456789", "*"]);
|
||||
],
|
||||
});
|
||||
|
||||
it("shows the account-scoped current DM policy in quickstart notes", async () => {
|
||||
|
||||
@@ -14,26 +14,11 @@
|
||||
"import": "./dist/index.mjs",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"./normalize-text": {
|
||||
"types": "./dist/normalize-text.d.mts",
|
||||
"import": "./dist/normalize-text.mjs",
|
||||
"default": "./dist/normalize-text.mjs"
|
||||
},
|
||||
"./meta": {
|
||||
"types": "./dist/meta.d.mts",
|
||||
"import": "./dist/meta.mjs",
|
||||
"default": "./dist/meta.mjs"
|
||||
},
|
||||
"./numeric-options": {
|
||||
"types": "./dist/numeric-options.d.mts",
|
||||
"import": "./dist/numeric-options.mjs",
|
||||
"default": "./dist/numeric-options.mjs"
|
||||
},
|
||||
"./record-shared": {
|
||||
"types": "./dist/record-shared.d.mts",
|
||||
"import": "./dist/record-shared.mjs",
|
||||
"default": "./dist/record-shared.mjs"
|
||||
},
|
||||
"./session": {
|
||||
"types": "./dist/session.d.mts",
|
||||
"import": "./dist/session.mjs",
|
||||
@@ -84,6 +69,6 @@
|
||||
"@openclaw/normalization-core": "workspace:*"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsdown src/index.ts src/error-format.ts src/meta.ts src/normalize-text.ts src/numeric-options.ts src/record-shared.ts src/session.ts src/session-interaction-mode.ts src/session-lineage-meta.ts src/types.ts src/runtime/error-text.ts src/runtime/errors.ts src/runtime/session-identifiers.ts src/runtime/session-identity.ts src/runtime/types.ts --no-config --platform node --format esm --dts --out-dir dist --clean"
|
||||
"build": "tsdown src/index.ts src/error-format.ts src/meta.ts src/session.ts src/session-interaction-mode.ts src/session-lineage-meta.ts src/types.ts src/runtime/error-text.ts src/runtime/errors.ts src/runtime/session-identifiers.ts src/runtime/session-identity.ts src/runtime/types.ts --no-config --platform node --format esm --dts --out-dir dist --clean"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
|
||||
export * from "./error-format.js";
|
||||
export * from "./meta.js";
|
||||
export * from "./normalize-text.js";
|
||||
export * from "./numeric-options.js";
|
||||
export * from "./record-shared.js";
|
||||
export * from "./session-interaction-mode.js";
|
||||
export * from "./session-lineage-meta.js";
|
||||
export * from "./session.js";
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
// ACP text normalization facade shared with older imports.
|
||||
|
||||
export { normalizeOptionalString as normalizeText } from "@openclaw/normalization-core/string-coerce";
|
||||
@@ -1,11 +0,0 @@
|
||||
// ACP Core module implements numeric options behavior.
|
||||
import { resolveIntegerOption as resolveSharedIntegerOption } from "@openclaw/normalization-core/number-coercion";
|
||||
|
||||
/** Resolves ACP integer options through the shared normalization contract. */
|
||||
export function resolveIntegerOption(
|
||||
value: number | undefined,
|
||||
fallback: number,
|
||||
params: { min: number },
|
||||
): number {
|
||||
return resolveSharedIntegerOption(value, fallback, params);
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
// ACP record normalization facade shared with older imports.
|
||||
|
||||
export { asOptionalRecord as asRecord } from "@openclaw/normalization-core/record-coerce";
|
||||
@@ -1,6 +1,8 @@
|
||||
// ACP Core module implements session identifiers behavior.
|
||||
import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce";
|
||||
import { normalizeText } from "../normalize-text.js";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString as normalizeText,
|
||||
} from "@openclaw/normalization-core/string-coerce";
|
||||
import type { SessionAcpIdentity, SessionAcpMeta } from "../types.js";
|
||||
import { isSessionIdentityPending, resolveSessionIdentityFromMeta } from "./session-identity.js";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// ACP Core module implements session identity behavior.
|
||||
import { normalizeText } from "../normalize-text.js";
|
||||
import { normalizeOptionalString as normalizeText } from "@openclaw/normalization-core/string-coerce";
|
||||
import type { SessionAcpIdentity, SessionAcpIdentitySource, SessionAcpMeta } from "../types.js";
|
||||
import type { AcpRuntimeHandle, AcpRuntimeStatus } from "./types.js";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// ACP Core module implements session behavior.
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { resolveIntegerOption } from "./numeric-options.js";
|
||||
import { resolveIntegerOption } from "@openclaw/normalization-core/number-coercion";
|
||||
import type { AcpSession } from "./types.js";
|
||||
|
||||
export type AcpSessionStore = {
|
||||
|
||||
@@ -13,9 +13,7 @@
|
||||
},
|
||||
"exports": {
|
||||
"./runtime-core": "./src/runtime-core.ts",
|
||||
"./runtime-cli": "./src/runtime-cli.ts",
|
||||
"./runtime-files": "./src/runtime-files.ts",
|
||||
"./engine": "./src/engine.ts",
|
||||
"./engine-foundation": "./src/engine-foundation.ts",
|
||||
"./engine-storage": "./src/engine-storage.ts",
|
||||
"./engine-embeddings": "./src/engine-embeddings.ts",
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
// Aggregate workspace contract for the memory engine surface.
|
||||
// Keep focused subpaths preferred for new code.
|
||||
|
||||
export * from "./engine-foundation.js";
|
||||
export * from "./engine-storage.js";
|
||||
export * from "./engine-embeddings.js";
|
||||
export * from "./engine-qmd.js";
|
||||
@@ -1,19 +0,0 @@
|
||||
// Narrow CLI/runtime facade re-exported for memory host helpers.
|
||||
|
||||
export {
|
||||
colorize,
|
||||
defaultRuntime,
|
||||
formatDocsLink,
|
||||
formatErrorMessage,
|
||||
formatHelpExamples,
|
||||
isRich,
|
||||
isVerbose,
|
||||
resolveCommandSecretRefsViaGateway,
|
||||
setVerbose,
|
||||
shortenHomeInString,
|
||||
shortenHomePath,
|
||||
theme,
|
||||
withManager,
|
||||
withProgress,
|
||||
withProgressTotals,
|
||||
} from "./openclaw-runtime.js";
|
||||
@@ -36,11 +36,7 @@ export {
|
||||
} from "../../../../src/auto-reply/tokens.js";
|
||||
|
||||
// CLI/runtime/config helpers.
|
||||
export { formatErrorMessage, withManager } from "../../../../src/cli/cli-utils.js";
|
||||
export { resolveCommandSecretRefsViaGateway } from "../../../../src/cli/command-secret-gateway.js";
|
||||
export { formatHelpExamples } from "../../../../src/cli/help-format.js";
|
||||
export { parseDurationMs } from "../../../../src/cli/parse-duration.js";
|
||||
export { withProgress, withProgressTotals } from "../../../../src/cli/progress.js";
|
||||
export { parseNonNegativeByteSize } from "../../../../src/config/byte-size.js";
|
||||
export {
|
||||
getRuntimeConfig,
|
||||
@@ -102,7 +98,6 @@ export {
|
||||
} from "../../../../src/config/types.secrets.js";
|
||||
export type { SecretInput } from "../../../../src/config/types.secrets.js";
|
||||
export type { MemorySearchConfig } from "../../../../src/config/types.tools.js";
|
||||
export { isVerbose, setVerbose } from "../../../../src/globals.js";
|
||||
|
||||
// IO, network, and logging helpers.
|
||||
export { isExecCompletionEvent } from "../../../../src/infra/heartbeat-events-filter.js";
|
||||
@@ -160,13 +155,10 @@ export type {
|
||||
export type { OpenClawPluginApi } from "../../../../src/plugins/types.js";
|
||||
|
||||
// Shared session/text utilities.
|
||||
export { defaultRuntime } from "../../../../src/runtime.js";
|
||||
export { parseAgentSessionKey } from "../../../../src/routing/session-key.js";
|
||||
export { hasInterSessionUserProvenance } from "../../../../src/sessions/input-provenance.js";
|
||||
export { isCronRunSessionKey } from "../../../../src/sessions/session-key-utils.js";
|
||||
export { onSessionTranscriptUpdate } from "../../../../src/sessions/transcript-events.js";
|
||||
export { formatDocsLink } from "../../../terminal-core/src/links.js";
|
||||
export { colorize, isRich, theme } from "../../../terminal-core/src/theme.js";
|
||||
export { CHARS_PER_TOKEN_ESTIMATE, estimateStringChars } from "../../../../src/utils/cjk-chars.js";
|
||||
export { runTasksWithConcurrency } from "../../../../src/utils/run-with-concurrency.js";
|
||||
export { splitShellArgs } from "../../../../src/utils/shell-argv.js";
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
// Focused runtime contract for memory CLI/UI helpers.
|
||||
|
||||
export { formatErrorMessage, withManager } from "./host/openclaw-runtime-cli.js";
|
||||
export { formatHelpExamples } from "./host/openclaw-runtime-cli.js";
|
||||
export { resolveCommandSecretRefsViaGateway } from "./host/openclaw-runtime-cli.js";
|
||||
export { withProgress, withProgressTotals } from "./host/openclaw-runtime-cli.js";
|
||||
export { defaultRuntime } from "./host/openclaw-runtime-cli.js";
|
||||
export { formatDocsLink } from "./host/openclaw-runtime-cli.js";
|
||||
export { colorize, isRich, theme } from "./host/openclaw-runtime-cli.js";
|
||||
export { isVerbose, setVerbose } from "./host/openclaw-runtime-cli.js";
|
||||
export { shortenHomeInString, shortenHomePath } from "./host/openclaw-runtime-cli.js";
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"name": "@openclaw/web-content-core",
|
||||
"version": "0.0.0-private",
|
||||
"private": true,
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"type": "module",
|
||||
"exports": {
|
||||
"./provider-runtime-shared": {
|
||||
"types": "./dist/provider-runtime-shared.d.mts",
|
||||
"import": "./dist/provider-runtime-shared.mjs",
|
||||
"default": "./dist/provider-runtime-shared.mjs"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsdown src/provider-runtime-shared.ts --no-config --platform node --format esm --dts --out-dir dist --clean"
|
||||
}
|
||||
}
|
||||
Generated
-2
@@ -2311,8 +2311,6 @@ importers:
|
||||
specifier: workspace:*
|
||||
version: link:../normalization-core
|
||||
|
||||
packages/web-content-core: {}
|
||||
|
||||
packages/workboard-contract: {}
|
||||
|
||||
ui:
|
||||
|
||||
@@ -20,7 +20,6 @@ const RUN_NODE_PACKAGE_SOURCE_ROOTS = [
|
||||
"packages/retry/src",
|
||||
"packages/acp-core/src",
|
||||
"packages/terminal-core/src",
|
||||
"packages/web-content-core/src",
|
||||
"packages/net-policy/src",
|
||||
];
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** Classifies ACP tool permission requests into auto-approved and prompt-required risk buckets. */
|
||||
import { homedir } from "node:os";
|
||||
import path from "node:path";
|
||||
import { asRecord } from "@openclaw/acp-core/record-shared";
|
||||
import { asOptionalRecord as asRecord } from "@openclaw/normalization-core/record-coerce";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString,
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
/** Validation and normalization for ACP session runtime options and config controls. */
|
||||
import { isAbsolute } from "node:path";
|
||||
import { normalizeText } from "@openclaw/acp-core/normalize-text";
|
||||
import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString as normalizeText,
|
||||
} from "@openclaw/normalization-core/string-coerce";
|
||||
import type { AcpSessionRuntimeOptions, SessionAcpMeta } from "../../config/sessions/types.js";
|
||||
import { parseStrictPositiveInteger } from "../../infra/parse-finite-number.js";
|
||||
import { AcpRuntimeError } from "../runtime/errors.js";
|
||||
|
||||
export { normalizeText } from "@openclaw/acp-core/normalize-text";
|
||||
export { normalizeOptionalString as normalizeText } from "@openclaw/normalization-core/string-coerce";
|
||||
|
||||
const MAX_RUNTIME_MODE_LENGTH = 64;
|
||||
const MAX_MODEL_LENGTH = 200;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** Persistent/replayable ACP event ledger implementations for session rehydration. */
|
||||
import type { DatabaseSync } from "node:sqlite";
|
||||
import type { ContentBlock, SessionUpdate } from "@agentclientprotocol/sdk";
|
||||
import { resolveIntegerOption } from "@openclaw/acp-core/numeric-options";
|
||||
import { resolveIntegerOption } from "@openclaw/normalization-core/number-coercion";
|
||||
import {
|
||||
openOpenClawStateDatabase,
|
||||
type OpenClawStateDatabaseOptions,
|
||||
|
||||
@@ -5,8 +5,8 @@ import type {
|
||||
ToolCallLocation,
|
||||
ToolKind,
|
||||
} from "@agentclientprotocol/sdk";
|
||||
import { asRecord } from "@openclaw/acp-core/record-shared";
|
||||
import { hasHttpUrlPrefix } from "@openclaw/net-policy/url-protocol";
|
||||
import { asOptionalRecord as asRecord } from "@openclaw/normalization-core/record-coerce";
|
||||
import {
|
||||
hasNonEmptyString,
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
/** Types and normalization helpers for configured channel-to-ACP persistent bindings. */
|
||||
import { normalizeText } from "@openclaw/acp-core/normalize-text";
|
||||
import type { AcpRuntimeSessionMode } from "@openclaw/acp-core/runtime/types";
|
||||
import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce";
|
||||
import {
|
||||
normalizeOptionalLowercaseString,
|
||||
normalizeOptionalString as normalizeText,
|
||||
} from "@openclaw/normalization-core/string-coerce";
|
||||
import type { ChannelId } from "../channels/plugins/types.public.js";
|
||||
import { sha256HexPrefix } from "../infra/crypto-digest.js";
|
||||
import type { SessionBindingRecord } from "../infra/outbound/session-binding-service.js";
|
||||
import { normalizeAccountId, resolveAgentIdFromSessionKey } from "../routing/session-key.js";
|
||||
import { sanitizeAgentId } from "../routing/session-key.js";
|
||||
|
||||
export { normalizeText } from "@openclaw/acp-core/normalize-text";
|
||||
export { normalizeOptionalString as normalizeText } from "@openclaw/normalization-core/string-coerce";
|
||||
|
||||
export type ConfiguredAcpBindingChannel = ChannelId;
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
} from "@openclaw/normalization-core/string-coerce";
|
||||
import { truncateUtf16Safe } from "@openclaw/normalization-core/utf16-slice";
|
||||
import { Type } from "typebox";
|
||||
import { resolveWebProviderConfig } from "../../../packages/web-content-core/src/provider-runtime-shared.js";
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import { SsrFBlockedError, type LookupFn, type SsrFPolicy } from "../../infra/net/ssrf.js";
|
||||
import { logDebug } from "../../logger.js";
|
||||
@@ -22,6 +21,7 @@ import { wrapExternalContent, wrapWebContent } from "../../security/external-con
|
||||
import { createLazyImportLoader } from "../../shared/lazy-promise.js";
|
||||
import { isRecord } from "../../utils.js";
|
||||
import { extractReadableContent } from "../../web-fetch/content-extractors.runtime.js";
|
||||
import { resolveWebProviderConfig } from "../../web/provider-runtime-shared.js";
|
||||
import { stringEnum } from "../schema/string-enum.js";
|
||||
import { writePrivateTempFile } from "../sessions/tools/private-temp-file.js";
|
||||
import { formatFullOutputFooter } from "../sessions/tools/tool-contracts.js";
|
||||
|
||||
@@ -4,6 +4,7 @@ export { expectDirectoryIds, type DirectoryListFn } from "./test-helpers/directo
|
||||
export {
|
||||
expectChannelPluginContract,
|
||||
installChannelActionsContractSuite,
|
||||
installChannelDmPolicyContractSuite,
|
||||
installChannelPluginContractSuite,
|
||||
installChannelSetupContractSuite,
|
||||
installChannelStatusContractSuite,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Channel contract suites provide reusable expectations for channel plugin test coverage.
|
||||
import { expect, it } from "vitest";
|
||||
import type { ChannelSetupDmPolicy } from "../../channels/plugins/setup-wizard-types.js";
|
||||
import type {
|
||||
ChannelAccountSnapshot,
|
||||
ChannelAccountState,
|
||||
@@ -172,6 +173,142 @@ export function installChannelSetupContractSuite<
|
||||
}
|
||||
}
|
||||
|
||||
type ChannelDmPolicyConfig = {
|
||||
dmPolicy?: unknown;
|
||||
allowFrom?: unknown;
|
||||
accounts?: Record<string, ChannelDmPolicyConfig | undefined>;
|
||||
};
|
||||
|
||||
type ChannelDmPolicyContractCase = {
|
||||
name: string;
|
||||
channel: string;
|
||||
accountId: string;
|
||||
accountConfig: Record<string, unknown>;
|
||||
inheritedAllowFrom: ReadonlyArray<string | number>;
|
||||
defaultAccount?: {
|
||||
rootAllowFrom?: ReadonlyArray<string | number>;
|
||||
accountAllowFrom?: ReadonlyArray<string | number>;
|
||||
};
|
||||
};
|
||||
|
||||
function createDmPolicyContractConfig(params: {
|
||||
testCase: ChannelDmPolicyContractCase;
|
||||
mode: "read" | "write" | "default";
|
||||
}): OpenClawConfig {
|
||||
const { testCase } = params;
|
||||
const defaultAccount = params.mode === "default" ? testCase.defaultAccount : undefined;
|
||||
const account = {
|
||||
...testCase.accountConfig,
|
||||
...(params.mode === "write" ? {} : { dmPolicy: "allowlist" }),
|
||||
...(defaultAccount?.accountAllowFrom
|
||||
? { allowFrom: [...defaultAccount.accountAllowFrom] }
|
||||
: {}),
|
||||
};
|
||||
const rootAllowFrom =
|
||||
params.mode === "write" ? testCase.inheritedAllowFrom : defaultAccount?.rootAllowFrom;
|
||||
return {
|
||||
channels: {
|
||||
[testCase.channel]: {
|
||||
...(params.mode === "write" ? {} : { dmPolicy: "disabled" }),
|
||||
...(params.mode === "default" ? { defaultAccount: testCase.accountId } : {}),
|
||||
...(rootAllowFrom ? { allowFrom: [...rootAllowFrom] } : {}),
|
||||
accounts: { [testCase.accountId]: account },
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
}
|
||||
|
||||
function addExpectedWildcard(values: ReadonlyArray<string | number> | undefined) {
|
||||
return values?.includes("*") ? [...values] : [...(values ?? []), "*"];
|
||||
}
|
||||
|
||||
function resolveDmPolicyConfig(
|
||||
cfg: OpenClawConfig,
|
||||
channel: string,
|
||||
accountId: string,
|
||||
): { channel: ChannelDmPolicyConfig; account: ChannelDmPolicyConfig } {
|
||||
const channels = cfg.channels as Record<string, ChannelDmPolicyConfig | undefined> | undefined;
|
||||
const channelConfig = channels?.[channel];
|
||||
const accountConfig = channelConfig?.accounts?.[accountId];
|
||||
expect(channelConfig).toBeDefined();
|
||||
expect(accountConfig).toBeDefined();
|
||||
return { channel: channelConfig!, account: accountConfig! };
|
||||
}
|
||||
|
||||
function expectOpenDmPolicyPatch(params: {
|
||||
dmPolicy: ChannelSetupDmPolicy;
|
||||
cfg: OpenClawConfig;
|
||||
channel: string;
|
||||
accountId?: string;
|
||||
resolvedAccountId: string;
|
||||
expectedAllowFrom: readonly unknown[];
|
||||
}) {
|
||||
const before = resolveDmPolicyConfig(params.cfg, params.channel, params.resolvedAccountId);
|
||||
const beforeRootPolicy = before.channel.dmPolicy;
|
||||
const beforeRootAllowFrom = Array.isArray(before.channel.allowFrom)
|
||||
? [...before.channel.allowFrom]
|
||||
: before.channel.allowFrom;
|
||||
const next = params.dmPolicy.setPolicy(params.cfg, "open", params.accountId);
|
||||
const after = resolveDmPolicyConfig(next, params.channel, params.resolvedAccountId);
|
||||
|
||||
expect(after.channel.dmPolicy).toBe(beforeRootPolicy);
|
||||
expect(after.channel.allowFrom).toEqual(beforeRootAllowFrom);
|
||||
expect(after.account.dmPolicy).toBe("open");
|
||||
expect(after.account.allowFrom).toEqual(params.expectedAllowFrom);
|
||||
}
|
||||
|
||||
export function installChannelDmPolicyContractSuite(params: {
|
||||
dmPolicy: ChannelSetupDmPolicy;
|
||||
cases: readonly ChannelDmPolicyContractCase[];
|
||||
}) {
|
||||
for (const testCase of params.cases) {
|
||||
it(`dm policy contract: ${testCase.name} reads the named-account policy`, () => {
|
||||
expect(params.dmPolicy.channel).toBe(testCase.channel);
|
||||
const cfg = createDmPolicyContractConfig({ testCase, mode: "read" });
|
||||
expect(params.dmPolicy.getCurrent(cfg, testCase.accountId)).toBe("allowlist");
|
||||
});
|
||||
|
||||
it(`dm policy contract: ${testCase.name} reports account-scoped config keys`, () => {
|
||||
expect(params.dmPolicy.resolveConfigKeys?.({}, testCase.accountId)).toEqual({
|
||||
policyKey: `channels.${testCase.channel}.accounts.${testCase.accountId}.dmPolicy`,
|
||||
allowFromKey: `channels.${testCase.channel}.accounts.${testCase.accountId}.allowFrom`,
|
||||
});
|
||||
});
|
||||
|
||||
it(`dm policy contract: ${testCase.name} writes open policy with inherited allowFrom`, () => {
|
||||
expectOpenDmPolicyPatch({
|
||||
dmPolicy: params.dmPolicy,
|
||||
cfg: createDmPolicyContractConfig({ testCase, mode: "write" }),
|
||||
channel: testCase.channel,
|
||||
accountId: testCase.accountId,
|
||||
resolvedAccountId: testCase.accountId,
|
||||
expectedAllowFrom: addExpectedWildcard(testCase.inheritedAllowFrom),
|
||||
});
|
||||
});
|
||||
|
||||
const defaultAccount = testCase.defaultAccount;
|
||||
if (defaultAccount) {
|
||||
it(`dm policy contract: ${testCase.name} uses defaultAccount when accountId is omitted`, () => {
|
||||
const cfg = createDmPolicyContractConfig({ testCase, mode: "default" });
|
||||
expect(params.dmPolicy.getCurrent(cfg)).toBe("allowlist");
|
||||
expect(params.dmPolicy.resolveConfigKeys?.(cfg)).toEqual({
|
||||
policyKey: `channels.${testCase.channel}.accounts.${testCase.accountId}.dmPolicy`,
|
||||
allowFromKey: `channels.${testCase.channel}.accounts.${testCase.accountId}.allowFrom`,
|
||||
});
|
||||
expectOpenDmPolicyPatch({
|
||||
dmPolicy: params.dmPolicy,
|
||||
cfg,
|
||||
channel: testCase.channel,
|
||||
resolvedAccountId: testCase.accountId,
|
||||
expectedAllowFrom: addExpectedWildcard(
|
||||
defaultAccount.accountAllowFrom ?? defaultAccount.rootAllowFrom,
|
||||
),
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type ChannelStatusContractCase<Probe> = {
|
||||
name: string;
|
||||
cfg: OpenClawConfig;
|
||||
|
||||
@@ -45,14 +45,12 @@ type PackageJson = {
|
||||
devDependencies?: Record<string, string>;
|
||||
};
|
||||
const MEMORY_HOST_SDK_EXPORTS = [
|
||||
"./engine",
|
||||
"./engine-embeddings",
|
||||
"./engine-foundation",
|
||||
"./engine-qmd",
|
||||
"./engine-storage",
|
||||
"./multimodal",
|
||||
"./query",
|
||||
"./runtime-cli",
|
||||
"./runtime-core",
|
||||
"./runtime-files",
|
||||
"./secret",
|
||||
@@ -66,7 +64,6 @@ const MEMORY_HOST_SDK_ALLOWED_CORE_BRIDGE_FILES = [
|
||||
] as const;
|
||||
const MEMORY_HOST_SDK_RUNTIME_ADAPTER_FILES = [
|
||||
"packages/memory-host-sdk/src/host/openclaw-runtime-agent.ts",
|
||||
"packages/memory-host-sdk/src/host/openclaw-runtime-cli.ts",
|
||||
"packages/memory-host-sdk/src/host/openclaw-runtime-config.ts",
|
||||
"packages/memory-host-sdk/src/host/openclaw-runtime-io.ts",
|
||||
"packages/memory-host-sdk/src/host/openclaw-runtime-memory.ts",
|
||||
|
||||
@@ -764,7 +764,6 @@ describe("plugin-sdk subpath exports", () => {
|
||||
});
|
||||
expectSourceContract("memory-core-host-runtime-cli", {
|
||||
mentions: ["defaultRuntime", "withManager", "withProgressTotals"],
|
||||
omits: ['export * from "../../packages/memory-host-sdk/src/runtime-cli.js";'],
|
||||
});
|
||||
expectSourceContract("memory-core-host-runtime-files", {
|
||||
mentions: ["listMemoryFiles", "normalizeExtraMemoryPaths", "MemorySearchResult"],
|
||||
|
||||
@@ -1528,9 +1528,6 @@ describe("plugin sdk alias helpers", () => {
|
||||
expect(fs.realpathSync(aliases["@openclaw/media-generation-core/catalog"] ?? "")).toBe(
|
||||
fs.realpathSync(mediaGenerationCore.distFile),
|
||||
);
|
||||
expect(fs.realpathSync(aliases["@openclaw/acp-core/normalize-text"] ?? "")).toBe(
|
||||
fs.realpathSync(acpCoreRootDistFile),
|
||||
);
|
||||
expect(fs.realpathSync(aliases["@openclaw/normalization-core/record-coerce"] ?? "")).toBe(
|
||||
fs.realpathSync(normalizationCoreRootDistFile),
|
||||
);
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
/** Runtime provider selection and tool construction for the `web_fetch` tool. */
|
||||
import { createHash } from "node:crypto";
|
||||
import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce";
|
||||
import {
|
||||
hasWebProviderEntryCredential,
|
||||
providerRequiresCredential,
|
||||
readWebProviderEnvValue,
|
||||
resolveWebProviderConfig,
|
||||
resolveWebProviderDefinition,
|
||||
} from "../../packages/web-content-core/src/provider-runtime-shared.js";
|
||||
import type { OpenClawConfig } from "../config/types.js";
|
||||
import { logVerbose } from "../globals.js";
|
||||
import { getActivePluginRegistryVersion } from "../plugins/runtime.js";
|
||||
@@ -22,6 +15,13 @@ import {
|
||||
import { sortWebFetchProvidersForAutoDetect } from "../plugins/web-fetch-providers.shared.js";
|
||||
import { getActiveRuntimeWebToolsMetadata } from "../secrets/runtime-web-tools-state.js";
|
||||
import type { RuntimeWebFetchMetadata } from "../secrets/runtime-web-tools.types.js";
|
||||
import {
|
||||
hasWebProviderEntryCredential,
|
||||
providerRequiresCredential,
|
||||
readWebProviderEnvValue,
|
||||
resolveWebProviderConfig,
|
||||
resolveWebProviderDefinition,
|
||||
} from "../web/provider-runtime-shared.js";
|
||||
|
||||
// Runtime provider selection for the web_fetch tool. It resolves config,
|
||||
// credentials, runtime metadata, and sandbox-safe bundled provider scopes.
|
||||
|
||||
@@ -4,12 +4,6 @@ import {
|
||||
normalizeOptionalLowercaseString,
|
||||
} from "@openclaw/normalization-core/string-coerce";
|
||||
import { uniqueStrings } from "@openclaw/normalization-core/string-normalization";
|
||||
import {
|
||||
hasWebProviderEntryCredential,
|
||||
providerRequiresCredential,
|
||||
readWebProviderEnvValue,
|
||||
resolveWebProviderConfig,
|
||||
} from "../../packages/web-content-core/src/provider-runtime-shared.js";
|
||||
import { resolveDefaultAgentDir } from "../agents/agent-scope-config.js";
|
||||
import { hasAuthProfileForProvider } from "../agents/tools/model-config.helpers.js";
|
||||
import {
|
||||
@@ -28,6 +22,12 @@ import {
|
||||
import { sortWebSearchProvidersForAutoDetect } from "../plugins/web-search-providers.shared.js";
|
||||
import { getActiveRuntimeWebToolsMetadata } from "../secrets/runtime-web-tools-state.js";
|
||||
import type { RuntimeWebSearchMetadata } from "../secrets/runtime-web-tools.types.js";
|
||||
import {
|
||||
hasWebProviderEntryCredential,
|
||||
providerRequiresCredential,
|
||||
readWebProviderEnvValue,
|
||||
resolveWebProviderConfig,
|
||||
} from "../web/provider-runtime-shared.js";
|
||||
import { executeWebSearchCandidates } from "./runtime-execution.js";
|
||||
import type {
|
||||
ResolveWebSearchDefinitionParams,
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Web Content Core tests cover provider runtime shared behavior.
|
||||
// Web provider runtime tests cover shared config, credential, and definition resolution.
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
hasWebProviderEntryCredential,
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
// Web Content Core module implements provider runtime shared behavior.
|
||||
export type WebProviderConfigSource = {
|
||||
// Shared web provider config, credential, and definition resolution.
|
||||
type WebProviderConfigSource = {
|
||||
tools?: {
|
||||
web?: {
|
||||
search?: unknown;
|
||||
@@ -183,7 +183,6 @@ describe("oxlint config", () => {
|
||||
"packages/terminal-core/**/*.ts",
|
||||
"packages/normalization-core/**/*.ts",
|
||||
"packages/model-catalog-core/**/*.ts",
|
||||
"packages/web-content-core/**/*.ts",
|
||||
"packages/agent-core/**/*.ts",
|
||||
"packages/acp-core/**/*.ts",
|
||||
"packages/ai/**/*.ts",
|
||||
|
||||
@@ -180,9 +180,6 @@
|
||||
"@openclaw/workboard-contract": ["./packages/workboard-contract/src/index.ts"],
|
||||
"@openclaw/acp-core": ["./packages/acp-core/src/index.ts"],
|
||||
"@openclaw/acp-core/meta": ["./packages/acp-core/src/meta.ts"],
|
||||
"@openclaw/acp-core/numeric-options": ["./packages/acp-core/src/numeric-options.ts"],
|
||||
"@openclaw/acp-core/normalize-text": ["./packages/acp-core/src/normalize-text.ts"],
|
||||
"@openclaw/acp-core/record-shared": ["./packages/acp-core/src/record-shared.ts"],
|
||||
"@openclaw/acp-core/session": ["./packages/acp-core/src/session.ts"],
|
||||
"@openclaw/acp-core/session-interaction-mode": [
|
||||
"./packages/acp-core/src/session-interaction-mode.ts"
|
||||
@@ -247,10 +244,6 @@
|
||||
"@openclaw/net-policy/url-protocol": ["./packages/net-policy/src/url-protocol.ts"],
|
||||
"@openclaw/net-policy/url-userinfo": ["./packages/net-policy/src/url-userinfo.ts"],
|
||||
"@openclaw/net-policy/*": ["./packages/net-policy/src/*"],
|
||||
"@openclaw/web-content-core/provider-runtime-shared": [
|
||||
"./packages/web-content-core/src/provider-runtime-shared.ts"
|
||||
],
|
||||
"@openclaw/web-content-core/*": ["./packages/web-content-core/src/*"],
|
||||
"@openclaw/speech-core": ["./packages/speech-core/runtime-api.ts"],
|
||||
"@openclaw/speech-core/runtime-api": ["./packages/speech-core/runtime-api.ts"],
|
||||
"@openclaw/speech-core/speaker": ["./packages/speech-core/speaker.ts"],
|
||||
|
||||
@@ -565,9 +565,6 @@ const configs = [
|
||||
neverBundle: shouldExternalizeTerminalCoreDependency,
|
||||
},
|
||||
}),
|
||||
nodeWorkspacePackageBuildConfig("web-content-core", {
|
||||
outDir: "packages/web-content-core/dist",
|
||||
}),
|
||||
nodeWorkspacePackageBuildConfig("speech-core", {
|
||||
entry: buildSpeechCoreDistEntries(),
|
||||
deps: {
|
||||
|
||||
Reference in New Issue
Block a user