mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 00:40:21 +00:00
refactor(tlon): share outbound target resolution
This commit is contained in:
@@ -7,7 +7,12 @@ import type {
|
|||||||
} from "openclaw/plugin-sdk/tlon";
|
} from "openclaw/plugin-sdk/tlon";
|
||||||
import { monitorTlonProvider } from "./monitor/index.js";
|
import { monitorTlonProvider } from "./monitor/index.js";
|
||||||
import { tlonSetupWizard } from "./setup-surface.js";
|
import { tlonSetupWizard } from "./setup-surface.js";
|
||||||
import { formatTargetHint, normalizeShip, parseTlonTarget } from "./targets.js";
|
import {
|
||||||
|
formatTargetHint,
|
||||||
|
normalizeShip,
|
||||||
|
parseTlonTarget,
|
||||||
|
resolveTlonOutboundTarget,
|
||||||
|
} from "./targets.js";
|
||||||
import { resolveTlonAccount } from "./types.js";
|
import { resolveTlonAccount } from "./types.js";
|
||||||
import { authenticate } from "./urbit/auth.js";
|
import { authenticate } from "./urbit/auth.js";
|
||||||
import { ssrfPolicyFromAllowPrivateNetwork } from "./urbit/context.js";
|
import { ssrfPolicyFromAllowPrivateNetwork } from "./urbit/context.js";
|
||||||
@@ -131,19 +136,7 @@ async function withHttpPokeAccountApi<T>(
|
|||||||
export const tlonRuntimeOutbound: ChannelOutboundAdapter = {
|
export const tlonRuntimeOutbound: ChannelOutboundAdapter = {
|
||||||
deliveryMode: "direct",
|
deliveryMode: "direct",
|
||||||
textChunkLimit: 10000,
|
textChunkLimit: 10000,
|
||||||
resolveTarget: ({ to }) => {
|
resolveTarget: ({ to }) => resolveTlonOutboundTarget(to),
|
||||||
const parsed = parseTlonTarget(to ?? "");
|
|
||||||
if (!parsed) {
|
|
||||||
return {
|
|
||||||
ok: false,
|
|
||||||
error: new Error(`Invalid Tlon target. Use ${formatTargetHint()}`),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (parsed.kind === "dm") {
|
|
||||||
return { ok: true, to: parsed.ship };
|
|
||||||
}
|
|
||||||
return { ok: true, to: parsed.nest };
|
|
||||||
},
|
|
||||||
sendText: async ({ cfg, to, text, accountId, replyToId, threadId }) => {
|
sendText: async ({ cfg, to, text, accountId, replyToId, threadId }) => {
|
||||||
const { account, parsed } = resolveOutboundContext({ cfg, accountId, to });
|
const { account, parsed } = resolveOutboundContext({ cfg, accountId, to });
|
||||||
return withHttpPokeAccountApi(account, async (api) => {
|
return withHttpPokeAccountApi(account, async (api) => {
|
||||||
|
|||||||
@@ -6,7 +6,12 @@ import {
|
|||||||
resolveTlonSetupConfigured,
|
resolveTlonSetupConfigured,
|
||||||
tlonSetupAdapter,
|
tlonSetupAdapter,
|
||||||
} from "./setup-core.js";
|
} from "./setup-core.js";
|
||||||
import { formatTargetHint, normalizeShip, parseTlonTarget } from "./targets.js";
|
import {
|
||||||
|
formatTargetHint,
|
||||||
|
normalizeShip,
|
||||||
|
parseTlonTarget,
|
||||||
|
resolveTlonOutboundTarget,
|
||||||
|
} from "./targets.js";
|
||||||
import { resolveTlonAccount, listTlonAccountIds } from "./types.js";
|
import { resolveTlonAccount, listTlonAccountIds } from "./types.js";
|
||||||
import { validateUrbitBaseUrl } from "./urbit/base-url.js";
|
import { validateUrbitBaseUrl } from "./urbit/base-url.js";
|
||||||
|
|
||||||
@@ -151,19 +156,7 @@ export const tlonPlugin: ChannelPlugin = {
|
|||||||
outbound: {
|
outbound: {
|
||||||
deliveryMode: "direct",
|
deliveryMode: "direct",
|
||||||
textChunkLimit: 10000,
|
textChunkLimit: 10000,
|
||||||
resolveTarget: ({ to }) => {
|
resolveTarget: ({ to }) => resolveTlonOutboundTarget(to),
|
||||||
const parsed = parseTlonTarget(to ?? "");
|
|
||||||
if (!parsed) {
|
|
||||||
return {
|
|
||||||
ok: false,
|
|
||||||
error: new Error(`Invalid Tlon target. Use ${formatTargetHint()}`),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (parsed.kind === "dm") {
|
|
||||||
return { ok: true, to: parsed.ship };
|
|
||||||
}
|
|
||||||
return { ok: true, to: parsed.nest };
|
|
||||||
},
|
|
||||||
sendText: async (params) =>
|
sendText: async (params) =>
|
||||||
await (
|
await (
|
||||||
await loadTlonChannelRuntime()
|
await loadTlonChannelRuntime()
|
||||||
|
|||||||
27
extensions/tlon/src/targets.test.ts
Normal file
27
extensions/tlon/src/targets.test.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { resolveTlonOutboundTarget } from "./targets.js";
|
||||||
|
|
||||||
|
describe("resolveTlonOutboundTarget", () => {
|
||||||
|
it("resolves dm targets to normalized ships", () => {
|
||||||
|
expect(resolveTlonOutboundTarget("dm/sampel-palnet")).toEqual({
|
||||||
|
ok: true,
|
||||||
|
to: "~sampel-palnet",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("resolves group targets to canonical chat nests", () => {
|
||||||
|
expect(resolveTlonOutboundTarget("group:host-ship/general")).toEqual({
|
||||||
|
ok: true,
|
||||||
|
to: "chat/~host-ship/general",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns a helpful error for invalid targets", () => {
|
||||||
|
const resolved = resolveTlonOutboundTarget("group:bad-target");
|
||||||
|
expect(resolved.ok).toBe(false);
|
||||||
|
if (resolved.ok) {
|
||||||
|
throw new Error("expected invalid target");
|
||||||
|
}
|
||||||
|
expect(resolved.error.message).toMatch(/invalid tlon target/i);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -84,6 +84,20 @@ export function parseTlonTarget(raw?: string | null): TlonTarget | null {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function resolveTlonOutboundTarget(to?: string | null) {
|
||||||
|
const parsed = parseTlonTarget(to ?? "");
|
||||||
|
if (!parsed) {
|
||||||
|
return {
|
||||||
|
ok: false as const,
|
||||||
|
error: new Error(`Invalid Tlon target. Use ${formatTargetHint()}`),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (parsed.kind === "dm") {
|
||||||
|
return { ok: true as const, to: parsed.ship };
|
||||||
|
}
|
||||||
|
return { ok: true as const, to: parsed.nest };
|
||||||
|
}
|
||||||
|
|
||||||
export function formatTargetHint(): string {
|
export function formatTargetHint(): string {
|
||||||
return "dm/~sampel-palnet | ~sampel-palnet | chat/~host-ship/channel | group:~host-ship/channel";
|
return "dm/~sampel-palnet | ~sampel-palnet | chat/~host-ship/channel | group:~host-ship/channel";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user