@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,101 @@
|
|
|
1
|
+
import type { Infer, PartId, SessionView } from "@nyte-ai/schema";
|
|
2
|
+
declare const info: import("@nyte-ai/schema").Schema<{
|
|
3
|
+
multiple?: boolean | undefined;
|
|
4
|
+
options: {
|
|
5
|
+
description: string;
|
|
6
|
+
label: string;
|
|
7
|
+
}[];
|
|
8
|
+
question: string;
|
|
9
|
+
header: string;
|
|
10
|
+
}>;
|
|
11
|
+
export declare const answerInput: import("@nyte-ai/schema").Schema<{
|
|
12
|
+
answers: string[][];
|
|
13
|
+
}>;
|
|
14
|
+
export declare const questionOutput: import("@nyte-ai/schema").Schema<{
|
|
15
|
+
answers: string[][] | null;
|
|
16
|
+
}>;
|
|
17
|
+
declare const state: import("@nyte-ai/schema").Schema<{
|
|
18
|
+
answers: string[][] | null;
|
|
19
|
+
questions: {
|
|
20
|
+
multiple?: boolean | undefined;
|
|
21
|
+
options: {
|
|
22
|
+
description: string;
|
|
23
|
+
label: string;
|
|
24
|
+
}[];
|
|
25
|
+
question: string;
|
|
26
|
+
header: string;
|
|
27
|
+
}[];
|
|
28
|
+
}>;
|
|
29
|
+
export declare const questionParameters: import("@nyte-ai/schema").Schema<{
|
|
30
|
+
questions: {
|
|
31
|
+
multiple?: boolean | undefined;
|
|
32
|
+
options: {
|
|
33
|
+
description: string;
|
|
34
|
+
label: string;
|
|
35
|
+
}[];
|
|
36
|
+
question: string;
|
|
37
|
+
header: string;
|
|
38
|
+
}[];
|
|
39
|
+
}>;
|
|
40
|
+
/** A question, its described choices, and whether the user may select several. */
|
|
41
|
+
export type QuestionInfo = Infer<typeof info>;
|
|
42
|
+
/** One answer list per question, in request order. An empty list leaves a question unanswered. */
|
|
43
|
+
export type QuestionAnswers = Infer<typeof answerInput>["answers"];
|
|
44
|
+
/** A grouped question request and its first complete answer, null while waiting. */
|
|
45
|
+
export type QuestionState = Infer<typeof state>;
|
|
46
|
+
/**
|
|
47
|
+
* A grouped modal request. Its answer action submits all questions at once,
|
|
48
|
+
* preserving the first complete answer across retries and restarts.
|
|
49
|
+
*
|
|
50
|
+
* @category plugins
|
|
51
|
+
* @since 0.1.0
|
|
52
|
+
*/
|
|
53
|
+
export declare const question: {
|
|
54
|
+
kind: string;
|
|
55
|
+
state: import("@nyte-ai/schema").Schema<{
|
|
56
|
+
answers: string[][] | null;
|
|
57
|
+
questions: {
|
|
58
|
+
multiple?: boolean | undefined;
|
|
59
|
+
options: {
|
|
60
|
+
description: string;
|
|
61
|
+
label: string;
|
|
62
|
+
}[];
|
|
63
|
+
question: string;
|
|
64
|
+
header: string;
|
|
65
|
+
}[];
|
|
66
|
+
}>;
|
|
67
|
+
actions: {
|
|
68
|
+
answer: {
|
|
69
|
+
input: import("@nyte-ai/schema").Schema<{
|
|
70
|
+
answers: string[][];
|
|
71
|
+
}>;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
fallback: (current: {
|
|
75
|
+
answers: string[][] | null;
|
|
76
|
+
questions: {
|
|
77
|
+
multiple?: boolean | undefined;
|
|
78
|
+
options: {
|
|
79
|
+
description: string;
|
|
80
|
+
label: string;
|
|
81
|
+
}[];
|
|
82
|
+
question: string;
|
|
83
|
+
header: string;
|
|
84
|
+
}[];
|
|
85
|
+
}, { id }: {
|
|
86
|
+
readonly id: PartId;
|
|
87
|
+
}) => string;
|
|
88
|
+
};
|
|
89
|
+
/** A grouped request still waiting for the user, with the part its submission goes to. */
|
|
90
|
+
export type OpenQuestion = Pick<QuestionState, "questions"> & {
|
|
91
|
+
readonly part: PartId;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Returns unanswered live question requests, oldest first. Requests from a
|
|
95
|
+
* stopped or failed run and parts with invalid state are omitted.
|
|
96
|
+
*
|
|
97
|
+
* @category plugins
|
|
98
|
+
* @since 0.1.0
|
|
99
|
+
*/
|
|
100
|
+
export declare function openQuestions(view: Pick<SessionView, "parts"> | undefined): readonly OpenQuestion[];
|
|
101
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
answerInput2,
|
|
3
|
+
questionOutput2,
|
|
4
|
+
questionParameters2,
|
|
5
|
+
question3,
|
|
6
|
+
openQuestions2
|
|
7
|
+
} from "../../chunks/billing-6z2kgtyt.js";
|
|
8
|
+
export {
|
|
9
|
+
answerInput2 as answerInput,
|
|
10
|
+
openQuestions2 as openQuestions,
|
|
11
|
+
question3 as question,
|
|
12
|
+
questionOutput2 as questionOutput,
|
|
13
|
+
questionParameters2 as questionParameters
|
|
14
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
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 after its first run: one `api.request` to
|
|
12
|
+
* the session's model for a title, then `session.update({ name })`. A named
|
|
13
|
+
* session or a child keeps its name, so every later run is a no-op. The
|
|
14
|
+
* request runs past the hook's budget, bounded by the plugin's deactivation;
|
|
15
|
+
* a failure is reported and leaves the name alone. `/rename <name>` names the
|
|
16
|
+
* chat; `/rename` alone asks the model again.
|
|
17
|
+
*
|
|
18
|
+
* @category plugins
|
|
19
|
+
* @since 0.1.0
|
|
20
|
+
*/
|
|
21
|
+
declare const _default: {
|
|
22
|
+
id: string;
|
|
23
|
+
contribute: {
|
|
24
|
+
commands: Command<"core">[];
|
|
25
|
+
};
|
|
26
|
+
hooks: {
|
|
27
|
+
run_ended: (_end: Readonly<{
|
|
28
|
+
readonly kind: "completed";
|
|
29
|
+
readonly usage: {
|
|
30
|
+
readonly output: number;
|
|
31
|
+
readonly input: number;
|
|
32
|
+
readonly cacheRead: number;
|
|
33
|
+
readonly cacheWrite: number;
|
|
34
|
+
readonly reasoning: number | null;
|
|
35
|
+
readonly total: number;
|
|
36
|
+
readonly cost: {
|
|
37
|
+
readonly output: number;
|
|
38
|
+
readonly input: number;
|
|
39
|
+
readonly cacheRead: number;
|
|
40
|
+
readonly cacheWrite: number;
|
|
41
|
+
readonly total: number;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
} | {
|
|
45
|
+
readonly kind: "stopped";
|
|
46
|
+
} | {
|
|
47
|
+
readonly kind: "failed";
|
|
48
|
+
readonly failure: {
|
|
49
|
+
readonly retryAfterMs?: number | undefined;
|
|
50
|
+
readonly message: string;
|
|
51
|
+
readonly class: "aborted" | "provider" | "rate_limit" | "auth" | "quota" | "context_window" | "overloaded" | "network" | "runner";
|
|
52
|
+
};
|
|
53
|
+
}>, { api }: {
|
|
54
|
+
readonly api: {
|
|
55
|
+
readonly side: "core";
|
|
56
|
+
readonly sdk: import("@nyte-ai/core").Connection;
|
|
57
|
+
readonly contribute: import("@nyte-ai/core").Registries<"core">;
|
|
58
|
+
readonly storage: import("@nyte-ai/core").PluginStorage;
|
|
59
|
+
readonly signal: AbortSignal;
|
|
60
|
+
hook<N extends "session_activated" | "before_send" | "run_started" | "transform_transcript" | "before_compaction" | "before_request" | "before_tool" | "after_tool" | "after_request" | "run_ended">(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
|
|
61
|
+
report(issue: import("@nyte-ai/schema").ValidationIssue): void;
|
|
62
|
+
reload(): void;
|
|
63
|
+
} & {
|
|
64
|
+
readonly session: import("@nyte-ai/core").Session;
|
|
65
|
+
readonly env: import("@nyte-ai/core").ExecutionEnv;
|
|
66
|
+
wrapEnv(wrap: import("@nyte-ai/core").EnvironmentWrap): import("@nyte-ai/schema").Disposer;
|
|
67
|
+
readonly inputs: import("@nyte-ai/core").Resources;
|
|
68
|
+
request<T = string>(input: import("@nyte-ai/schema").ModelRequestInput<T>): Promise<import("@nyte-ai/schema").ModelRequestOutcome<T>>;
|
|
69
|
+
approve(call: import("@nyte-ai/core").RuntimeCall, signal: AbortSignal): Promise<import("@nyte-ai/core").RuntimeVerdict>;
|
|
70
|
+
};
|
|
71
|
+
readonly signal: AbortSignal;
|
|
72
|
+
readonly session: import("@nyte-ai/schema").SessionId | null;
|
|
73
|
+
readonly head: import("@nyte-ai/schema").HeadName | null;
|
|
74
|
+
readonly run: import("@nyte-ai/schema").RunId | null;
|
|
75
|
+
}) => void;
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
export default _default;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// src/rename.ts
|
|
2
|
+
import { dev, isPart, text } from "@nyte-ai/core";
|
|
3
|
+
var TITLE_PROMPT = `You write the title of a conversation so the user can find it later.
|
|
4
|
+
Answer with one line of at most 50 characters and nothing else, in the language of the user's request.
|
|
5
|
+
Name the topic or task, keep technical terms, numbers and file names exact, and never answer the request itself.`;
|
|
6
|
+
var NAME_LIMIT = 100;
|
|
7
|
+
var renameCommand = {
|
|
8
|
+
name: "rename",
|
|
9
|
+
title: "Rename chat",
|
|
10
|
+
description: "Names the chat; with no name, the chat's model titles it again.",
|
|
11
|
+
takesText: true,
|
|
12
|
+
async run(given, { api, signal }) {
|
|
13
|
+
const name = given === "" ? await requestTitle(api, signal) : given.slice(0, NAME_LIMIT);
|
|
14
|
+
await api.session.update({ name });
|
|
15
|
+
return `Renamed to ${name}.`;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var rename_default = {
|
|
19
|
+
id: "rename",
|
|
20
|
+
contribute: { commands: [renameCommand] },
|
|
21
|
+
hooks: {
|
|
22
|
+
run_ended: (_end, { api }) => {
|
|
23
|
+
nameUnnamed(api).catch((error) => api.report({
|
|
24
|
+
severity: "warning",
|
|
25
|
+
path: ["run_ended"],
|
|
26
|
+
message: `Naming the session failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
27
|
+
source: { plugin: "rename" }
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
async function nameUnnamed(api) {
|
|
33
|
+
const info = await api.session.info();
|
|
34
|
+
if (info.name !== null || info.parent !== null)
|
|
35
|
+
return;
|
|
36
|
+
await api.session.update({ name: await requestTitle(api, api.signal) });
|
|
37
|
+
}
|
|
38
|
+
async function requestTitle(api, signal) {
|
|
39
|
+
const view = await api.session.view();
|
|
40
|
+
const model = view.configuration.effective?.model;
|
|
41
|
+
const conversation = transcript(view.messages);
|
|
42
|
+
if (model === undefined)
|
|
43
|
+
throw new Error("The chat has no model to title it.");
|
|
44
|
+
if (conversation === "")
|
|
45
|
+
throw new Error("Send a message before titling the chat.");
|
|
46
|
+
const outcome = await api.request({
|
|
47
|
+
model,
|
|
48
|
+
system: TITLE_PROMPT,
|
|
49
|
+
messages: [{ role: "user", content: conversation, timestamp: Date.now() }],
|
|
50
|
+
maxOutput: 64,
|
|
51
|
+
signal
|
|
52
|
+
});
|
|
53
|
+
dev("rename", "title", { session: api.session.id, outcome: outcome.kind });
|
|
54
|
+
if (outcome.kind === "refused")
|
|
55
|
+
throw new Error(outcome.reason);
|
|
56
|
+
if (outcome.kind === "failed")
|
|
57
|
+
throw new Error(outcome.failure.message);
|
|
58
|
+
const name = outcome.value.split(`
|
|
59
|
+
`).find((line) => line.trim() !== "")?.trim().slice(0, NAME_LIMIT);
|
|
60
|
+
if (name === undefined)
|
|
61
|
+
throw new Error("The model answered with no title.");
|
|
62
|
+
return name;
|
|
63
|
+
}
|
|
64
|
+
function transcript(messages) {
|
|
65
|
+
return messages.flatMap((message) => {
|
|
66
|
+
if (message.kind === "user") {
|
|
67
|
+
const words = typeof message.content === "string" ? message.content : message.content.flatMap((block) => block.kind === "text" ? [block.text] : []).join(" ");
|
|
68
|
+
return [`User: ${words}`];
|
|
69
|
+
}
|
|
70
|
+
return isPart(message, text) ? [`Assistant: ${message.state.markdown}`] : [];
|
|
71
|
+
}).join(`
|
|
72
|
+
|
|
73
|
+
`).slice(0, 4000);
|
|
74
|
+
}
|
|
75
|
+
export {
|
|
76
|
+
TITLE_PROMPT,
|
|
77
|
+
rename_default as default
|
|
78
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { SettingDefinition } from "@nyte-ai/core";
|
|
2
|
+
/**
|
|
3
|
+
* Exports one span per model request to an OTLP/HTTP traces endpoint, the
|
|
4
|
+
* host setting `telemetry.endpoint`; empty, the default, exports nothing.
|
|
5
|
+
* The span runs from the request's start to its settlement and carries the
|
|
6
|
+
* model, step, thinking level, session, run and token usage. Each session
|
|
7
|
+
* follows the setting as it changes, and sessions on one endpoint share one
|
|
8
|
+
* tracer provider (§48h).
|
|
9
|
+
*
|
|
10
|
+
* @category plugins
|
|
11
|
+
* @since 0.1.0
|
|
12
|
+
*/
|
|
13
|
+
declare const _default: {
|
|
14
|
+
id: string;
|
|
15
|
+
contribute: {
|
|
16
|
+
settings: SettingDefinition<string>[];
|
|
17
|
+
};
|
|
18
|
+
activate(api: {
|
|
19
|
+
readonly side: "core";
|
|
20
|
+
readonly sdk: import("@nyte-ai/core").Connection;
|
|
21
|
+
readonly contribute: import("@nyte-ai/core").Registries<"core">;
|
|
22
|
+
readonly storage: import("@nyte-ai/core").PluginStorage;
|
|
23
|
+
readonly signal: AbortSignal;
|
|
24
|
+
hook<N extends "session_activated" | "before_send" | "run_started" | "transform_transcript" | "before_compaction" | "before_request" | "before_tool" | "after_tool" | "after_request" | "run_ended">(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
|
|
25
|
+
report(issue: import("@nyte-ai/schema").ValidationIssue): void;
|
|
26
|
+
reload(): void;
|
|
27
|
+
} & {
|
|
28
|
+
readonly session: import("@nyte-ai/core").Session;
|
|
29
|
+
readonly env: import("@nyte-ai/core").ExecutionEnv;
|
|
30
|
+
wrapEnv(wrap: import("@nyte-ai/core").EnvironmentWrap): import("@nyte-ai/schema").Disposer;
|
|
31
|
+
readonly inputs: import("@nyte-ai/core").Resources;
|
|
32
|
+
request<T = string>(input: import("@nyte-ai/schema").ModelRequestInput<T>): Promise<import("@nyte-ai/schema").ModelRequestOutcome<T>>;
|
|
33
|
+
approve(call: import("@nyte-ai/core").RuntimeCall, signal: AbortSignal): Promise<import("@nyte-ai/core").RuntimeVerdict>;
|
|
34
|
+
}): void;
|
|
35
|
+
};
|
|
36
|
+
export default _default;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// src/telemetry.ts
|
|
2
|
+
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
3
|
+
import { resourceFromAttributes } from "@opentelemetry/resources";
|
|
4
|
+
import { SimpleSpanProcessor, TracerProvider } from "@opentelemetry/sdk-trace";
|
|
5
|
+
import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
|
|
6
|
+
import { dev } from "@nyte-ai/core";
|
|
7
|
+
import { standard } from "@nyte-ai/schema";
|
|
8
|
+
import { Type } from "typebox";
|
|
9
|
+
var endpoint = {
|
|
10
|
+
id: "telemetry.endpoint",
|
|
11
|
+
label: "OTLP traces endpoint",
|
|
12
|
+
schema: standard(Type.String()),
|
|
13
|
+
default: "",
|
|
14
|
+
scope: "host"
|
|
15
|
+
};
|
|
16
|
+
var providers = new Map;
|
|
17
|
+
function hold(url) {
|
|
18
|
+
const known = providers.get(url);
|
|
19
|
+
const provider = known?.provider ?? new TracerProvider({
|
|
20
|
+
resource: resourceFromAttributes({ [ATTR_SERVICE_NAME]: "nyte" }),
|
|
21
|
+
spanProcessors: [new SimpleSpanProcessor({ exporter: new OTLPTraceExporter({ url }) })]
|
|
22
|
+
});
|
|
23
|
+
const held = known ?? {
|
|
24
|
+
provider,
|
|
25
|
+
tracer: provider.getTracer("@nyte-ai/plugin/core/telemetry"),
|
|
26
|
+
holders: 0
|
|
27
|
+
};
|
|
28
|
+
held.holders += 1;
|
|
29
|
+
providers.set(url, held);
|
|
30
|
+
let released = false;
|
|
31
|
+
return {
|
|
32
|
+
tracer: held.tracer,
|
|
33
|
+
release() {
|
|
34
|
+
if (released)
|
|
35
|
+
return;
|
|
36
|
+
released = true;
|
|
37
|
+
held.holders -= 1;
|
|
38
|
+
if (held.holders > 0)
|
|
39
|
+
return;
|
|
40
|
+
providers.delete(url);
|
|
41
|
+
held.provider.shutdown();
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
var telemetry_default = {
|
|
46
|
+
id: "telemetry",
|
|
47
|
+
contribute: { settings: [endpoint] },
|
|
48
|
+
activate(api) {
|
|
49
|
+
let current = null;
|
|
50
|
+
api.hook("after_request", (event, { session, run }) => {
|
|
51
|
+
const end = Date.now();
|
|
52
|
+
current?.tracer.startSpan(`${event.step} ${event.model.provider}/${event.model.id}`, {
|
|
53
|
+
startTime: end - event.durationMs,
|
|
54
|
+
attributes: {
|
|
55
|
+
"gen_ai.provider.name": event.model.provider,
|
|
56
|
+
"gen_ai.request.model": event.model.id,
|
|
57
|
+
"gen_ai.usage.input_tokens": event.usage.input,
|
|
58
|
+
"gen_ai.usage.output_tokens": event.usage.output,
|
|
59
|
+
"nyte.step": event.step,
|
|
60
|
+
"nyte.thinking": event.thinking,
|
|
61
|
+
"nyte.session": session ?? "",
|
|
62
|
+
"nyte.run": run ?? "",
|
|
63
|
+
"nyte.cost": event.usage.cost.total
|
|
64
|
+
}
|
|
65
|
+
}).end(end);
|
|
66
|
+
});
|
|
67
|
+
(async () => {
|
|
68
|
+
for await (const url of api.contribute.settings.watch(endpoint.id)) {
|
|
69
|
+
current?.release();
|
|
70
|
+
current = typeof url === "string" && url !== "" ? hold(url) : null;
|
|
71
|
+
dev("telemetry", "endpoint", {
|
|
72
|
+
session: api.session.id,
|
|
73
|
+
exporting: current !== null,
|
|
74
|
+
providers: providers.size
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
current?.release();
|
|
78
|
+
current = null;
|
|
79
|
+
})();
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
export {
|
|
83
|
+
telemetry_default as default
|
|
84
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { Command, SettingDefinition } from "@nyte-ai/core";
|
|
2
|
+
/**
|
|
3
|
+
* Names a search provider the `web_search` tool can route to.
|
|
4
|
+
*
|
|
5
|
+
* @category plugins
|
|
6
|
+
* @since 0.1.0
|
|
7
|
+
*/
|
|
8
|
+
export type SearchProvider = (typeof PROVIDERS)[number];
|
|
9
|
+
declare const PROVIDERS: readonly ["exa", "tavily", "firecrawl", "parallel"];
|
|
10
|
+
/**
|
|
11
|
+
* Returns one search hit as the tool reports it.
|
|
12
|
+
*
|
|
13
|
+
* @category plugins
|
|
14
|
+
* @since 0.1.0
|
|
15
|
+
*/
|
|
16
|
+
export interface SearchResult {
|
|
17
|
+
readonly url: string;
|
|
18
|
+
readonly title: string | null;
|
|
19
|
+
readonly content: string | null;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Returns what one adapter call needs: the query, the provider's key or
|
|
23
|
+
* undefined for its keyless route, the fetch to send with, and a signal.
|
|
24
|
+
*
|
|
25
|
+
* @category plugins
|
|
26
|
+
* @since 0.1.0
|
|
27
|
+
*/
|
|
28
|
+
export interface SearchInput {
|
|
29
|
+
readonly query: string;
|
|
30
|
+
readonly key: string | undefined;
|
|
31
|
+
readonly fetch: typeof globalThis.fetch;
|
|
32
|
+
readonly signal: AbortSignal;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* One adapter per provider: Tavily over its REST endpoint, the others over
|
|
36
|
+
* one stateless MCP `tools/call` to their public route. Each sends through
|
|
37
|
+
* the given fetch only and returns the hits it recognised.
|
|
38
|
+
*
|
|
39
|
+
* @category plugins
|
|
40
|
+
* @since 0.1.0
|
|
41
|
+
*/
|
|
42
|
+
export declare const adapters: {
|
|
43
|
+
readonly [P in SearchProvider]: (input: SearchInput) => Promise<readonly SearchResult[]>;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Adds `web_search`, routed by the host setting `web_search.provider` to
|
|
47
|
+
* Tavily, Exa, Firecrawl or Parallel. A provider's key lives in the plugin's
|
|
48
|
+
* secrets under the provider's id, set with the `websearch-key` command; without one
|
|
49
|
+
* the provider's keyless route is used.
|
|
50
|
+
*
|
|
51
|
+
* @category plugins
|
|
52
|
+
* @since 0.1.0
|
|
53
|
+
*/
|
|
54
|
+
declare const _default: {
|
|
55
|
+
id: string;
|
|
56
|
+
contribute: {
|
|
57
|
+
settings: SettingDefinition<"exa" | "tavily" | "firecrawl" | "parallel">[];
|
|
58
|
+
commands: Command<keyof import("@nyte-ai/core").SideTable>[];
|
|
59
|
+
};
|
|
60
|
+
activate(api: {
|
|
61
|
+
readonly side: "core";
|
|
62
|
+
readonly sdk: import("@nyte-ai/core").Connection;
|
|
63
|
+
readonly contribute: import("@nyte-ai/core").Registries<"core">;
|
|
64
|
+
readonly storage: import("@nyte-ai/core").PluginStorage;
|
|
65
|
+
readonly signal: AbortSignal;
|
|
66
|
+
hook<N extends "session_activated" | "before_send" | "run_started" | "transform_transcript" | "before_compaction" | "before_request" | "before_tool" | "after_tool" | "after_request" | "run_ended">(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
|
|
67
|
+
report(issue: import("@nyte-ai/schema").ValidationIssue): void;
|
|
68
|
+
reload(): void;
|
|
69
|
+
} & {
|
|
70
|
+
readonly session: import("@nyte-ai/core").Session;
|
|
71
|
+
readonly env: import("@nyte-ai/core").ExecutionEnv;
|
|
72
|
+
wrapEnv(wrap: import("@nyte-ai/core").EnvironmentWrap): import("@nyte-ai/schema").Disposer;
|
|
73
|
+
readonly inputs: import("@nyte-ai/core").Resources;
|
|
74
|
+
request<T = string>(input: import("@nyte-ai/schema").ModelRequestInput<T>): Promise<import("@nyte-ai/schema").ModelRequestOutcome<T>>;
|
|
75
|
+
approve(call: import("@nyte-ai/core").RuntimeCall, signal: AbortSignal): Promise<import("@nyte-ai/core").RuntimeVerdict>;
|
|
76
|
+
}): void;
|
|
77
|
+
};
|
|
78
|
+
export default _default;
|