@nyte-ai/plugin 0.0.24 → 0.0.25-nightly.20261025.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD-PARTY-NOTICES.md +13 -5
- package/dist/chunks/bash-description-0ah30s12.js +33 -0
- package/dist/chunks/{bash-description-qnwggxq3.js → bash-description-1neewp76.js} +19 -8
- package/dist/chunks/bash-description-4cdbmar0.js +124 -0
- package/dist/chunks/bash-description-4h0hnsv4.js +68 -0
- package/dist/chunks/bash-description-5dpf5hpt.js +724 -0
- package/dist/chunks/bash-description-9gw9ets8.js +162 -0
- package/dist/chunks/bash-description-b78pre8c.js +147 -0
- package/dist/chunks/{bash-description-necnb2k7.js → bash-description-vg0xecwm.js} +17 -7
- package/dist/src/acp/connection.js +1 -1
- package/dist/src/acp/index.d.ts +3 -3
- package/dist/src/acp/index.js +1 -1
- package/dist/src/approvals/approvals.d.ts +16 -16
- package/dist/src/approvals/schema.d.ts +18 -18
- package/dist/src/bash-description.d.ts +1 -1
- package/dist/src/bash-description.js +3 -5
- package/dist/src/canvas/canvas-protocol.d.ts +12 -12
- package/dist/src/canvas/canvas.d.ts +12 -3
- package/dist/src/canvas/canvas.js +33 -11
- package/dist/src/canvas/schema.d.ts +48 -8
- package/dist/src/canvas/schema.js +5 -1
- package/dist/src/claude-code-sdk/index.d.ts +1 -1
- package/dist/src/claude-code-sdk/index.js +1 -0
- package/dist/src/client/notifications.d.ts +1 -1
- package/dist/src/client/presentation.d.ts +1 -27
- package/dist/src/client/presentation.js +1 -19
- package/dist/src/codemode.js +148 -41
- package/dist/src/core.d.ts +1 -1
- package/dist/src/question/question.d.ts +14 -14
- package/dist/src/question/schema.d.ts +23 -23
- package/dist/src/rename.d.ts +17 -32
- package/dist/src/rename.js +115 -48
- package/dist/src/subagents.d.ts +30 -0
- package/dist/src/subagents.js +323 -0
- package/dist/src/telemetry.d.ts +1 -1
- package/dist/src/tool-search.d.ts +49 -0
- package/dist/src/tool-search.js +14 -0
- package/dist/src/web/body.d.ts +3 -0
- package/dist/src/web/body.js +6 -0
- package/dist/src/web/fetch.d.ts +16 -0
- package/dist/src/web/fetch.js +8 -0
- package/dist/src/web/html-markdown.d.ts +9 -0
- package/dist/src/web/html-markdown.js +10 -0
- package/dist/src/web/index.d.ts +24 -0
- package/dist/src/web/index.js +93 -0
- package/dist/src/web/providers.d.ts +60 -0
- package/dist/src/web/providers.js +11 -0
- package/dist/src/web/search.d.ts +21 -0
- package/dist/src/web/search.js +6 -0
- package/package.json +17 -9
- package/dist/src/web-search.d.ts +0 -78
- package/dist/src/web-search.js +0 -219
|
@@ -48,24 +48,24 @@ export declare const TINTS: readonly ["blue", "pink", "orange", "teal", "red", "
|
|
|
48
48
|
* answers any other import of `nyte/canvas` with a positioned error.
|
|
49
49
|
*/
|
|
50
50
|
export declare const KIT: {
|
|
51
|
-
readonly Stack:
|
|
52
|
-
readonly Grid:
|
|
51
|
+
readonly Stack: '{ direction?: "row" | "column" = "column", gap?: 0 | 1 | 2 | 3 | 4 | 6 = 2 (×4 px), align?: "start" | "center" | "end" | "stretch", justify?: "start" | "center" | "end" | "between", wrap?: boolean, children }: flex layout';
|
|
52
|
+
readonly Grid: '{ columns?: number | "auto" = "auto", minWidth?: number = 160 (px, with "auto"), gap?: 0 | 1 | 2 | 3 | 4 | 6 = 2, children }: equal columns';
|
|
53
53
|
readonly Divider: "{}: a hairline";
|
|
54
54
|
readonly Heading: "{ level?: 1 | 2 | 3 = 2, children }";
|
|
55
|
-
readonly Text:
|
|
55
|
+
readonly Text: '{ size?: "xs" | "sm" | "base" | "lg", tone?: "primary" | "secondary" | "tertiary", weight?: "normal" | "medium" | "semibold", mono?: boolean, truncate?: boolean, align?: "start" | "center" | "end", children }';
|
|
56
56
|
readonly Code: "{ block?: boolean, children: string }: monospace, inline or a block";
|
|
57
|
-
readonly Stat:
|
|
58
|
-
readonly Badge:
|
|
59
|
-
readonly Meter:
|
|
60
|
-
readonly Table:
|
|
61
|
-
readonly Callout:
|
|
57
|
+
readonly Stat: '{ label: string, value: ReactNode, detail?: ReactNode, tone?: "neutral" | "success" | "warning" | "danger" }: a labelled number';
|
|
58
|
+
readonly Badge: '{ tone?: "neutral" | "info" | "success" | "warning" | "danger", children }';
|
|
59
|
+
readonly Meter: '{ value: number, max?: number = 100, label?: string, tone?: "primary" | "success" | "warning" | "danger" = "primary" }: a thin filled bar with the value beside the label';
|
|
60
|
+
readonly Table: '{ columns: { key: string, label: ReactNode, align?: "start" | "end", width?: number | string }[], rows: Record<string, ReactNode>[], caption?: string }: rows are keyed by column key; a cell can hold a Sparkline or a Badge';
|
|
61
|
+
readonly Callout: '{ tone?: "info" | "success" | "warning" | "danger", title?: string, children }';
|
|
62
62
|
readonly Card: "{ title?: ReactNode, actions?: ReactNode, padding?: 0 | 2 | 3 | 4 = 4, children }: an elevated bordered surface";
|
|
63
63
|
readonly StackedBars: "{ label: string, series: { key: string, label: string, tint: Tint }[], buckets: { key: string, label: string, values: number[] }[], format: (value: number) => string, height?: number = 88, ticks?: number = 5 }: compact stacked bars without axes, a readout on pointer or arrow keys; the numbers live in the copy around it. Preferred beside a Stat or a heading figure";
|
|
64
64
|
readonly Sparkline: "{ values: number[], tint?: Tint, label?: string, width?: number = 72, height?: number = 20 }: a row's trend scaled to its own peak, for a Table cell beside the row's number";
|
|
65
|
-
readonly LineChart:
|
|
66
|
-
readonly BarChart:
|
|
65
|
+
readonly LineChart: '{ series: { id: string, data: { x: number | string, y: number }[], tint?: Tint }[], height?: number = 240, xFormat?: (x) => string, yFormat?: (y) => string, curve?: "linear" | "monotone" | "step", area?: boolean, legend?: boolean }: a full chart with axes and a readout';
|
|
66
|
+
readonly BarChart: '{ data: Record<string, number | string>[], keys: (string | { key: string, label?: string, tint?: Tint })[], indexBy: string, height?: number = 240, layout?: "vertical" | "horizontal", mode?: "grouped" | "stacked" = "stacked", valueFormat?: (value: number) => string, legend?: boolean }: a full chart with axes and a readout with the total';
|
|
67
67
|
readonly PieChart: "{ data: { id: string, value: number, label?: string, tint?: Tint }[], height?: number = 240, donut?: boolean, valueFormat?: (value: number) => string, legend?: boolean }";
|
|
68
|
-
readonly Button:
|
|
68
|
+
readonly Button: '{ variant?: "solid" | "outline" | "ghost", pill?: boolean, size?: "2xs" | "xs" | "sm" | "md" | "lg" | "xl", tone?: "neutral" | "primary" | "success" | "warning" | "danger", loading?: boolean, disabled?: boolean, onClick, children }';
|
|
69
69
|
readonly Tabs: "Tabs.Root { value?, defaultValue?, onValueChange? } > Tabs.List { children: Tabs.Tab { value, children }[] } + Tabs.Panel { value, children }";
|
|
70
70
|
readonly Select: "Select { value?, defaultValue?, onValueChange? } > SelectTrigger { children: <SelectValue /> } + SelectContent { children: SelectItem[] }";
|
|
71
71
|
readonly SelectTrigger: "see Select";
|
|
@@ -83,7 +83,7 @@ export declare const KIT: {
|
|
|
83
83
|
readonly Collapsible: "Collapsible.Root { open?, defaultOpen?, onOpenChange? } > Collapsible.Trigger { children } + Collapsible.Panel { children }";
|
|
84
84
|
readonly Kbd: "{ keys: string[] }";
|
|
85
85
|
readonly Spinner: "{}";
|
|
86
|
-
readonly useColorScheme:
|
|
86
|
+
readonly useColorScheme: '(): "light" | "dark"';
|
|
87
87
|
};
|
|
88
88
|
/** Every name `nyte/canvas` exports, in `KIT` order. */
|
|
89
89
|
export declare const KIT_EXPORTS: readonly string[];
|
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
import type { CanvasPreviewer } from "./canvas-preview.ts";
|
|
2
2
|
import type { Plugin } from "@nyte-ai/plugin/core";
|
|
3
3
|
export declare const canvas: import("@nyte-ai/core").PartDefinition<{
|
|
4
|
-
code: string;
|
|
5
4
|
runtime: number;
|
|
6
5
|
title: string;
|
|
7
|
-
error: string | null;
|
|
8
6
|
height: number | null;
|
|
7
|
+
code: string;
|
|
8
|
+
error: string | null;
|
|
9
|
+
revisions?: {
|
|
10
|
+
runtime: number;
|
|
11
|
+
title: string;
|
|
12
|
+
height: number | null;
|
|
13
|
+
number: number;
|
|
14
|
+
blob: import("@nyte-ai/schema").Id<"blob">;
|
|
15
|
+
at: number;
|
|
16
|
+
}[] | undefined;
|
|
9
17
|
}, {
|
|
10
18
|
replace: {
|
|
11
19
|
input: import("@nyte-ai/schema").Schema<{
|
|
12
|
-
code: string;
|
|
13
20
|
runtime: number;
|
|
14
21
|
title: string;
|
|
15
22
|
height: number | null;
|
|
23
|
+
code: string;
|
|
24
|
+
blob: import("@nyte-ai/schema").Id<"blob">;
|
|
16
25
|
}>;
|
|
17
26
|
};
|
|
18
27
|
report: {
|
|
@@ -18,8 +18,10 @@ import {
|
|
|
18
18
|
describeCanvasPreview2
|
|
19
19
|
} from "../../chunks/bash-description-yyd9jznf.js";
|
|
20
20
|
import {
|
|
21
|
+
CANVAS_RENDER_TOOL2,
|
|
22
|
+
CANVAS_REVISIONS_KEPT2,
|
|
21
23
|
canvas2
|
|
22
|
-
} from "../../chunks/bash-description-
|
|
24
|
+
} from "../../chunks/bash-description-1neewp76.js";
|
|
23
25
|
|
|
24
26
|
// src/canvas/canvas.ts
|
|
25
27
|
import { definePart, followedTrace, traced } from "@nyte-ai/core";
|
|
@@ -27,7 +29,24 @@ import { asId, standard } from "@nyte-ai/schema";
|
|
|
27
29
|
import { Type } from "typebox";
|
|
28
30
|
var handlers = {
|
|
29
31
|
async replace(input, context) {
|
|
30
|
-
const outcome = await context.part.update(() => ({
|
|
32
|
+
const outcome = await context.part.update((current) => ({
|
|
33
|
+
runtime: input.runtime,
|
|
34
|
+
title: input.title,
|
|
35
|
+
code: input.code,
|
|
36
|
+
height: input.height,
|
|
37
|
+
error: null,
|
|
38
|
+
revisions: [
|
|
39
|
+
...current.revisions ?? [],
|
|
40
|
+
{
|
|
41
|
+
number: (current.revisions?.at(-1)?.number ?? 1) + 1,
|
|
42
|
+
blob: input.blob,
|
|
43
|
+
runtime: input.runtime,
|
|
44
|
+
title: input.title,
|
|
45
|
+
height: input.height,
|
|
46
|
+
at: Date.now()
|
|
47
|
+
}
|
|
48
|
+
].slice(-CANVAS_REVISIONS_KEPT2)
|
|
49
|
+
}));
|
|
31
50
|
if (outcome.kind !== "updated")
|
|
32
51
|
throw new Error(`The canvas could not be replaced: ${outcome.kind}.`);
|
|
33
52
|
},
|
|
@@ -99,7 +118,7 @@ ${describeErrors(compiled.errors)}`);
|
|
|
99
118
|
var PREVIEW_FIRST = "Before rendering, call `canvas_preview` with the same `source` and `files`: it shows you the canvas and its errors, console and height without the user seeing it. Fix what it shows, then render once.";
|
|
100
119
|
function renderTool(previewing) {
|
|
101
120
|
return {
|
|
102
|
-
name:
|
|
121
|
+
name: CANVAS_RENDER_TOOL2,
|
|
103
122
|
description: previewing ? `${PREVIEW_FIRST}
|
|
104
123
|
|
|
105
124
|
${CANVAS_DESCRIPTION}` : CANVAS_DESCRIPTION,
|
|
@@ -113,15 +132,18 @@ ${CANVAS_DESCRIPTION}` : CANVAS_DESCRIPTION,
|
|
|
113
132
|
replay: "safe",
|
|
114
133
|
async execute(args, invocation) {
|
|
115
134
|
const compiled = await compile(args, invocation);
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
height: args.height ?? null
|
|
121
|
-
};
|
|
135
|
+
const drawn = { runtime: compiled.runtime, title: args.title, height: args.height ?? null };
|
|
136
|
+
const blob = await invocation.env.files.upload(async function* () {
|
|
137
|
+
yield encoder.encode(compiled.code);
|
|
138
|
+
}());
|
|
122
139
|
if (args.canvas === undefined) {
|
|
123
140
|
const part = await invocation.session.parts.create(canvas, {
|
|
124
|
-
state: {
|
|
141
|
+
state: {
|
|
142
|
+
...drawn,
|
|
143
|
+
code: compiled.code,
|
|
144
|
+
error: null,
|
|
145
|
+
revisions: [{ number: 1, blob, ...drawn, at: Date.now() }]
|
|
146
|
+
},
|
|
125
147
|
placement: { kind: "transcript", role: "answer" }
|
|
126
148
|
});
|
|
127
149
|
return {
|
|
@@ -129,7 +151,7 @@ ${CANVAS_DESCRIPTION}` : CANVAS_DESCRIPTION,
|
|
|
129
151
|
parts: [part.id]
|
|
130
152
|
};
|
|
131
153
|
}
|
|
132
|
-
const outcome = await invocation.session.part(asId(args.canvas)).act("replace",
|
|
154
|
+
const outcome = await invocation.session.part(asId(args.canvas)).act("replace", { ...drawn, code: compiled.code, blob });
|
|
133
155
|
if (outcome.kind !== "ok")
|
|
134
156
|
throw new Error(`Canvas ${args.canvas} was not replaced: ${outcome.kind}.`);
|
|
135
157
|
return {
|
|
@@ -1,41 +1,81 @@
|
|
|
1
1
|
import type { Infer } from "@nyte-ai/schema";
|
|
2
|
+
/**
|
|
3
|
+
* The tool that renders a canvas and replaces one in place.
|
|
4
|
+
*
|
|
5
|
+
* @category plugins
|
|
6
|
+
* @since 0.1.0
|
|
7
|
+
*/
|
|
8
|
+
export declare const CANVAS_RENDER_TOOL = "canvas_render";
|
|
9
|
+
/**
|
|
10
|
+
* How many revisions a canvas lists; a replace past it drops the oldest.
|
|
11
|
+
*
|
|
12
|
+
* @category plugins
|
|
13
|
+
* @since 0.1.0
|
|
14
|
+
*/
|
|
15
|
+
export declare const CANVAS_REVISIONS_KEPT = 50;
|
|
2
16
|
declare const state: import("@nyte-ai/schema").Schema<{
|
|
3
|
-
code: string;
|
|
4
17
|
runtime: number;
|
|
5
18
|
title: string;
|
|
6
|
-
error: string | null;
|
|
7
19
|
height: number | null;
|
|
20
|
+
code: string;
|
|
21
|
+
error: string | null;
|
|
22
|
+
revisions?: {
|
|
23
|
+
runtime: number;
|
|
24
|
+
title: string;
|
|
25
|
+
height: number | null;
|
|
26
|
+
number: number;
|
|
27
|
+
blob: import("@nyte-ai/schema").Id<"blob">;
|
|
28
|
+
at: number;
|
|
29
|
+
}[] | undefined;
|
|
8
30
|
}>;
|
|
9
31
|
/**
|
|
10
32
|
* Returns a canvas part's state: the compiled module, the runtime it needs,
|
|
11
|
-
* its title, the agent's height hint
|
|
33
|
+
* its title, the agent's height hint, the last error a client reported, and
|
|
34
|
+
* its revisions, oldest first, the last one being the module itself.
|
|
12
35
|
*
|
|
13
36
|
* @category plugins
|
|
14
37
|
* @since 0.1.0
|
|
15
38
|
*/
|
|
16
39
|
export type CanvasState = Infer<typeof state>;
|
|
40
|
+
/**
|
|
41
|
+
* One revision of a canvas: its compiled module stored as a blob, with what
|
|
42
|
+
* drawing it needs besides the code.
|
|
43
|
+
*
|
|
44
|
+
* @category plugins
|
|
45
|
+
* @since 0.1.0
|
|
46
|
+
*/
|
|
47
|
+
export type CanvasRevision = NonNullable<CanvasState["revisions"]>[number];
|
|
17
48
|
/**
|
|
18
49
|
* A canvas part: a React module the agent wrote, compiled on the host and
|
|
19
50
|
* drawn by a client inside the sandboxed runtime shell. `replace` swaps the
|
|
20
|
-
* module in place; `report` records a load
|
|
21
|
-
* which the model reads in the fallback.
|
|
51
|
+
* module in place and lists it as the next revision; `report` records a load
|
|
52
|
+
* or render error a client saw, which the model reads in the fallback.
|
|
22
53
|
*
|
|
23
54
|
* @category plugins
|
|
24
55
|
* @since 0.1.0
|
|
25
56
|
*/
|
|
26
57
|
export declare const canvas: import("@nyte-ai/core").PartDefinition<{
|
|
27
|
-
code: string;
|
|
28
58
|
runtime: number;
|
|
29
59
|
title: string;
|
|
30
|
-
error: string | null;
|
|
31
60
|
height: number | null;
|
|
61
|
+
code: string;
|
|
62
|
+
error: string | null;
|
|
63
|
+
revisions?: {
|
|
64
|
+
runtime: number;
|
|
65
|
+
title: string;
|
|
66
|
+
height: number | null;
|
|
67
|
+
number: number;
|
|
68
|
+
blob: import("@nyte-ai/schema").Id<"blob">;
|
|
69
|
+
at: number;
|
|
70
|
+
}[] | undefined;
|
|
32
71
|
}, {
|
|
33
72
|
replace: {
|
|
34
73
|
input: import("@nyte-ai/schema").Schema<{
|
|
35
|
-
code: string;
|
|
36
74
|
runtime: number;
|
|
37
75
|
title: string;
|
|
38
76
|
height: number | null;
|
|
77
|
+
code: string;
|
|
78
|
+
blob: import("@nyte-ai/schema").Id<"blob">;
|
|
39
79
|
}>;
|
|
40
80
|
};
|
|
41
81
|
report: {
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
+
CANVAS_RENDER_TOOL2,
|
|
3
|
+
CANVAS_REVISIONS_KEPT2,
|
|
2
4
|
canvas2
|
|
3
|
-
} from "../../chunks/bash-description-
|
|
5
|
+
} from "../../chunks/bash-description-1neewp76.js";
|
|
4
6
|
import"../../chunks/bash-description-dnvgk30y.js";
|
|
5
7
|
import"../../chunks/bash-description-zfpm2rt0.js";
|
|
6
8
|
export {
|
|
9
|
+
CANVAS_RENDER_TOOL2 as CANVAS_RENDER_TOOL,
|
|
10
|
+
CANVAS_REVISIONS_KEPT2 as CANVAS_REVISIONS_KEPT,
|
|
7
11
|
canvas2 as canvas
|
|
8
12
|
};
|
|
@@ -20,7 +20,7 @@ export declare function claudeCodeSdk(start?: StartQuery): {
|
|
|
20
20
|
readonly contribute: import("@nyte-ai/core").Registries<"core">;
|
|
21
21
|
readonly storage: import("@nyte-ai/core").PluginStorage;
|
|
22
22
|
readonly signal: AbortSignal;
|
|
23
|
-
hook<N extends "
|
|
23
|
+
hook<N extends import("@nyte-ai/core").HookName<"core">>(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
|
|
24
24
|
report(issue: import("@nyte-ai/schema").ValidationIssue): void;
|
|
25
25
|
reload(): void;
|
|
26
26
|
} & {
|
|
@@ -22,7 +22,7 @@ declare const _default: {
|
|
|
22
22
|
readonly contribute: import("@nyte-ai/core").Registries<"client">;
|
|
23
23
|
readonly storage: import("@nyte-ai/core").PluginStorage;
|
|
24
24
|
readonly signal: AbortSignal;
|
|
25
|
-
hook<N extends "
|
|
25
|
+
hook<N extends import("@nyte-ai/core").HookName<"client">>(name: N, entry: import("@nyte-ai/core").HookEntry<"client", N>): import("@nyte-ai/schema").Disposer;
|
|
26
26
|
report(issue: import("@nyte-ai/schema").ValidationIssue): void;
|
|
27
27
|
reload(): void;
|
|
28
28
|
} & import("@nyte-ai/plugin/client").ClientApi;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { text, thinking } from "@nyte-ai/core";
|
|
2
2
|
import type { PartState } from "@nyte-ai/core";
|
|
3
|
-
import type { Execution, Failure, HeadInfo, Message, MessageSource, SessionInfo, ToolClass, ToolPartState, UserContent
|
|
3
|
+
import type { Execution, Failure, HeadInfo, Message, MessageSource, SessionInfo, ToolClass, ToolPartState, UserContent } from "@nyte-ai/schema";
|
|
4
4
|
/**
|
|
5
5
|
* A message the user sent, or one a child, job or action delivered for them.
|
|
6
6
|
*
|
|
@@ -92,32 +92,6 @@ export declare function readRawPart(message: PartMessage): RawPart;
|
|
|
92
92
|
* @category presentation
|
|
93
93
|
*/
|
|
94
94
|
export declare function showsReport(message: UserMessage): message is ReportMessage;
|
|
95
|
-
type PendingStatus = Extract<UserStatus, {
|
|
96
|
-
readonly kind: "pending";
|
|
97
|
-
}>;
|
|
98
|
-
/**
|
|
99
|
-
* A message that waits in the queue: unsent, or pending for a later turn. A pending steer sent
|
|
100
|
-
* while idle or joining the live run is never one.
|
|
101
|
-
*
|
|
102
|
-
* @category presentation
|
|
103
|
-
*/
|
|
104
|
-
export type QueuedMessage = UserMessage & {
|
|
105
|
-
readonly status: Extract<UserStatus, {
|
|
106
|
-
readonly kind: "unsent";
|
|
107
|
-
}> | (PendingStatus & {
|
|
108
|
-
readonly schedule: Exclude<PendingStatus["schedule"], {
|
|
109
|
-
readonly kind: "joined";
|
|
110
|
-
}>;
|
|
111
|
-
});
|
|
112
|
-
};
|
|
113
|
-
/**
|
|
114
|
-
* Whether a message waits in the queue rather than showing in the transcript. A retrying send
|
|
115
|
-
* always waits. Reports, joined steers and steers sent while idle stay in the transcript.
|
|
116
|
-
* Other messages wait only while a run is active.
|
|
117
|
-
*
|
|
118
|
-
* @category presentation
|
|
119
|
-
*/
|
|
120
|
-
export declare function waitsInQueue(message: UserMessage, running: boolean): message is QueuedMessage;
|
|
121
95
|
/**
|
|
122
96
|
* What a user message shows: an action's label in place of the prompt it sent.
|
|
123
97
|
*
|
|
@@ -21,23 +21,6 @@ function readRawPart(message) {
|
|
|
21
21
|
function showsReport(message) {
|
|
22
22
|
return message.source.kind === "child" || message.source.kind === "job";
|
|
23
23
|
}
|
|
24
|
-
function waitsInQueue(message, running) {
|
|
25
|
-
const { status } = message;
|
|
26
|
-
if (showsReport(message))
|
|
27
|
-
return false;
|
|
28
|
-
switch (status.kind) {
|
|
29
|
-
case "landed":
|
|
30
|
-
return false;
|
|
31
|
-
case "unsent":
|
|
32
|
-
return status.retrying !== null || running && message.delivery !== "steer";
|
|
33
|
-
case "pending":
|
|
34
|
-
return running && status.schedule.kind !== "joined" && !(message.delivery === "steer" && status.schedule.kind === "next-turn" && status.schedule.reason === "idle");
|
|
35
|
-
default: {
|
|
36
|
-
const _exhaustive = status;
|
|
37
|
-
return _exhaustive;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
24
|
function shownContent(message) {
|
|
42
25
|
return message.source.kind === "action" ? message.source.label : message.content;
|
|
43
26
|
}
|
|
@@ -386,6 +369,5 @@ export {
|
|
|
386
369
|
toolStatus,
|
|
387
370
|
toolSubject,
|
|
388
371
|
toolTitle,
|
|
389
|
-
toolVerbs
|
|
390
|
-
waitsInQueue
|
|
372
|
+
toolVerbs
|
|
391
373
|
};
|
package/dist/src/codemode.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_SEARCH_LIMIT2,
|
|
3
|
+
createToolSearchDocument2,
|
|
4
|
+
rankTools2
|
|
5
|
+
} from "../chunks/bash-description-b78pre8c.js";
|
|
6
|
+
|
|
1
7
|
// src/codemode.ts
|
|
2
8
|
import { CodemodeSandbox } from "@earendil-works/pi-codemode";
|
|
3
|
-
import { renderToolSample } from "@earendil-works/pi-codemode/declarations";
|
|
9
|
+
import { renderToolSample, toCodemodeIdentifier } from "@earendil-works/pi-codemode/declarations";
|
|
4
10
|
import { CODEMODE_SOURCE_GRAMMAR, parseCodemodeSource } from "@earendil-works/pi-codemode/source";
|
|
11
|
+
import { estimateTextTokens } from "@nyte-ai/ai/utils/estimate";
|
|
5
12
|
import { dev } from "@nyte-ai/core";
|
|
6
13
|
import { isJson, isJsonObject, SdkError, standard } from "@nyte-ai/schema";
|
|
7
14
|
import { Type } from "typebox";
|
|
@@ -9,8 +16,8 @@ var DESCRIPTION = `Run JavaScript that calls other tools. The input is raw JavaS
|
|
|
9
16
|
- \`await tools.<name>({ ...args })\` resolves to the tool's output, or its text, and rejects with an Error on failure.
|
|
10
17
|
- Optional first line: \`// @options: {"timeout_ms": 60000}\`
|
|
11
18
|
- \`text(value)\`, \`console.log(...)\` and \`return\` add output; \`store(key, value)\` and \`load(key)\` keep JSON values across codemode calls in this session.
|
|
12
|
-
- \`ALL_TOOLS\`, \`searchTools(query, { limit?, namespace? })\` and \`
|
|
13
|
-
var
|
|
19
|
+
- \`ALL_TOOLS\`, \`await searchTools(query, { limit?, namespace? })\`, \`await describeTool(name)\` and \`await describeNamespace(name)\` find unlisted tools, such as MCP tools, and their declarations.`;
|
|
20
|
+
var LISTING_TOKENS = 3000;
|
|
14
21
|
var parameters = standard(Type.Object({ code: Type.String({ description: "Raw JavaScript source." }) }));
|
|
15
22
|
function codemodePlugin(runtime) {
|
|
16
23
|
return {
|
|
@@ -18,32 +25,94 @@ function codemodePlugin(runtime) {
|
|
|
18
25
|
activate(api) {
|
|
19
26
|
api.contribute.tools.add(codemode(api, runtime));
|
|
20
27
|
api.contribute.prompt.add((draft, siblings) => {
|
|
21
|
-
const
|
|
22
|
-
if (
|
|
23
|
-
|
|
24
|
-
draft.set("codemode", {
|
|
25
|
-
id: "codemode",
|
|
26
|
-
order: 96,
|
|
27
|
-
text: [
|
|
28
|
-
"Tools you reach only from a codemode script, as `await tools.<name>(args)`; `describeTool(name)` inside a script returns a tool's arguments:",
|
|
29
|
-
...reachable
|
|
30
|
-
].join(`
|
|
31
|
-
`)
|
|
32
|
-
});
|
|
28
|
+
const text = listTools(siblings.tools.list());
|
|
29
|
+
if (text !== null)
|
|
30
|
+
draft.set("codemode", { id: "codemode", order: 96, text });
|
|
33
31
|
});
|
|
34
32
|
}
|
|
35
33
|
};
|
|
36
34
|
}
|
|
37
|
-
function
|
|
38
|
-
const
|
|
35
|
+
function listTools(definitions) {
|
|
36
|
+
const sections = definitions.flatMap((definition) => {
|
|
37
|
+
if (definition.exposure !== "code")
|
|
38
|
+
return [];
|
|
39
|
+
const inputSchema = toJsonSchema(definition.parameters, "input");
|
|
40
|
+
const outputSchema = definition.output === undefined ? { type: "string" } : toJsonSchema(definition.output, "output");
|
|
41
|
+
if (inputSchema === null || outputSchema === null)
|
|
42
|
+
return [];
|
|
43
|
+
const id = toCodemodeIdentifier(definition.name);
|
|
44
|
+
const sample = renderToolSample({
|
|
45
|
+
name: definition.name,
|
|
46
|
+
description: definition.description,
|
|
47
|
+
inputSchema,
|
|
48
|
+
outputSchema
|
|
49
|
+
}).trim();
|
|
50
|
+
const section = `### \`${id}\`${id === definition.name ? "" : ` (\`${definition.name}\`)`}
|
|
51
|
+
${sample}`;
|
|
52
|
+
return [
|
|
53
|
+
{
|
|
54
|
+
namespace: definition.namespace,
|
|
55
|
+
name: definition.name,
|
|
56
|
+
section,
|
|
57
|
+
cost: estimateTextTokens(section)
|
|
58
|
+
}
|
|
59
|
+
];
|
|
60
|
+
});
|
|
61
|
+
if (sections.length === 0)
|
|
62
|
+
return null;
|
|
63
|
+
const groups = [
|
|
64
|
+
...Map.groupBy(sections, (entry) => entry.namespace?.name ?? "").entries()
|
|
65
|
+
].toSorted((left, right) => left[0].localeCompare(right[0])).map((pair) => ({ namespace: pair[1][0]?.namespace, entries: pair[1] }));
|
|
66
|
+
const shown = selectListed(groups, LISTING_TOKENS);
|
|
67
|
+
return [
|
|
68
|
+
"Tools you reach only from a codemode script, as `await tools.<name>(args)`:",
|
|
69
|
+
...groups.flatMap((group) => {
|
|
70
|
+
const visible = group.entries.filter((entry) => shown.has(entry.name));
|
|
71
|
+
if (group.namespace === undefined)
|
|
72
|
+
return visible.map((entry) => entry.section);
|
|
73
|
+
const listing = visible.length === group.entries.length ? "" : visible.length === 0 ? " (tools not listed)" : " (some tools not listed)";
|
|
74
|
+
const description = group.namespace.description?.trim() ?? "";
|
|
75
|
+
return [
|
|
76
|
+
`## ${group.namespace.name}${listing}${description === "" ? "" : `
|
|
77
|
+
${description}`}`,
|
|
78
|
+
...visible.map((entry) => entry.section)
|
|
79
|
+
];
|
|
80
|
+
})
|
|
81
|
+
].join(`
|
|
82
|
+
|
|
39
83
|
`);
|
|
40
|
-
|
|
84
|
+
}
|
|
85
|
+
function selectListed(groups, budget) {
|
|
86
|
+
const queues = groups.map((group) => group.entries.toSorted((a, b) => a.cost - b.cost));
|
|
87
|
+
const shown = new Set;
|
|
88
|
+
let remaining = budget;
|
|
89
|
+
let active = queues.filter((queue) => queue.length > 0);
|
|
90
|
+
while (active.length > 0)
|
|
91
|
+
active = active.filter((queue) => {
|
|
92
|
+
const next = queue[0];
|
|
93
|
+
if (next === undefined || next.cost > remaining)
|
|
94
|
+
return false;
|
|
95
|
+
remaining -= next.cost;
|
|
96
|
+
shown.add(next.name);
|
|
97
|
+
queue.shift();
|
|
98
|
+
return queue.length > 0;
|
|
99
|
+
});
|
|
100
|
+
return shown;
|
|
101
|
+
}
|
|
102
|
+
function toJsonSchema(schema, direction) {
|
|
103
|
+
try {
|
|
104
|
+
const converted = schema["~standard"].jsonSchema[direction]({ target: "draft-2020-12" });
|
|
105
|
+
return isJson(converted) && isJsonObject(converted) ? converted : null;
|
|
106
|
+
} catch {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
41
109
|
}
|
|
42
110
|
function codemode(api, runtime) {
|
|
43
111
|
return {
|
|
44
112
|
name: "codemode",
|
|
45
113
|
description: DESCRIPTION,
|
|
46
114
|
parameters,
|
|
115
|
+
exposure: "model-only",
|
|
47
116
|
grammar: { kind: "lark", source: CODEMODE_SOURCE_GRAMMAR },
|
|
48
117
|
class: () => ({ kind: "custom", label: "Running a script" }),
|
|
49
118
|
effects: "none",
|
|
@@ -51,14 +120,24 @@ function codemode(api, runtime) {
|
|
|
51
120
|
replay: "never",
|
|
52
121
|
async execute(args, invocation) {
|
|
53
122
|
const { code, options } = parseCodemodeSource(args.code);
|
|
54
|
-
const callable = invocation.tools.list().filter((info) => info.
|
|
123
|
+
const callable = invocation.tools.list().filter((info) => info.exposure !== "model-only" && info.exposure !== "hidden");
|
|
55
124
|
const stored = await api.storage.get("store");
|
|
56
125
|
if (stored !== undefined && !isJsonObject(stored))
|
|
57
126
|
throw new SdkError("internal", "Codemode's stored values are not a JSON object.");
|
|
127
|
+
const namespaces = new Map(api.contribute.tools.list().flatMap((definition) => definition.namespace === undefined ? [] : [[definition.name, definition.namespace]]));
|
|
128
|
+
const samples = new Map(callable.map((info) => [
|
|
129
|
+
info.name,
|
|
130
|
+
renderToolSample({
|
|
131
|
+
name: info.name,
|
|
132
|
+
description: info.description,
|
|
133
|
+
inputSchema: info.parameters,
|
|
134
|
+
outputSchema: info.output ?? { type: "string" }
|
|
135
|
+
})
|
|
136
|
+
]));
|
|
58
137
|
const sandbox = new CodemodeSandbox({
|
|
59
138
|
...runtime,
|
|
60
|
-
tools: callable.map((info) => bridge(info, invocation)),
|
|
61
|
-
globals: discovery(callable),
|
|
139
|
+
tools: callable.map((info) => bridge(info, samples.get(info.name) ?? "", invocation)),
|
|
140
|
+
globals: discovery(callable, samples, namespaces),
|
|
62
141
|
timeoutMs: options.timeoutMs ?? 300000,
|
|
63
142
|
memoryLimitBytes: 256 * 1024 * 1024
|
|
64
143
|
});
|
|
@@ -102,11 +181,11 @@ ${calls(result)}`);
|
|
|
102
181
|
}
|
|
103
182
|
};
|
|
104
183
|
}
|
|
105
|
-
function bridge(info, invocation) {
|
|
184
|
+
function bridge(info, sample, invocation) {
|
|
106
185
|
let sequence = 0;
|
|
107
186
|
return {
|
|
108
187
|
name: info.name,
|
|
109
|
-
description:
|
|
188
|
+
description: sample,
|
|
110
189
|
inputSchema: info.parameters,
|
|
111
190
|
outputSchema: info.output ?? { type: "string" },
|
|
112
191
|
async execute(args, { signal }) {
|
|
@@ -121,42 +200,70 @@ function unwrapToolOutcome(outcome) {
|
|
|
121
200
|
`);
|
|
122
201
|
throw new Error(outcome.kind === "failed" ? outcome.message : outcome.kind === "rejected" ? `Rejected: ${outcome.reason}` : `The call was ${outcome.kind}.`);
|
|
123
202
|
}
|
|
124
|
-
function discovery(tools) {
|
|
203
|
+
function discovery(tools, samples, namespaces) {
|
|
125
204
|
return [
|
|
126
205
|
{
|
|
127
206
|
name: "searchTools",
|
|
128
207
|
spread: true,
|
|
129
208
|
execute(args) {
|
|
130
209
|
const [query, options] = Array.isArray(args) ? args : [];
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
210
|
+
if (typeof query !== "string")
|
|
211
|
+
throw new Error("searchTools() expects a query string");
|
|
212
|
+
const limit = isJsonObject(options) ? options.limit ?? null : null;
|
|
213
|
+
const namespace = isJsonObject(options) ? options.namespace ?? null : null;
|
|
214
|
+
if (limit !== null && (typeof limit !== "number" || !Number.isInteger(limit) || limit <= 0))
|
|
215
|
+
throw new Error("searchTools() limit must be a positive integer");
|
|
216
|
+
if (namespace !== null && typeof namespace !== "string")
|
|
217
|
+
throw new Error("searchTools() namespace must be a string");
|
|
218
|
+
const documents = tools.flatMap((info) => {
|
|
219
|
+
const found = namespaces.get(info.name);
|
|
220
|
+
if (namespace !== null && (found === undefined || !matchesNamespace(found, namespace)))
|
|
221
|
+
return [];
|
|
222
|
+
return [createToolSearchDocument2(info, found)];
|
|
223
|
+
});
|
|
224
|
+
return rankTools2(query, documents, limit ?? DEFAULT_SEARCH_LIMIT2).map((name) => ({
|
|
225
|
+
name: toCodemodeIdentifier(name),
|
|
226
|
+
description: samples.get(name) ?? ""
|
|
141
227
|
}));
|
|
142
228
|
}
|
|
143
229
|
},
|
|
144
230
|
{
|
|
145
231
|
name: "describeTool",
|
|
146
232
|
execute(name) {
|
|
147
|
-
|
|
233
|
+
if (typeof name !== "string")
|
|
234
|
+
throw new Error("describeTool() expects a tool name");
|
|
235
|
+
const info = tools.find((candidate) => candidate.name === name || toCodemodeIdentifier(candidate.name) === name);
|
|
148
236
|
if (info === undefined)
|
|
149
|
-
throw new Error(`No tool is named ${
|
|
150
|
-
return
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
237
|
+
throw new Error(`No tool is named ${name}.`);
|
|
238
|
+
return samples.get(info.name) ?? "";
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
name: "describeNamespace",
|
|
243
|
+
execute(name) {
|
|
244
|
+
if (typeof name !== "string")
|
|
245
|
+
throw new Error("describeNamespace() expects a namespace name");
|
|
246
|
+
const members = tools.filter((info) => {
|
|
247
|
+
const found = namespaces.get(info.name);
|
|
248
|
+
return found !== undefined && matchesNamespace(found, name);
|
|
155
249
|
});
|
|
250
|
+
const namespace = members[0] === undefined ? undefined : namespaces.get(members[0].name);
|
|
251
|
+
if (namespace === undefined)
|
|
252
|
+
throw new Error(`No namespace is named ${name}.`);
|
|
253
|
+
return {
|
|
254
|
+
name: namespace.name,
|
|
255
|
+
...namespace.description === undefined ? {} : { description: namespace.description },
|
|
256
|
+
...namespace.instructions === undefined ? {} : { instructions: namespace.instructions },
|
|
257
|
+
tools: members.map((info) => toCodemodeIdentifier(info.name))
|
|
258
|
+
};
|
|
156
259
|
}
|
|
157
260
|
}
|
|
158
261
|
];
|
|
159
262
|
}
|
|
263
|
+
function matchesNamespace(namespace, query) {
|
|
264
|
+
const id = toCodemodeIdentifier(query);
|
|
265
|
+
return [namespace.name, ...namespace.aliases ?? []].some((name) => name === query || toCodemodeIdentifier(name) === id);
|
|
266
|
+
}
|
|
160
267
|
function calls(result) {
|
|
161
268
|
return result.calls.length === 0 ? "No tool calls were made." : `Tool calls made before the failure (not undone): ${result.calls.map((call) => `${call.name} (${call.status})`).join(", ")}`;
|
|
162
269
|
}
|
package/dist/src/core.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { HookEntry as SideHookEntry, HookHandler as SideHookHandler, HookName as SideHookName, Plugin as CorePlugin, PluginApi as CorePluginApi } from "@nyte-ai/core";
|
|
2
2
|
export { branchSummary, compaction, definePart, isPart, text, thinking, tool } from "@nyte-ai/core";
|
|
3
|
-
export type { ActionContext, Agent, Command, Durable, HookTable, ModelContextPolicy, Part, PartDefinition, PartState, PromptSection, Setting, SettingDefinition, Skill, ToolDefinition, ToolInvocation, } from "@nyte-ai/core";
|
|
3
|
+
export type { ActionContext, Agent, Command, Durable, HookTable, ModelContextPolicy, Part, PartDefinition, PartState, PromptSection, SearchProvider, SearchResult, Setting, SettingDefinition, Skill, ToolDefinition, ToolInvocation, } from "@nyte-ai/core";
|
|
4
4
|
export type { CompactionPlan, Decision, ModelRequest, Submission, ToolCall, Transcript, } from "@nyte-ai/schema";
|
|
5
5
|
/**
|
|
6
6
|
* A core plugin: per session on the host, with tools, prompt sections,
|