@nyte-ai/plugin 0.0.0-stage → 0.0.18
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/LICENSE +21 -0
- package/THIRD-PARTY-NOTICES.md +800 -0
- package/dist/chunks/billing-0y7dfkp2.js +146 -0
- package/dist/chunks/billing-2v3g7rd9.js +190 -0
- package/dist/chunks/billing-3j77ss7y.js +86 -0
- package/dist/chunks/billing-3scqmkzb.js +559 -0
- package/dist/chunks/billing-6z2kgtyt.js +51 -0
- package/dist/chunks/billing-8rjk35gr.js +444 -0
- package/dist/chunks/billing-9mfedmsh.js +373 -0
- package/dist/chunks/billing-9nn3yp18.js +176 -0
- package/dist/chunks/billing-9qc0eqh4.js +174 -0
- package/dist/chunks/billing-a9vqn66p.js +351 -0
- package/dist/chunks/billing-bv5zr32b.js +369 -0
- package/dist/chunks/billing-cy1rg619.js +302 -0
- package/dist/chunks/billing-ejx2hv52.js +323 -0
- package/dist/chunks/billing-h13r0byk.js +80 -0
- package/dist/chunks/billing-j643d12p.js +197 -0
- package/dist/chunks/billing-k2p1t25n.js +109 -0
- package/dist/chunks/billing-kn3d30b4.js +276 -0
- package/dist/chunks/billing-mvc33pv6.js +36 -0
- package/dist/chunks/billing-s4rrspsk.js +7 -0
- package/dist/chunks/billing-svrhh5a5.js +307 -0
- package/dist/chunks/billing-sxc70w72.js +161 -0
- package/dist/chunks/billing-t1qrxe16.js +41 -0
- package/dist/chunks/billing-tzr3cebf.js +20 -0
- package/dist/chunks/billing-wmcbg6fw.js +52 -0
- package/dist/chunks/billing-wmkxkypm.js +527 -0
- package/dist/chunks/billing-ye3wk5r3.js +205 -0
- package/dist/chunks/billing-zfpm2rt0.js +29 -0
- package/dist/examples/claude-code/LICENSE +21 -0
- package/dist/examples/claude-code/billing.d.ts +7 -0
- package/dist/examples/claude-code/billing.js +11 -0
- package/dist/examples/claude-code/claude-cli.d.ts +35 -0
- package/dist/examples/claude-code/claude-cli.js +15 -0
- package/dist/examples/claude-code/env.d.ts +1 -0
- package/dist/examples/claude-code/env.js +6 -0
- package/dist/examples/claude-code/index.d.ts +24 -0
- package/dist/examples/claude-code/index.js +149 -0
- package/dist/examples/claude-code/inert-mcp.d.ts +1 -0
- package/dist/examples/claude-code/inert-mcp.js +6 -0
- package/dist/examples/claude-code/model-catalog.d.ts +27 -0
- package/dist/examples/claude-code/model-catalog.js +12 -0
- package/dist/examples/claude-code/process.d.ts +22 -0
- package/dist/examples/claude-code/process.js +25 -0
- package/dist/examples/claude-code/replay.d.ts +4 -0
- package/dist/examples/claude-code/replay.js +11 -0
- package/dist/examples/claude-code/stream.d.ts +3 -0
- package/dist/examples/claude-code/stream.js +16 -0
- package/dist/examples/claude-code/transcript.d.ts +83 -0
- package/dist/examples/claude-code/transcript.js +23 -0
- package/dist/examples/claude-code/turn-relay.d.ts +48 -0
- package/dist/examples/claude-code/turn-relay.js +9 -0
- package/dist/examples/claude-code/wire.d.ts +372 -0
- package/dist/examples/claude-code/wire.js +18 -0
- package/dist/src/acp/connection.d.ts +24 -0
- package/dist/src/acp/connection.js +8 -0
- package/dist/src/acp/index.d.ts +54 -0
- package/dist/src/acp/index.js +1004 -0
- package/dist/src/acp/registry.d.ts +18 -0
- package/dist/src/acp/registry.js +8 -0
- package/dist/src/acp/thread.d.ts +46 -0
- package/dist/src/acp/thread.js +7 -0
- package/dist/src/acp/transcript.d.ts +8 -0
- package/dist/src/acp/transcript.js +11 -0
- package/dist/src/acp/translate.d.ts +33 -0
- package/dist/src/acp/translate.js +20 -0
- package/dist/src/approvals/approvals.d.ts +189 -0
- package/dist/src/approvals/approvals.js +143 -0
- package/dist/src/approvals/schema.d.ts +169 -0
- package/dist/src/approvals/schema.js +18 -0
- package/dist/src/bash-description.d.ts +30 -0
- package/dist/src/bash-description.js +18 -0
- package/dist/src/browser-tools.d.ts +25 -0
- package/dist/src/browser-tools.js +246 -0
- package/dist/src/canvas/canvas-compile.d.ts +48 -0
- package/dist/src/canvas/canvas-compile.js +8 -0
- package/dist/src/canvas/canvas-libraries.d.ts +32 -0
- package/dist/src/canvas/canvas-libraries.js +6 -0
- package/dist/src/canvas/canvas-preview.d.ts +107 -0
- package/dist/src/canvas/canvas-preview.js +12 -0
- package/dist/src/canvas/canvas-protocol.d.ts +184 -0
- package/dist/src/canvas/canvas-protocol.js +75 -0
- package/dist/src/canvas/canvas.d.ts +50 -0
- package/dist/src/canvas/canvas.js +221 -0
- package/dist/src/canvas/schema.d.ts +47 -0
- package/dist/src/canvas/schema.js +8 -0
- package/dist/src/claude-code-sdk/index.d.ts +35 -0
- package/dist/src/claude-code-sdk/index.js +368 -0
- package/dist/src/claude-code-sdk/session.d.ts +48 -0
- package/dist/src/claude-code-sdk/session.js +7 -0
- package/dist/src/claude-code-sdk/transcript.d.ts +19 -0
- package/dist/src/claude-code-sdk/transcript.js +15 -0
- package/dist/src/claude-code-sdk/translate.d.ts +18 -0
- package/dist/src/claude-code-sdk/translate.js +20 -0
- package/dist/src/client/mount.d.ts +44 -0
- package/dist/src/client/mount.js +252 -0
- package/dist/src/client/notifications.d.ts +35 -0
- package/dist/src/client/notifications.js +26 -0
- package/dist/src/client/presentation.d.ts +336 -0
- package/dist/src/client/presentation.js +373 -0
- package/dist/src/client/transcript-tui.d.ts +23 -0
- package/dist/src/client/transcript-tui.js +20 -0
- package/dist/src/client/transcript.d.ts +23 -0
- package/dist/src/client/transcript.js +51 -0
- package/dist/src/client.d.ts +53 -0
- package/dist/src/client.js +22 -0
- package/dist/src/codemode-runtime.d.ts +11 -0
- package/dist/src/codemode-runtime.js +10 -0
- package/dist/src/codemode-worker.d.ts +1 -0
- package/dist/src/codemode-worker.js +2 -0
- package/dist/src/codemode.d.ts +21 -0
- package/dist/src/codemode.js +170 -0
- package/dist/src/core.d.ts +43 -0
- package/dist/src/core.js +11 -0
- package/dist/src/openai-astra-context.d.ts +23 -0
- package/dist/src/openai-astra-context.js +14 -0
- package/dist/src/openai-compaction.d.ts +15 -0
- package/dist/src/openai-compaction.js +55 -0
- package/dist/src/question/client/questions-tui.d.ts +9 -0
- package/dist/src/question/client/questions-tui.js +19 -0
- package/dist/src/question/client/questions.d.ts +9 -0
- package/dist/src/question/client/questions.js +160 -0
- package/dist/src/question/question.d.ts +63 -0
- package/dist/src/question/question.js +9 -0
- package/dist/src/question/schema.d.ts +101 -0
- package/dist/src/question/schema.js +14 -0
- package/dist/src/rename.d.ts +78 -0
- package/dist/src/rename.js +78 -0
- package/dist/src/telemetry.d.ts +36 -0
- package/dist/src/telemetry.js +84 -0
- package/dist/src/web-search.d.ts +78 -0
- package/dist/src/web-search.js +219 -0
- package/package.json +190 -3
- package/README.md +0 -3
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// src/codemode.ts
|
|
2
|
+
import { CodemodeSandbox } from "@earendil-works/pi-codemode";
|
|
3
|
+
import { renderToolSample } from "@earendil-works/pi-codemode/declarations";
|
|
4
|
+
import { CODEMODE_SOURCE_GRAMMAR, parseCodemodeSource } from "@earendil-works/pi-codemode/source";
|
|
5
|
+
import { dev } from "@nyte-ai/core";
|
|
6
|
+
import { isJson, isJsonObject, SdkError, standard } from "@nyte-ai/schema";
|
|
7
|
+
import { Type } from "typebox";
|
|
8
|
+
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
|
+
- \`await tools.<name>({ ...args })\` resolves to the tool's output, or its text, and rejects with an Error on failure.
|
|
10
|
+
- Optional first line: \`// @options: {"timeout_ms": 60000}\`
|
|
11
|
+
- \`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 \`describeTool(name)\` find tools and their declarations.`;
|
|
13
|
+
var SUMMARY_CHARS = 160;
|
|
14
|
+
var parameters = standard(Type.Object({ code: Type.String({ description: "Raw JavaScript source." }) }));
|
|
15
|
+
function codemodePlugin(runtime) {
|
|
16
|
+
return {
|
|
17
|
+
id: "codemode",
|
|
18
|
+
activate(api) {
|
|
19
|
+
api.contribute.tools.add(codemode(api, runtime));
|
|
20
|
+
api.contribute.prompt.add((draft, siblings) => {
|
|
21
|
+
const reachable = siblings.tools.list().flatMap((tool) => tool.exposure === "code" || tool.exposure === "deferred" ? [`- ${tool.name}: ${summarize(tool.description)}`] : []).toSorted();
|
|
22
|
+
if (reachable.length === 0)
|
|
23
|
+
return;
|
|
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
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function summarize(description) {
|
|
38
|
+
const [line = ""] = description.trim().split(`
|
|
39
|
+
`);
|
|
40
|
+
return line.length > SUMMARY_CHARS ? `${line.slice(0, SUMMARY_CHARS)}…` : line;
|
|
41
|
+
}
|
|
42
|
+
function codemode(api, runtime) {
|
|
43
|
+
return {
|
|
44
|
+
name: "codemode",
|
|
45
|
+
description: DESCRIPTION,
|
|
46
|
+
parameters,
|
|
47
|
+
grammar: { kind: "lark", source: CODEMODE_SOURCE_GRAMMAR },
|
|
48
|
+
class: () => ({ kind: "custom", label: "Running a script" }),
|
|
49
|
+
effects: "none",
|
|
50
|
+
approval: "never",
|
|
51
|
+
replay: "never",
|
|
52
|
+
async execute(args, invocation) {
|
|
53
|
+
const { code, options } = parseCodemodeSource(args.code);
|
|
54
|
+
const callable = invocation.tools.list().filter((info) => info.name !== "codemode" && info.exposure !== "hidden");
|
|
55
|
+
const stored = await api.storage.get("store");
|
|
56
|
+
if (stored !== undefined && !isJsonObject(stored))
|
|
57
|
+
throw new SdkError("internal", "Codemode's stored values are not a JSON object.");
|
|
58
|
+
const sandbox = new CodemodeSandbox({
|
|
59
|
+
...runtime,
|
|
60
|
+
tools: callable.map((info) => bridge(info, invocation)),
|
|
61
|
+
globals: discovery(callable),
|
|
62
|
+
timeoutMs: options.timeoutMs ?? 300000,
|
|
63
|
+
memoryLimitBytes: 256 * 1024 * 1024
|
|
64
|
+
});
|
|
65
|
+
dev("codemode", "run", { call: invocation.call, tools: callable.length });
|
|
66
|
+
let result;
|
|
67
|
+
try {
|
|
68
|
+
result = await sandbox.execute(code, { signal: invocation.signal, store: stored ?? {} });
|
|
69
|
+
} finally {
|
|
70
|
+
await sandbox.close();
|
|
71
|
+
}
|
|
72
|
+
dev("codemode", "end", { call: invocation.call, ok: result.ok, calls: result.calls.length });
|
|
73
|
+
if (!result.ok)
|
|
74
|
+
throw new Error(`${result.error.kind === "script" ? result.error.stack ?? result.error.message : `Script ${result.error.kind}: ${result.error.message}`}
|
|
75
|
+
${calls(result)}`);
|
|
76
|
+
const writes = Object.entries(result.storeWrites.set).flatMap(([key, value]) => isJson(value) ? [[key, value]] : []);
|
|
77
|
+
if (writes.length > 0 || result.storeWrites.delete.length > 0) {
|
|
78
|
+
const next = { ...stored, ...Object.fromEntries(writes) };
|
|
79
|
+
for (const key of result.storeWrites.delete)
|
|
80
|
+
delete next[key];
|
|
81
|
+
await api.storage.set("store", next);
|
|
82
|
+
}
|
|
83
|
+
const content = [];
|
|
84
|
+
for (const item of result.output) {
|
|
85
|
+
if (item.type === "text")
|
|
86
|
+
content.push({ kind: "text", text: item.text });
|
|
87
|
+
else
|
|
88
|
+
content.push({
|
|
89
|
+
kind: "file",
|
|
90
|
+
blob: await invocation.env.files.upload(once(Uint8Array.fromBase64(item.data))),
|
|
91
|
+
mime: item.mimeType
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (result.value !== undefined)
|
|
95
|
+
content.push({
|
|
96
|
+
kind: "text",
|
|
97
|
+
text: typeof result.value === "string" ? result.value : JSON.stringify(result.value)
|
|
98
|
+
});
|
|
99
|
+
return {
|
|
100
|
+
content: content.length === 0 ? [{ kind: "text", text: "The script produced no output." }] : content
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function bridge(info, invocation) {
|
|
106
|
+
let sequence = 0;
|
|
107
|
+
return {
|
|
108
|
+
name: info.name,
|
|
109
|
+
description: info.description,
|
|
110
|
+
inputSchema: info.parameters,
|
|
111
|
+
outputSchema: info.output ?? { type: "string" },
|
|
112
|
+
async execute(args, { signal }) {
|
|
113
|
+
const key = `codemode:${info.name}:${sequence++}`;
|
|
114
|
+
return unwrapToolOutcome(await invocation.tools.execute(info.name, isJson(args) ? args : null, { key, signal }));
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function unwrapToolOutcome(outcome) {
|
|
119
|
+
if (outcome.kind === "ok")
|
|
120
|
+
return outcome.output ?? outcome.content.flatMap((item) => item.kind === "text" ? [item.text] : []).join(`
|
|
121
|
+
`);
|
|
122
|
+
throw new Error(outcome.kind === "failed" ? outcome.message : outcome.kind === "rejected" ? `Rejected: ${outcome.reason}` : `The call was ${outcome.kind}.`);
|
|
123
|
+
}
|
|
124
|
+
function discovery(tools) {
|
|
125
|
+
return [
|
|
126
|
+
{
|
|
127
|
+
name: "searchTools",
|
|
128
|
+
spread: true,
|
|
129
|
+
execute(args) {
|
|
130
|
+
const [query, options] = Array.isArray(args) ? args : [];
|
|
131
|
+
const words = new Set(String(query).toLowerCase().split(/[^a-z0-9]+/).filter((word) => word.length > 1));
|
|
132
|
+
const limit = typeof options === "object" && options !== null && "limit" in options && typeof options.limit === "number" ? options.limit : 8;
|
|
133
|
+
const namespace = typeof options === "object" && options !== null && "namespace" in options && typeof options.namespace === "string" ? options.namespace : null;
|
|
134
|
+
return tools.filter((info) => namespace === null || info.namespace === namespace).map((info) => ({
|
|
135
|
+
info,
|
|
136
|
+
score: `${info.name} ${info.description}`.toLowerCase().split(/[^a-z0-9]+/).filter((word) => words.has(word)).length
|
|
137
|
+
})).filter((entry) => entry.score > 0).toSorted((left, right) => right.score - left.score).slice(0, limit).map(({ info }) => ({
|
|
138
|
+
name: info.name,
|
|
139
|
+
namespace: info.namespace,
|
|
140
|
+
description: info.description
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
name: "describeTool",
|
|
146
|
+
execute(name) {
|
|
147
|
+
const info = tools.find((candidate) => candidate.name === name);
|
|
148
|
+
if (info === undefined)
|
|
149
|
+
throw new Error(`No tool is named ${String(name)}.`);
|
|
150
|
+
return renderToolSample({
|
|
151
|
+
name: info.name,
|
|
152
|
+
description: info.description,
|
|
153
|
+
inputSchema: info.parameters,
|
|
154
|
+
outputSchema: info.output ?? { type: "string" }
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
];
|
|
159
|
+
}
|
|
160
|
+
function calls(result) {
|
|
161
|
+
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
|
+
}
|
|
163
|
+
async function* once(bytes) {
|
|
164
|
+
yield bytes;
|
|
165
|
+
}
|
|
166
|
+
var codemode_default = codemodePlugin({});
|
|
167
|
+
export {
|
|
168
|
+
codemodePlugin,
|
|
169
|
+
codemode_default as default
|
|
170
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { HookEntry as SideHookEntry, HookHandler as SideHookHandler, HookName as SideHookName, Plugin as CorePlugin, PluginApi as CorePluginApi } from "@nyte-ai/core";
|
|
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";
|
|
4
|
+
export type { CompactionPlan, Decision, ModelRequest, Submission, ToolCall, Transcript, } from "@nyte-ai/schema";
|
|
5
|
+
/**
|
|
6
|
+
* A core plugin: per session on the host, with tools, prompt sections,
|
|
7
|
+
* agents, parts, commands, settings and core hooks. Author one as an object
|
|
8
|
+
* literal and check it with `satisfies Plugin`.
|
|
9
|
+
*
|
|
10
|
+
* @category plugins
|
|
11
|
+
* @since 0.1.0
|
|
12
|
+
*/
|
|
13
|
+
export type Plugin = CorePlugin<"core">;
|
|
14
|
+
/**
|
|
15
|
+
* What a core plugin's `activate` and hook handlers receive: the session,
|
|
16
|
+
* its environment, the registries, storage and `request`.
|
|
17
|
+
*
|
|
18
|
+
* @category plugins
|
|
19
|
+
* @since 0.1.0
|
|
20
|
+
*/
|
|
21
|
+
export type PluginApi = CorePluginApi<"core">;
|
|
22
|
+
/**
|
|
23
|
+
* Names a hook a core plugin may handle.
|
|
24
|
+
*
|
|
25
|
+
* @category hooks
|
|
26
|
+
* @since 0.1.0
|
|
27
|
+
*/
|
|
28
|
+
export type HookName = SideHookName<"core">;
|
|
29
|
+
/**
|
|
30
|
+
* Returns a core hook handler's signature, for a helper factored out of a
|
|
31
|
+
* plugin's `hooks`.
|
|
32
|
+
*
|
|
33
|
+
* @category hooks
|
|
34
|
+
* @since 0.1.0
|
|
35
|
+
*/
|
|
36
|
+
export type HookHandler<N extends HookName> = SideHookHandler<"core", N>;
|
|
37
|
+
/**
|
|
38
|
+
* Returns a core hook entry: a handler, or a handler with an order.
|
|
39
|
+
*
|
|
40
|
+
* @category hooks
|
|
41
|
+
* @since 0.1.0
|
|
42
|
+
*/
|
|
43
|
+
export type HookEntry<N extends HookName> = SideHookEntry<"core", N>;
|
package/dist/src/core.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ModelContextPolicy } from "@nyte-ai/core";
|
|
2
|
+
/**
|
|
3
|
+
* The context policy of `gpt-6-astra` on OpenAI and OpenAI Codex: a window
|
|
4
|
+
* of one million tokens, compacted at 400 000.
|
|
5
|
+
*
|
|
6
|
+
* @category plugins
|
|
7
|
+
* @since 0.1.0
|
|
8
|
+
*/
|
|
9
|
+
export declare const astra: readonly ModelContextPolicy[];
|
|
10
|
+
/**
|
|
11
|
+
* Gives the astra models their context window and compaction threshold,
|
|
12
|
+
* folded into their `ModelInfo` and the sessions that run them.
|
|
13
|
+
*
|
|
14
|
+
* @category plugins
|
|
15
|
+
* @since 0.1.0
|
|
16
|
+
*/
|
|
17
|
+
declare const _default: {
|
|
18
|
+
id: string;
|
|
19
|
+
contribute: {
|
|
20
|
+
modelContext: readonly ModelContextPolicy[];
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export default _default;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// src/openai-astra-context.ts
|
|
2
|
+
var astra = ["openai", "openai-codex"].map((provider) => ({
|
|
3
|
+
model: { provider, id: "gpt-6-astra" },
|
|
4
|
+
contextWindow: 1e6,
|
|
5
|
+
compactAt: 400000
|
|
6
|
+
}));
|
|
7
|
+
var openai_astra_context_default = {
|
|
8
|
+
id: "openai-astra-context",
|
|
9
|
+
contribute: { modelContext: astra }
|
|
10
|
+
};
|
|
11
|
+
export {
|
|
12
|
+
astra,
|
|
13
|
+
openai_astra_context_default as default
|
|
14
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Models } from "@nyte-ai/ai";
|
|
2
|
+
import type { Plugin } from "@nyte-ai/plugin/core";
|
|
3
|
+
/**
|
|
4
|
+
* Returns the plugin that compacts through OpenAI's own endpoint. On
|
|
5
|
+
* `before_compaction`, when the session's model is OpenAI Responses (an API
|
|
6
|
+
* key) or OpenAI Codex Responses (a ChatGPT account), it sends the messages
|
|
7
|
+
* to summarise to the provider's compact endpoint and supplies the opaque
|
|
8
|
+
* window it returns as the plan's `material`; core writes it without a
|
|
9
|
+
* summary request. Any other model, or a provider without credentials,
|
|
10
|
+
* leaves the plan to core. `models` is the host's, for credentials.
|
|
11
|
+
*
|
|
12
|
+
* @category plugins
|
|
13
|
+
* @since 0.1.0
|
|
14
|
+
*/
|
|
15
|
+
export declare function openaiCompaction(models: Pick<Models, "getModel" | "getAuth">): Plugin;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// src/openai-compaction.ts
|
|
2
|
+
import {
|
|
3
|
+
compactOpenAICodexContext,
|
|
4
|
+
compactOpenAIResponsesContext,
|
|
5
|
+
providerIdentity
|
|
6
|
+
} from "@nyte-ai/ai";
|
|
7
|
+
function openaiCompaction(models) {
|
|
8
|
+
return {
|
|
9
|
+
id: "openai-compaction",
|
|
10
|
+
hooks: {
|
|
11
|
+
before_compaction: async (plan, { signal }) => {
|
|
12
|
+
const model = models.getModel(plan.model.provider, plan.model.id);
|
|
13
|
+
const responses = model?.provider === "openai" && model.api === "openai-responses";
|
|
14
|
+
const codex = model?.provider === "openai-codex" && model.api === "openai-codex-responses";
|
|
15
|
+
if (plan.result !== null || model === undefined || !responses && !codex)
|
|
16
|
+
return plan;
|
|
17
|
+
const auth = await models.getAuth(model, { signal });
|
|
18
|
+
if (auth === undefined)
|
|
19
|
+
return plan;
|
|
20
|
+
const base = { ...model, baseUrl: auth.auth.baseUrl ?? model.baseUrl };
|
|
21
|
+
const options = { apiKey: auth.auth.apiKey, headers: auth.auth.headers, signal };
|
|
22
|
+
const context = {
|
|
23
|
+
messages: [
|
|
24
|
+
...plan.summarise,
|
|
25
|
+
...plan.instructions === null ? [] : [{ role: "system", content: plan.instructions, timestamp: Date.now() }]
|
|
26
|
+
]
|
|
27
|
+
};
|
|
28
|
+
const compacted = codex ? await compactOpenAICodexContext({ ...base, api: "openai-codex-responses" }, context, options) : await compactOpenAIResponsesContext({ ...base, api: "openai-responses" }, context, options);
|
|
29
|
+
return {
|
|
30
|
+
...plan,
|
|
31
|
+
result: {
|
|
32
|
+
kind: "material",
|
|
33
|
+
...providerIdentity(model),
|
|
34
|
+
data: compacted.data,
|
|
35
|
+
usage: compacted.usage === undefined ? null : sessionUsage(compacted.usage)
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function sessionUsage(usage) {
|
|
43
|
+
return {
|
|
44
|
+
input: usage.input,
|
|
45
|
+
output: usage.output,
|
|
46
|
+
cacheRead: usage.cacheRead,
|
|
47
|
+
cacheWrite: usage.cacheWrite,
|
|
48
|
+
reasoning: usage.reasoning ?? null,
|
|
49
|
+
total: usage.totalTokens,
|
|
50
|
+
cost: usage.cost
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
openaiCompaction
|
|
55
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Renderer } from "@nyte-ai/plugin/client";
|
|
2
|
+
export declare const questionRenderers: readonly Renderer[];
|
|
3
|
+
declare const _default: {
|
|
4
|
+
id: string;
|
|
5
|
+
contribute: {
|
|
6
|
+
renderers: readonly Renderer<import("@nyte-ai/plugin/client").PartDefinition<unknown, import("@nyte-ai/core").ActionSchemas>, unknown>[];
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
question3
|
|
3
|
+
} from "../../../chunks/billing-6z2kgtyt.js";
|
|
4
|
+
|
|
5
|
+
// src/question/client/questions-tui.ts
|
|
6
|
+
import { Box, Text } from "@opentui/core";
|
|
7
|
+
import { defineRenderer } from "@nyte-ai/plugin/client";
|
|
8
|
+
var unreadable = (kind) => Text({ content: `This ${kind} part cannot be shown.` });
|
|
9
|
+
var questionRenderers = [
|
|
10
|
+
defineRenderer(question3, "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
|
+
];
|
|
12
|
+
var questions_tui_default = {
|
|
13
|
+
id: "questions-tui",
|
|
14
|
+
contribute: { renderers: questionRenderers }
|
|
15
|
+
};
|
|
16
|
+
export {
|
|
17
|
+
questions_tui_default as default,
|
|
18
|
+
questionRenderers
|
|
19
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Renderer } from "@nyte-ai/plugin/client";
|
|
2
|
+
export declare const questionRenderers: readonly Renderer[];
|
|
3
|
+
declare const _default: {
|
|
4
|
+
id: string;
|
|
5
|
+
contribute: {
|
|
6
|
+
renderers: readonly Renderer<import("@nyte-ai/plugin/client").PartDefinition<unknown, import("@nyte-ai/core").ActionSchemas>, unknown>[];
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import {
|
|
2
|
+
question3
|
|
3
|
+
} from "../../../chunks/billing-6z2kgtyt.js";
|
|
4
|
+
|
|
5
|
+
// src/question/client/questions.tsx
|
|
6
|
+
import { useId, useRef, useState } from "react";
|
|
7
|
+
import { defineRenderer } from "@nyte-ai/plugin/client";
|
|
8
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
9
|
+
var unreadable = (kind) => /* @__PURE__ */ jsxDEV("div", {
|
|
10
|
+
"data-part": kind,
|
|
11
|
+
children: [
|
|
12
|
+
"This ",
|
|
13
|
+
kind,
|
|
14
|
+
" part cannot be shown."
|
|
15
|
+
]
|
|
16
|
+
}, undefined, true, undefined, this);
|
|
17
|
+
function QuestionForm({
|
|
18
|
+
questions,
|
|
19
|
+
act
|
|
20
|
+
}) {
|
|
21
|
+
const id = useId();
|
|
22
|
+
const [selected, setSelected] = useState(() => questions.map(() => []));
|
|
23
|
+
const [custom, setCustom] = useState(() => questions.map(() => ""));
|
|
24
|
+
const [status, setStatus] = useState({ kind: "editing" });
|
|
25
|
+
const submitting = useRef(false);
|
|
26
|
+
const blocked = status.kind === "sending" || status.kind === "sent";
|
|
27
|
+
const submit = async () => {
|
|
28
|
+
if (blocked || submitting.current)
|
|
29
|
+
return;
|
|
30
|
+
submitting.current = true;
|
|
31
|
+
setStatus({ kind: "sending" });
|
|
32
|
+
const answers = questions.map((item, index) => {
|
|
33
|
+
const typed = custom[index].trim();
|
|
34
|
+
const choices = selected[index];
|
|
35
|
+
if (typed === "" || choices.includes(typed))
|
|
36
|
+
return choices;
|
|
37
|
+
return item.multiple ? [...choices, typed] : [typed];
|
|
38
|
+
});
|
|
39
|
+
try {
|
|
40
|
+
const outcome = await act("answer", { answers });
|
|
41
|
+
setStatus(outcome.kind === "ok" ? { kind: "sent" } : {
|
|
42
|
+
kind: "failed",
|
|
43
|
+
message: outcome.kind === "rejected" ? outcome.reason : "These questions are no longer waiting."
|
|
44
|
+
});
|
|
45
|
+
} catch {
|
|
46
|
+
setStatus({ kind: "failed", message: "Couldn't send your answers. Try again." });
|
|
47
|
+
}
|
|
48
|
+
submitting.current = false;
|
|
49
|
+
};
|
|
50
|
+
return /* @__PURE__ */ jsxDEV("form", {
|
|
51
|
+
"data-part": "ask/question",
|
|
52
|
+
"aria-label": "Questions",
|
|
53
|
+
onSubmit: (event) => {
|
|
54
|
+
event.preventDefault();
|
|
55
|
+
submit();
|
|
56
|
+
},
|
|
57
|
+
children: [
|
|
58
|
+
questions.map((item, index) => /* @__PURE__ */ jsxDEV("fieldset", {
|
|
59
|
+
disabled: blocked,
|
|
60
|
+
children: [
|
|
61
|
+
/* @__PURE__ */ jsxDEV("legend", {
|
|
62
|
+
children: item.header
|
|
63
|
+
}, undefined, false, undefined, this),
|
|
64
|
+
/* @__PURE__ */ jsxDEV("p", {
|
|
65
|
+
children: item.question
|
|
66
|
+
}, undefined, false, undefined, this),
|
|
67
|
+
item.options.map((option) => /* @__PURE__ */ jsxDEV("label", {
|
|
68
|
+
children: [
|
|
69
|
+
/* @__PURE__ */ jsxDEV("input", {
|
|
70
|
+
type: item.multiple ? "checkbox" : "radio",
|
|
71
|
+
name: `${id}-${index}`,
|
|
72
|
+
value: option.label,
|
|
73
|
+
checked: selected[index].includes(option.label),
|
|
74
|
+
onChange: () => {
|
|
75
|
+
setSelected((current) => current.map((choices, position) => {
|
|
76
|
+
if (position !== index)
|
|
77
|
+
return choices;
|
|
78
|
+
if (!item.multiple)
|
|
79
|
+
return [option.label];
|
|
80
|
+
return choices.includes(option.label) ? choices.filter((choice) => choice !== option.label) : [...choices, option.label];
|
|
81
|
+
}));
|
|
82
|
+
if (!item.multiple)
|
|
83
|
+
setCustom((current) => current.map((typed, position) => position === index ? "" : typed));
|
|
84
|
+
}
|
|
85
|
+
}, undefined, false, undefined, this),
|
|
86
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
87
|
+
children: option.label
|
|
88
|
+
}, undefined, false, undefined, this),
|
|
89
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
90
|
+
children: option.description
|
|
91
|
+
}, undefined, false, undefined, this)
|
|
92
|
+
]
|
|
93
|
+
}, option.label, true, undefined, this)),
|
|
94
|
+
/* @__PURE__ */ jsxDEV("label", {
|
|
95
|
+
children: [
|
|
96
|
+
"Type your own answer",
|
|
97
|
+
/* @__PURE__ */ jsxDEV("textarea", {
|
|
98
|
+
value: custom[index],
|
|
99
|
+
onChange: ({ currentTarget }) => {
|
|
100
|
+
const typed = currentTarget.value;
|
|
101
|
+
setCustom((current) => current.map((value, position) => position === index ? typed : value));
|
|
102
|
+
if (!item.multiple && typed.trim() !== "")
|
|
103
|
+
setSelected((current) => current.map((choices, position) => position === index ? [] : choices));
|
|
104
|
+
}
|
|
105
|
+
}, undefined, false, undefined, this)
|
|
106
|
+
]
|
|
107
|
+
}, undefined, true, undefined, this)
|
|
108
|
+
]
|
|
109
|
+
}, index, true, undefined, this)),
|
|
110
|
+
/* @__PURE__ */ jsxDEV("button", {
|
|
111
|
+
type: "submit",
|
|
112
|
+
disabled: blocked,
|
|
113
|
+
children: status.kind === "sending" ? "Sending answers…" : "Submit answers"
|
|
114
|
+
}, undefined, false, undefined, this),
|
|
115
|
+
status.kind === "failed" && /* @__PURE__ */ jsxDEV("p", {
|
|
116
|
+
role: "alert",
|
|
117
|
+
children: status.message
|
|
118
|
+
}, undefined, false, undefined, this),
|
|
119
|
+
status.kind === "sent" && /* @__PURE__ */ jsxDEV("p", {
|
|
120
|
+
role: "status",
|
|
121
|
+
children: "Answers sent."
|
|
122
|
+
}, undefined, false, undefined, this)
|
|
123
|
+
]
|
|
124
|
+
}, undefined, true, undefined, this);
|
|
125
|
+
}
|
|
126
|
+
var questionRenderers = [
|
|
127
|
+
defineRenderer(question3, "react", (state, act) => {
|
|
128
|
+
const answers = state.answers;
|
|
129
|
+
if (answers !== null)
|
|
130
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
131
|
+
"data-part": "ask/question",
|
|
132
|
+
"aria-label": "Answers",
|
|
133
|
+
children: state.questions.map((item, index) => /* @__PURE__ */ jsxDEV("section", {
|
|
134
|
+
children: [
|
|
135
|
+
/* @__PURE__ */ jsxDEV("h3", {
|
|
136
|
+
children: item.header
|
|
137
|
+
}, undefined, false, undefined, this),
|
|
138
|
+
/* @__PURE__ */ jsxDEV("p", {
|
|
139
|
+
children: item.question
|
|
140
|
+
}, undefined, false, undefined, this),
|
|
141
|
+
/* @__PURE__ */ jsxDEV("p", {
|
|
142
|
+
children: [
|
|
143
|
+
"Answer: ",
|
|
144
|
+
answers[index].join(", ") || "Unanswered"
|
|
145
|
+
]
|
|
146
|
+
}, undefined, true, undefined, this)
|
|
147
|
+
]
|
|
148
|
+
}, index, true, undefined, this))
|
|
149
|
+
}, undefined, false, undefined, this);
|
|
150
|
+
return /* @__PURE__ */ jsxDEV(QuestionForm, {
|
|
151
|
+
questions: state.questions,
|
|
152
|
+
act
|
|
153
|
+
}, JSON.stringify(state.questions), false, undefined, this);
|
|
154
|
+
}, unreadable)
|
|
155
|
+
];
|
|
156
|
+
var questions_default = { id: "questions", contribute: { renderers: questionRenderers } };
|
|
157
|
+
export {
|
|
158
|
+
questions_default as default,
|
|
159
|
+
questionRenderers
|
|
160
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { ToolDefinition } from "@nyte-ai/core";
|
|
2
|
+
export declare const question: import("@nyte-ai/core").PartDefinition<{
|
|
3
|
+
answers: string[][] | null;
|
|
4
|
+
questions: {
|
|
5
|
+
multiple?: boolean | undefined;
|
|
6
|
+
options: {
|
|
7
|
+
description: string;
|
|
8
|
+
label: string;
|
|
9
|
+
}[];
|
|
10
|
+
question: string;
|
|
11
|
+
header: string;
|
|
12
|
+
}[];
|
|
13
|
+
}, {
|
|
14
|
+
answer: {
|
|
15
|
+
input: import("@nyte-ai/schema").Schema<{
|
|
16
|
+
answers: string[][];
|
|
17
|
+
}>;
|
|
18
|
+
};
|
|
19
|
+
}>;
|
|
20
|
+
/**
|
|
21
|
+
* Contributes the question tool and its grouped modal. The durable wait
|
|
22
|
+
* resumes after one complete submission from any client.
|
|
23
|
+
*
|
|
24
|
+
* @category plugins
|
|
25
|
+
* @since 0.1.0
|
|
26
|
+
*/
|
|
27
|
+
declare const _default: {
|
|
28
|
+
id: string;
|
|
29
|
+
contribute: {
|
|
30
|
+
parts: import("@nyte-ai/core").PartDefinition<{
|
|
31
|
+
answers: string[][] | null;
|
|
32
|
+
questions: {
|
|
33
|
+
multiple?: boolean | undefined;
|
|
34
|
+
options: {
|
|
35
|
+
description: string;
|
|
36
|
+
label: string;
|
|
37
|
+
}[];
|
|
38
|
+
question: string;
|
|
39
|
+
header: string;
|
|
40
|
+
}[];
|
|
41
|
+
}, {
|
|
42
|
+
answer: {
|
|
43
|
+
input: import("@nyte-ai/schema").Schema<{
|
|
44
|
+
answers: string[][];
|
|
45
|
+
}>;
|
|
46
|
+
};
|
|
47
|
+
}>[];
|
|
48
|
+
tools: ToolDefinition<{
|
|
49
|
+
questions: {
|
|
50
|
+
multiple?: boolean | undefined;
|
|
51
|
+
options: {
|
|
52
|
+
description: string;
|
|
53
|
+
label: string;
|
|
54
|
+
}[];
|
|
55
|
+
question: string;
|
|
56
|
+
header: string;
|
|
57
|
+
}[];
|
|
58
|
+
}, {
|
|
59
|
+
answers: string[][] | null;
|
|
60
|
+
}>[];
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
export default _default;
|