style: format assistant custom widget files
This commit is contained in:
1 parent
288bbcff98
commit
135cd928ba
10 files changed
+33
-28
No files matched your search
@@ -28,7 +28,14 @@ The object key `default` is the required source ID; `default` is not a property
|
||||
"requests": {
|
||||
"summary": { "path": "/summary" },
|
||||
"search": { "trigger": "manual", "path": "/search", "query": { "q": { "$param": "query" } } },
|
||||
"create": { "kind": "action", "method": "POST", "path": "/items", "body": { "id": { "$param": "id" } }, "confirmation": "Create this item?", "invalidates": ["search"] }
|
||||
"create": {
|
||||
"kind": "action",
|
||||
"method": "POST",
|
||||
"path": "/items",
|
||||
"body": { "id": { "$param": "id" } },
|
||||
"confirmation": "Create this item?",
|
||||
"invalidates": ["search"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -76,7 +76,11 @@ describe("repairAssistantToolInput", () => {
|
||||
});
|
||||
|
||||
test.each([
|
||||
["customWidget_previewQuery", { previewId: "preview-1", requestId: "search" }, { sessionId: "preview-1", requestId: "search" }],
|
||||
[
|
||||
"customWidget_previewQuery",
|
||||
{ previewId: "preview-1", requestId: "search" },
|
||||
{ sessionId: "preview-1", requestId: "search" },
|
||||
],
|
||||
[
|
||||
"customWidget_previewAction",
|
||||
{ previewSessionId: "preview-1", requestId: "requestMovie", params: { mediaId: 603 } },
|
||||
|
||||
@@ -125,10 +125,7 @@ const repairCustomWidgetLifecycleInput = <T extends AssistantToolCallInput>(tool
|
||||
return null;
|
||||
}
|
||||
if (typeof input !== "object" || input === null || Array.isArray(input)) return null;
|
||||
const normalized = normalizeCustomWidgetLifecycleToolInput(
|
||||
toolCall.toolName,
|
||||
input as Record<string, unknown>,
|
||||
);
|
||||
const normalized = normalizeCustomWidgetLifecycleToolInput(toolCall.toolName, input as Record<string, unknown>);
|
||||
if (normalized === input) return null;
|
||||
return { ...toolCall, input: JSON.stringify(normalized) };
|
||||
};
|
||||
|
||||
@@ -101,12 +101,8 @@ export const createPreviewSession = (input: CreatePreviewSessionInput) => call((
|
||||
export const getPreviewSession = (id: string, userId: string) => call(() => getService().get(id, userId));
|
||||
export const setPreviewSessionLiveActions = (id: string, userId: string, enabled: boolean) =>
|
||||
call(() => getService().setLiveActions(id, userId, enabled));
|
||||
export const revisePreviewSessionTemplate = (
|
||||
id: string,
|
||||
userId: string,
|
||||
template: string,
|
||||
expectedRevision?: number,
|
||||
) => call(() => getService().reviseTemplate(id, userId, template, expectedRevision));
|
||||
export const revisePreviewSessionTemplate = (id: string, userId: string, template: string, expectedRevision?: number) =>
|
||||
call(() => getService().reviseTemplate(id, userId, template, expectedRevision));
|
||||
export const appendPreviewJournal = (
|
||||
session: CustomWidgetPreviewSession,
|
||||
entry: Omit<CustomWidgetPreviewJournalEntry, "id" | "sessionRevision" | "timestamp">,
|
||||
|
||||
@@ -110,7 +110,7 @@ describe("custom widget agent preview workflow", () => {
|
||||
},
|
||||
secrets: [],
|
||||
});
|
||||
const revisedTemplate = '<Stack><Text>{data.fixtures?.name}</Text><Badge>Ready</Badge></Stack>';
|
||||
const revisedTemplate = "<Stack><Text>{data.fixtures?.name}</Text><Badge>Ready</Badge></Stack>";
|
||||
|
||||
const revised = await caller.previewReviseTemplate({
|
||||
sessionId: preview.previewSession.id,
|
||||
|
||||
@@ -30,8 +30,7 @@ const harmlessCredentialSettings = new Set([
|
||||
|
||||
const commonCredentialLiteralPattern =
|
||||
/\b(?:sk|pk|rk)-(?:[A-Za-z0-9][A-Za-z0-9._-]{7,})\b|\b(?:sk_(?:live|test)|github_pat|glpat|gh[pousr]|hf_|xox[baprs])-?[A-Za-z0-9._-]{8,}\b|\b(?:AKIA|ASIA)[A-Z0-9]{16}\b|\bAIza[0-9A-Za-z_-]{20,}\b|\beyJ[A-Za-z0-9_-]{8,}\.eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/giu;
|
||||
const authorizationSchemePattern =
|
||||
/(^|[^A-Za-z0-9_-])(bearer|basic)([\s:_-]+)(["']?)([A-Za-z0-9._~+/%=-]{8,})/giu;
|
||||
const authorizationSchemePattern = /(^|[^A-Za-z0-9_-])(bearer|basic)([\s:_-]+)(["']?)([A-Za-z0-9._~+/%=-]{8,})/giu;
|
||||
const credentialAssignmentPattern =
|
||||
/\b(authorization|auth(?:entication)?(?:[ _-]?(?:tokens?|keys?|credentials?))?|credentials?|api[ _-]?keys?|passwords?|passwds?|secrets?|tokens?|access[ _-]?(?:tokens?|keys?)|refresh[ _-]?tokens?|client[ _-]?secrets?|private[ _-]?keys?|signing[ _-]?keys?)((?:["']?\s*[:=]\s*["']?))([^\s,;"'}<>]+)/giu;
|
||||
|
||||
|
||||
@@ -19,9 +19,7 @@ export function getScopedCustomJsxControlName(scopeId: string, name: string) {
|
||||
export function getInvalidCustomJsxPropValueReason(componentName: string, propName: string, value: unknown) {
|
||||
if (propName === "resetKey" && value !== null) {
|
||||
const scalar =
|
||||
typeof value === "string" ||
|
||||
typeof value === "boolean" ||
|
||||
(typeof value === "number" && Number.isFinite(value));
|
||||
typeof value === "string" || typeof value === "boolean" || (typeof value === "number" && Number.isFinite(value));
|
||||
if (!scalar) return "resetKey supports only a finite number, string, boolean, or null";
|
||||
}
|
||||
if (
|
||||
|
||||
@@ -14,7 +14,13 @@ export interface RefreshButtonProps {
|
||||
size?: string;
|
||||
}
|
||||
|
||||
export function RefreshButton({ requestId, label, color = "gray", variant = "subtle", size = "sm" }: RefreshButtonProps) {
|
||||
export function RefreshButton({
|
||||
requestId,
|
||||
label,
|
||||
color = "gray",
|
||||
variant = "subtle",
|
||||
size = "sm",
|
||||
}: RefreshButtonProps) {
|
||||
const runtime = useCustomWidgetRuntime();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const refresh = async () => {
|
||||
|
||||
@@ -228,7 +228,7 @@ describe("preview sessions", () => {
|
||||
const revised = await service.reviseTemplate(
|
||||
"session",
|
||||
"owner",
|
||||
'<Stack><Text>{data.data?.name}</Text><Badge>Ready</Badge></Stack>',
|
||||
"<Stack><Text>{data.data?.name}</Text><Badge>Ready</Badge></Stack>",
|
||||
0,
|
||||
);
|
||||
const session = await service.get("session", "owner");
|
||||
@@ -238,13 +238,11 @@ describe("preview sessions", () => {
|
||||
expect(session.sources).toEqual(original.sources);
|
||||
expect(session.requests).toEqual(original.requests);
|
||||
expect(session.optionDefinitions).toEqual(original.optionDefinitions);
|
||||
expect(await service.getJournal("session", "owner")).toEqual([
|
||||
expect.objectContaining({ sessionRevision: 0 }),
|
||||
]);
|
||||
expect(await service.getJournal("session", "owner")).toEqual([expect.objectContaining({ sessionRevision: 0 })]);
|
||||
await expect(service.reviseTemplate("session", "owner", session.template, 1)).rejects.toThrow("unchanged");
|
||||
await expect(
|
||||
service.reviseTemplate("session", "owner", "<Text>Stale edit</Text>", 0),
|
||||
).rejects.toMatchObject({ code: "CONFLICT" });
|
||||
await expect(service.reviseTemplate("session", "owner", "<Text>Stale edit</Text>", 0)).rejects.toMatchObject({
|
||||
code: "CONFLICT",
|
||||
});
|
||||
await expect(
|
||||
service.reviseTemplate("session", "owner", '<ActionButton requestId="missing">Run</ActionButton>', 1),
|
||||
).rejects.toMatchObject({ code: "BAD_REQUEST" });
|
||||
|
||||
@@ -91,7 +91,7 @@ describe("lean Custom Widget schema", () => {
|
||||
it("removes model-inserted zero-width spaces before JSX validation and persistence", () => {
|
||||
const candidate = customWidgetDefinitionSchema.parse({
|
||||
...CUSTOM_WIDGET_STARTER,
|
||||
template: '<Stack>\u200b<Text>Cafe\u0301 {1 ?? \u03040}</Text>\u200b</Stack>',
|
||||
template: "<Stack>\u200b<Text>Cafe\u0301 {1 ?? \u03040}</Text>\u200b</Stack>",
|
||||
});
|
||||
|
||||
expect(candidate.template).toBe("<Stack><Text>Café {1 ?? 0}</Text></Stack>");
|
||||
@@ -319,7 +319,7 @@ describe("lean Custom Widget schema", () => {
|
||||
customWidgetDefinitionSchema.safeParse({
|
||||
...CUSTOM_WIDGET_STARTER,
|
||||
template:
|
||||
'<Text>https://www.themoviedb.org/assets/2/v4/glyphicons/basic/glyphicons-basic-38-picture-grey-c8f8b4d9.svg</Text>',
|
||||
"<Text>https://www.themoviedb.org/assets/2/v4/glyphicons/basic/glyphicons-basic-38-picture-grey-c8f8b4d9.svg</Text>",
|
||||
}).success,
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user