@nyte-ai/plugin 0.0.25-beta.1 → 0.0.25-nightly.20261101.40
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 +49 -32
- package/dist/chunks/bash-description-0ah30s12.js +33 -0
- package/dist/chunks/bash-description-4h0hnsv4.js +68 -0
- package/dist/chunks/{bash-description-dnvgk30y.js → bash-description-4rfavmha.js} +32 -1
- package/dist/chunks/bash-description-5dpf5hpt.js +724 -0
- package/dist/chunks/{bash-description-yyd9jznf.js → bash-description-94km1hm2.js} +1 -1
- package/dist/chunks/{bash-description-svrhh5a5.js → bash-description-99k8z2r7.js} +3 -2
- package/dist/chunks/bash-description-9gw9ets8.js +162 -0
- package/dist/chunks/{bash-description-h13r0byk.js → bash-description-axnga0jz.js} +3 -3
- package/dist/chunks/bash-description-b78pre8c.js +147 -0
- package/dist/chunks/{bash-description-ye3wk5r3.js → bash-description-bas41ptb.js} +6 -24
- package/dist/chunks/{bash-description-2v3g7rd9.js → bash-description-bj5yh7tr.js} +26 -64
- package/dist/chunks/{bash-description-6z2kgtyt.js → bash-description-bkhr9zrz.js} +4 -4
- package/dist/chunks/{bash-description-hg64tqf1.js → bash-description-f754ge33.js} +49 -3
- package/dist/chunks/{bash-description-zz15raxk.js → bash-description-ff18794t.js} +1 -1
- package/dist/chunks/{bash-description-wmcbg6fw.js → bash-description-g7gfy7nw.js} +1 -1
- package/dist/chunks/{bash-description-1neewp76.js → bash-description-hp4rb8k4.js} +4 -3
- package/dist/chunks/bash-description-myvnmtt2.js +125 -0
- package/dist/chunks/{bash-description-9nn3yp18.js → bash-description-q2v8wbn8.js} +9 -1
- package/dist/chunks/bash-description-qwyy182r.js +452 -0
- package/dist/chunks/bash-description-rxpx004v.js +295 -0
- package/dist/chunks/{bash-description-eqp7ap2w.js → bash-description-z1581a29.js} +23 -9
- package/dist/src/acp/connection.d.ts +3 -1
- package/dist/src/acp/connection.js +3 -3
- package/dist/src/acp/index.d.ts +7 -4
- package/dist/src/acp/index.js +41 -8
- package/dist/src/acp/registry.d.ts +9 -0
- package/dist/src/acp/registry.js +5 -3
- package/dist/src/acp/thread.js +2 -2
- package/dist/src/acp/transcript.js +2 -2
- package/dist/src/acp/translate.d.ts +10 -2
- package/dist/src/acp/translate.js +3 -1
- package/dist/src/approvals/approvals.d.ts +1 -1
- package/dist/src/approvals/approvals.js +2 -2
- package/dist/src/approvals/schema.d.ts +3 -3
- package/dist/src/approvals/schema.js +1 -1
- package/dist/src/browser-tools.js +8 -2
- package/dist/src/canvas/canvas-compile.js +2 -2
- package/dist/src/canvas/canvas-preview.js +2 -2
- package/dist/src/canvas/canvas-protocol.d.ts +46 -0
- package/dist/src/canvas/canvas-protocol.js +11 -1
- package/dist/src/canvas/canvas.d.ts +17 -3
- package/dist/src/canvas/canvas.js +75 -31
- package/dist/src/canvas/schema.d.ts +28 -7
- package/dist/src/canvas/schema.js +2 -2
- package/dist/src/claude-code-sdk/index.d.ts +0 -10
- package/dist/src/claude-code-sdk/index.js +19 -179
- package/dist/src/claude-code-sdk/session.d.ts +22 -23
- package/dist/src/claude-code-sdk/session.js +6 -3
- package/dist/src/claude-code-sdk/transcript.d.ts +0 -6
- package/dist/src/claude-code-sdk/transcript.js +2 -4
- package/dist/src/claude-code-sdk/translate.d.ts +1 -5
- package/dist/src/claude-code-sdk/translate.js +2 -8
- package/dist/src/client/mount.d.ts +4 -2
- package/dist/src/client/mount.js +3 -0
- package/dist/src/client/notifications.d.ts +12 -4
- package/dist/src/client/notifications.js +25 -10
- package/dist/src/client/presentation.d.ts +138 -8
- package/dist/src/client/presentation.js +86 -371
- package/dist/src/codemode.js +151 -46
- package/dist/src/core.d.ts +1 -1
- package/dist/src/question/client/questions-tui.js +3 -3
- package/dist/src/question/client/questions.js +3 -3
- package/dist/src/question/question.js +84 -5
- package/dist/src/question/schema.js +3 -3
- package/dist/src/rename.d.ts +7 -35
- 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/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 +16 -7
- package/dist/chunks/bash-description-3j77ss7y.js +0 -86
- package/dist/chunks/bash-description-wbe8w0te.js +0 -530
- package/dist/src/web-search.d.ts +0 -78
- package/dist/src/web-search.js +0 -219
package/dist/src/codemode.js
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
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";
|
|
5
|
-
import {
|
|
11
|
+
import { estimateTextTokens } from "@nyte-ai/ai/utils/estimate";
|
|
12
|
+
import { attachFile, dev } from "@nyte-ai/core";
|
|
6
13
|
import { isJson, isJsonObject, SdkError, standard } from "@nyte-ai/schema";
|
|
7
14
|
import { Type } from "typebox";
|
|
8
15
|
var DESCRIPTION = `Run JavaScript that calls other tools. The input is raw JavaScript (not JSON, no code fence), run as an async function body in a QuickJS sandbox: top-level \`await\` and \`return\` work. No Node, file system, network, or timers.
|
|
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
|
});
|
|
@@ -85,11 +164,9 @@ ${calls(result)}`);
|
|
|
85
164
|
if (item.type === "text")
|
|
86
165
|
content.push({ kind: "text", text: item.text });
|
|
87
166
|
else
|
|
88
|
-
content.push({
|
|
89
|
-
kind: "file",
|
|
90
|
-
blob: await invocation.env.files.upload(once(Uint8Array.fromBase64(item.data))),
|
|
167
|
+
content.push(await attachFile(invocation.env.files, once(Uint8Array.fromBase64(item.data)), {
|
|
91
168
|
mime: item.mimeType
|
|
92
|
-
});
|
|
169
|
+
}));
|
|
93
170
|
}
|
|
94
171
|
if (result.value !== undefined)
|
|
95
172
|
content.push({
|
|
@@ -102,11 +179,11 @@ ${calls(result)}`);
|
|
|
102
179
|
}
|
|
103
180
|
};
|
|
104
181
|
}
|
|
105
|
-
function bridge(info, invocation) {
|
|
182
|
+
function bridge(info, sample, invocation) {
|
|
106
183
|
let sequence = 0;
|
|
107
184
|
return {
|
|
108
185
|
name: info.name,
|
|
109
|
-
description:
|
|
186
|
+
description: sample,
|
|
110
187
|
inputSchema: info.parameters,
|
|
111
188
|
outputSchema: info.output ?? { type: "string" },
|
|
112
189
|
async execute(args, { signal }) {
|
|
@@ -121,42 +198,70 @@ function unwrapToolOutcome(outcome) {
|
|
|
121
198
|
`);
|
|
122
199
|
throw new Error(outcome.kind === "failed" ? outcome.message : outcome.kind === "rejected" ? `Rejected: ${outcome.reason}` : `The call was ${outcome.kind}.`);
|
|
123
200
|
}
|
|
124
|
-
function discovery(tools) {
|
|
201
|
+
function discovery(tools, samples, namespaces) {
|
|
125
202
|
return [
|
|
126
203
|
{
|
|
127
204
|
name: "searchTools",
|
|
128
205
|
spread: true,
|
|
129
206
|
execute(args) {
|
|
130
207
|
const [query, options] = Array.isArray(args) ? args : [];
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
208
|
+
if (typeof query !== "string")
|
|
209
|
+
throw new Error("searchTools() expects a query string");
|
|
210
|
+
const limit = isJsonObject(options) ? options.limit ?? null : null;
|
|
211
|
+
const namespace = isJsonObject(options) ? options.namespace ?? null : null;
|
|
212
|
+
if (limit !== null && (typeof limit !== "number" || !Number.isInteger(limit) || limit <= 0))
|
|
213
|
+
throw new Error("searchTools() limit must be a positive integer");
|
|
214
|
+
if (namespace !== null && typeof namespace !== "string")
|
|
215
|
+
throw new Error("searchTools() namespace must be a string");
|
|
216
|
+
const documents = tools.flatMap((info) => {
|
|
217
|
+
const found = namespaces.get(info.name);
|
|
218
|
+
if (namespace !== null && (found === undefined || !matchesNamespace(found, namespace)))
|
|
219
|
+
return [];
|
|
220
|
+
return [createToolSearchDocument2(info, found)];
|
|
221
|
+
});
|
|
222
|
+
return rankTools2(query, documents, limit ?? DEFAULT_SEARCH_LIMIT2).map((name) => ({
|
|
223
|
+
name: toCodemodeIdentifier(name),
|
|
224
|
+
description: samples.get(name) ?? ""
|
|
141
225
|
}));
|
|
142
226
|
}
|
|
143
227
|
},
|
|
144
228
|
{
|
|
145
229
|
name: "describeTool",
|
|
146
230
|
execute(name) {
|
|
147
|
-
|
|
231
|
+
if (typeof name !== "string")
|
|
232
|
+
throw new Error("describeTool() expects a tool name");
|
|
233
|
+
const info = tools.find((candidate) => candidate.name === name || toCodemodeIdentifier(candidate.name) === name);
|
|
148
234
|
if (info === undefined)
|
|
149
|
-
throw new Error(`No tool is named ${
|
|
150
|
-
return
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
235
|
+
throw new Error(`No tool is named ${name}.`);
|
|
236
|
+
return samples.get(info.name) ?? "";
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
name: "describeNamespace",
|
|
241
|
+
execute(name) {
|
|
242
|
+
if (typeof name !== "string")
|
|
243
|
+
throw new Error("describeNamespace() expects a namespace name");
|
|
244
|
+
const members = tools.filter((info) => {
|
|
245
|
+
const found = namespaces.get(info.name);
|
|
246
|
+
return found !== undefined && matchesNamespace(found, name);
|
|
155
247
|
});
|
|
248
|
+
const namespace = members[0] === undefined ? undefined : namespaces.get(members[0].name);
|
|
249
|
+
if (namespace === undefined)
|
|
250
|
+
throw new Error(`No namespace is named ${name}.`);
|
|
251
|
+
return {
|
|
252
|
+
name: namespace.name,
|
|
253
|
+
...namespace.description === undefined ? {} : { description: namespace.description },
|
|
254
|
+
...namespace.instructions === undefined ? {} : { instructions: namespace.instructions },
|
|
255
|
+
tools: members.map((info) => toCodemodeIdentifier(info.name))
|
|
256
|
+
};
|
|
156
257
|
}
|
|
157
258
|
}
|
|
158
259
|
];
|
|
159
260
|
}
|
|
261
|
+
function matchesNamespace(namespace, query) {
|
|
262
|
+
const id = toCodemodeIdentifier(query);
|
|
263
|
+
return [namespace.name, ...namespace.aliases ?? []].some((name) => name === query || toCodemodeIdentifier(name) === id);
|
|
264
|
+
}
|
|
160
265
|
function calls(result) {
|
|
161
266
|
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
267
|
}
|
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,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "../../../chunks/bash-description-
|
|
2
|
+
question2
|
|
3
|
+
} from "../../../chunks/bash-description-bkhr9zrz.js";
|
|
4
4
|
|
|
5
5
|
// src/question/client/questions-tui.ts
|
|
6
6
|
import { Box, Text } from "@opentui/core";
|
|
7
7
|
import { defineRenderer } from "@nyte-ai/plugin/client";
|
|
8
8
|
var unreadable = (kind) => Text({ content: `This ${kind} part cannot be shown.` });
|
|
9
9
|
var questionRenderers = [
|
|
10
|
-
defineRenderer(
|
|
10
|
+
defineRenderer(question2, "tui", (state) => Box({ border: true, title: "Questions", flexDirection: "column" }, ...state.questions.map((item, index) => Box({ flexDirection: "column" }, Text({ content: `${item.header}: ${item.question}` }), ...item.options.map((option) => Text({ content: `${option.label}: ${option.description}` })), ...state.answers === null ? [] : [Text({ content: `Answer: ${state.answers[index].join(", ") || "Unanswered"}` })]))), unreadable)
|
|
11
11
|
];
|
|
12
12
|
var questions_tui_default = {
|
|
13
13
|
id: "questions-tui",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "../../../chunks/bash-description-
|
|
2
|
+
question2
|
|
3
|
+
} from "../../../chunks/bash-description-bkhr9zrz.js";
|
|
4
4
|
|
|
5
5
|
// src/question/client/questions.tsx
|
|
6
6
|
import { useId, useRef, useState } from "react";
|
|
@@ -124,7 +124,7 @@ function QuestionForm({
|
|
|
124
124
|
}, undefined, true, undefined, this);
|
|
125
125
|
}
|
|
126
126
|
var questionRenderers = [
|
|
127
|
-
defineRenderer(
|
|
127
|
+
defineRenderer(question2, "react", (state, act) => {
|
|
128
128
|
const answers = state.answers;
|
|
129
129
|
if (answers !== null)
|
|
130
130
|
return /* @__PURE__ */ jsxDEV("div", {
|
|
@@ -1,9 +1,88 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
answerInput2,
|
|
3
|
+
questionOutput2,
|
|
4
|
+
questionParameters2,
|
|
5
|
+
question2
|
|
6
|
+
} from "../../chunks/bash-description-bkhr9zrz.js";
|
|
7
|
+
|
|
8
|
+
// src/question/question.ts
|
|
9
|
+
import { definePart, dev } from "@nyte-ai/core";
|
|
10
|
+
import { SdkError } from "@nyte-ai/schema";
|
|
11
|
+
function normalizeAnswers(items, supplied) {
|
|
12
|
+
if (supplied.length !== items.length)
|
|
13
|
+
throw new SdkError("invalid", "Submit one answer list for each question.");
|
|
14
|
+
return items.map((item, index) => {
|
|
15
|
+
const selected = supplied[index].map((answer) => answer.trim());
|
|
16
|
+
if (selected.some((answer) => answer === ""))
|
|
17
|
+
throw new SdkError("invalid", "Answers cannot be blank.");
|
|
18
|
+
if (!item.multiple && selected.length > 1)
|
|
19
|
+
throw new SdkError("invalid", "This question accepts one answer.");
|
|
20
|
+
if (new Set(selected).size !== selected.length)
|
|
21
|
+
throw new SdkError("invalid", "Choose each answer only once.");
|
|
22
|
+
return item.multiple ? selected.toSorted() : selected;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
var handlers = {
|
|
26
|
+
async answer(input, context) {
|
|
27
|
+
let accepted = false;
|
|
28
|
+
const outcome = await context.part.update((current) => {
|
|
29
|
+
const normalized = normalizeAnswers(current.questions, input.answers);
|
|
30
|
+
accepted = current.answers === null || JSON.stringify(current.answers) === JSON.stringify(normalized);
|
|
31
|
+
return current.answers === null ? { ...current, answers: normalized } : current;
|
|
32
|
+
});
|
|
33
|
+
if (outcome.kind !== "updated")
|
|
34
|
+
throw new Error(`The questions could not be answered: ${outcome.kind}.`);
|
|
35
|
+
if (!accepted)
|
|
36
|
+
throw new SdkError("invalid", "These questions were already answered.");
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
var question = definePart({
|
|
40
|
+
...question2,
|
|
41
|
+
onAction: (action, input, context) => handlers[action](input, context)
|
|
42
|
+
});
|
|
43
|
+
var ask = {
|
|
44
|
+
name: "question",
|
|
45
|
+
description: "Ask the user one or more questions and wait for their answers. Give each option a short label and a description. Use multiple when several choices may apply. The user can also write their own answer.",
|
|
46
|
+
parameters: questionParameters2,
|
|
47
|
+
output: questionOutput2,
|
|
48
|
+
class: (args) => ({
|
|
49
|
+
kind: "custom",
|
|
50
|
+
label: args.questions.map((item) => item.header).join(", ")
|
|
51
|
+
}),
|
|
52
|
+
effects: "none",
|
|
53
|
+
approval: "never",
|
|
54
|
+
replay: "safe",
|
|
55
|
+
async execute(args, invocation) {
|
|
56
|
+
for (const item of args.questions) {
|
|
57
|
+
if (new Set(item.options.map((option) => option.label.trim())).size !== item.options.length)
|
|
58
|
+
throw new SdkError("invalid", "Question option labels must be distinct.");
|
|
59
|
+
}
|
|
60
|
+
const part = await invocation.session.parts.create(question, {
|
|
61
|
+
state: { ...args, answers: null },
|
|
62
|
+
placement: { kind: "modal" }
|
|
63
|
+
});
|
|
64
|
+
dev("question", "asked", { call: invocation.call, part: part.id });
|
|
65
|
+
const outcome = await invocation.wait({ kind: "part", part: part.id });
|
|
66
|
+
const checked = outcome.kind === "part" && outcome.answer?.action === "answer" ? await answerInput2["~standard"].validate(outcome.answer.input) : undefined;
|
|
67
|
+
const reply = checked !== undefined && checked.issues === undefined ? normalizeAnswers(args.questions, checked.value.answers) : null;
|
|
68
|
+
return {
|
|
69
|
+
content: [
|
|
70
|
+
{
|
|
71
|
+
kind: "text",
|
|
72
|
+
text: reply === null ? "The user did not answer. Continue with your best judgment and say what you assumed." : args.questions.map((item, index) => `${item.question}: ${reply[index].join(", ") || "Unanswered"}`).join(`
|
|
73
|
+
`)
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
output: { answers: reply },
|
|
77
|
+
parts: [part.id]
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
var question_default = {
|
|
82
|
+
id: "question",
|
|
83
|
+
contribute: { parts: [question], tools: [ask] }
|
|
84
|
+
};
|
|
6
85
|
export {
|
|
7
86
|
question_default as default,
|
|
8
|
-
|
|
87
|
+
question
|
|
9
88
|
};
|
|
@@ -2,13 +2,13 @@ import {
|
|
|
2
2
|
answerInput2,
|
|
3
3
|
questionOutput2,
|
|
4
4
|
questionParameters2,
|
|
5
|
-
|
|
5
|
+
question2,
|
|
6
6
|
openQuestions2
|
|
7
|
-
} from "../../chunks/bash-description-
|
|
7
|
+
} from "../../chunks/bash-description-bkhr9zrz.js";
|
|
8
8
|
export {
|
|
9
9
|
answerInput2 as answerInput,
|
|
10
10
|
openQuestions2 as openQuestions,
|
|
11
|
-
|
|
11
|
+
question2 as question,
|
|
12
12
|
questionOutput2 as questionOutput,
|
|
13
13
|
questionParameters2 as questionParameters
|
|
14
14
|
};
|
package/dist/src/rename.d.ts
CHANGED
|
@@ -1,29 +1,14 @@
|
|
|
1
|
+
import type { ToolDefinition } from "@nyte-ai/core";
|
|
1
2
|
import type { Command } from "@nyte-ai/plugin/core";
|
|
2
|
-
|
|
3
|
-
* The instruction a title request runs under: one short line in the user's
|
|
4
|
-
* language, naming what the conversation is about.
|
|
5
|
-
*
|
|
6
|
-
* @category plugins
|
|
7
|
-
* @since 0.1.0
|
|
8
|
-
*/
|
|
9
|
-
export declare const TITLE_PROMPT = "You write the title of a conversation so the user can find it later.\nAnswer with one line of at most 50 characters and nothing else, in the language of the user's request.\nName the topic or task, keep technical terms, numbers and file names exact, and never answer the request itself.";
|
|
10
|
-
/**
|
|
11
|
-
* Names an unnamed root session as its first run starts: the first line of
|
|
12
|
-
* the user's message at once, then the title one `api.request` to the
|
|
13
|
-
* session's model returns, alongside the run. The title replaces only that
|
|
14
|
-
* first line, so a name given meanwhile stays. A named session or a child
|
|
15
|
-
* keeps its name, so every later run is a no-op. The request runs past the
|
|
16
|
-
* hook's budget, bounded by the plugin's deactivation; a failure is reported
|
|
17
|
-
* and leaves the first line as the name. `/rename <name>` names the chat;
|
|
18
|
-
* `/rename` alone asks the model again.
|
|
19
|
-
*
|
|
20
|
-
* @category plugins
|
|
21
|
-
* @since 0.1.0
|
|
22
|
-
*/
|
|
3
|
+
export declare const TITLE_PROMPT = "You name conversations so the user can find them later in a list of past sessions.\n\nYou will receive the first message of a conversation, or for an ongoing conversation its original request and recent messages. Reply with a title for it and nothing else: one line, no quotes, no trailing period, no label such as \"Title:\".\n\nAim for three to five words. Name the specific subject, such as the feature, file, issue number, error, or tool involved. Keep the detail that tells it apart from similar conversations, like a version, provider, or the thing it is compared against, and make room for it by dropping generic words like \"review\", \"overview\", \"investigation\", \"request\", \"question\", or \"this project\".\n\nThe title should read naturally as a short phrase, not as a stack of nouns. Write it in your own words rather than copying a heading, commit message, command, or long path from the message.\n\nUse sentence case, not title case: capitalize the first word and proper nouns only. Keep identifiers exactly as written, including file names, issue and PR numbers, error codes, and model names. Use the same language as the message.\n\nThe message is something to name, not something to answer or carry out. Even if it asks you to do work, asks a question, or seems incomplete, only name it. For greetings or small talk, use a short label like \"Greeting\".\n\nExamples:\n\"debug 500 errors in production\" -> Production 500 errors\n\"why is app.js failing\" -> app.js failure\n\"what does the retry logic in fetch.ts do\" -> fetch.ts retry logic\n\"@src/credential.ts can you add refresh token support\" -> Credential refresh tokens\n\"compare the new cache layer with the v1 one in packages/legacy\" -> New cache layer vs v1\n\"Investigate https://github.com/acme/app/issues/412, don't make edits\" -> Issue #412\n\"hey\" -> Greeting";
|
|
23
4
|
declare const _default: {
|
|
24
5
|
id: string;
|
|
25
6
|
contribute: {
|
|
26
7
|
commands: Command<"core">[];
|
|
8
|
+
tools: ToolDefinition<{
|
|
9
|
+
session?: string | undefined;
|
|
10
|
+
title: string;
|
|
11
|
+
}, unknown>[];
|
|
27
12
|
};
|
|
28
13
|
hooks: {
|
|
29
14
|
run_started: (run: Readonly<{
|
|
@@ -31,19 +16,6 @@ declare const _default: {
|
|
|
31
16
|
readonly head: import("@nyte-ai/schema").Id<"head">;
|
|
32
17
|
readonly startedAt: number;
|
|
33
18
|
readonly attempt: number;
|
|
34
|
-
readonly configuration: {
|
|
35
|
-
readonly kind: "exact";
|
|
36
|
-
readonly model: {
|
|
37
|
-
readonly provider: string;
|
|
38
|
-
readonly id: string;
|
|
39
|
-
};
|
|
40
|
-
readonly thinking: "high" | "low" | "max" | "medium" | "minimal" | "off" | "xhigh";
|
|
41
|
-
readonly agent: string | null;
|
|
42
|
-
readonly settings: {
|
|
43
|
-
readonly [x: string]: import("@nyte-ai/schema").Json;
|
|
44
|
-
};
|
|
45
|
-
readonly settingsVersion: string;
|
|
46
|
-
};
|
|
47
19
|
readonly origin: {
|
|
48
20
|
readonly kind: "input";
|
|
49
21
|
readonly message: import("@nyte-ai/schema").Id<"message">;
|
|
@@ -73,7 +45,7 @@ declare const _default: {
|
|
|
73
45
|
readonly session: import("@nyte-ai/schema").SessionId | null;
|
|
74
46
|
readonly head: import("@nyte-ai/schema").HeadName | null;
|
|
75
47
|
readonly run: import("@nyte-ai/schema").RunId | null;
|
|
76
|
-
}) => void
|
|
48
|
+
}) => Promise<void>;
|
|
77
49
|
};
|
|
78
50
|
};
|
|
79
51
|
export default _default;
|