@nyte-ai/plugin 0.0.18 → 0.0.19
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 +66 -0
- package/dist/chunks/billing-4vz9pxyx.js +22 -0
- package/dist/chunks/{billing-k2p1t25n.js → billing-hg64tqf1.js} +10 -22
- package/dist/chunks/{billing-wmkxkypm.js → billing-tm34gm2p.js} +2 -1
- package/dist/chunks/{billing-9mfedmsh.js → billing-v3hg5rc7.js} +2 -2
- package/dist/src/acp/connection.js +1 -1
- package/dist/src/acp/index.js +3 -2
- package/dist/src/acp/registry.js +2 -1
- package/dist/src/claude-code-sdk/index.js +15 -4
- package/dist/src/claude-code-sdk/session.d.ts +2 -0
- package/dist/src/claude-code-sdk/session.js +1 -1
- package/dist/src/client/notifications.d.ts +3 -2
- package/dist/src/client/notifications.js +1 -3
- package/dist/src/client/presentation.d.ts +27 -1
- package/dist/src/client/presentation.js +19 -1
- package/dist/src/find-on-path.d.ts +4 -0
- package/dist/src/find-on-path.js +8 -0
- package/dist/src/rename.d.ts +30 -29
- package/dist/src/rename.js +20 -7
- package/package.json +5 -5
package/THIRD-PARTY-NOTICES.md
CHANGED
|
@@ -91,6 +91,9 @@ SOFTWARE.
|
|
|
91
91
|
- Transcript reconciliation, checkpoint instruction snapshots, provider system
|
|
92
92
|
updates, and cache warming are ported from the 1.0.0 release commit
|
|
93
93
|
`a13d35a742c6ef8462812a28fbe1d8c8b7431c32`.
|
|
94
|
+
- Fitting images to model limits (`packages/core/src/agent/images.ts` and
|
|
95
|
+
`packages/host/src/images`) is ported from `@earendil-works/pi-durable`'s
|
|
96
|
+
images at commit `73f8de80bc87021375f8b525292ac07492253002`.
|
|
94
97
|
|
|
95
98
|
License: MIT, with the following notice:
|
|
96
99
|
|
|
@@ -148,6 +151,16 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
148
151
|
THE SOFTWARE.
|
|
149
152
|
```
|
|
150
153
|
|
|
154
|
+
## Photon (`silvia-odwyer/photon`)
|
|
155
|
+
|
|
156
|
+
- Repository: https://github.com/silvia-odwyer/photon
|
|
157
|
+
- Package: `@silvia-odwyer/photon` 0.3.3
|
|
158
|
+
- What: the host decodes, orients, scales and re-encodes images for the model
|
|
159
|
+
with Photon's WebAssembly build.
|
|
160
|
+
|
|
161
|
+
License: Apache License 2.0, reproduced in the appendix below. Copyright 2023
|
|
162
|
+
Silvia O'Dwyer.
|
|
163
|
+
|
|
151
164
|
## Pierre
|
|
152
165
|
|
|
153
166
|
- Repository: https://github.com/pierrecomputer/pierre
|
|
@@ -561,6 +574,59 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
561
574
|
SOFTWARE.
|
|
562
575
|
```
|
|
563
576
|
|
|
577
|
+
## snapcn (`snapcndev/snapcn`)
|
|
578
|
+
|
|
579
|
+
- Repository: https://github.com/snapcndev/snapcn
|
|
580
|
+
- What: the launch film's Logo Flicker and Check Cycle scenes
|
|
581
|
+
(`packages/lab/video/src/snap-cn/`) are adapted from snapcn's registry
|
|
582
|
+
components at commit `47ee435f17d85f74abf48b095b40d64fc9616fb0`.
|
|
583
|
+
|
|
584
|
+
License: MIT, with the following notice:
|
|
585
|
+
|
|
586
|
+
```text
|
|
587
|
+
MIT License
|
|
588
|
+
|
|
589
|
+
Copyright (c) 2026 Sri Nath (snap-cn)
|
|
590
|
+
|
|
591
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
592
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
593
|
+
in the Software without restriction, including without limitation the rights
|
|
594
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
595
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
596
|
+
furnished to do so, subject to the following conditions:
|
|
597
|
+
|
|
598
|
+
The above copyright notice and this permission notice shall be included in all
|
|
599
|
+
copies or substantial portions of the Software.
|
|
600
|
+
|
|
601
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
602
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
603
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
604
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
605
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
606
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
607
|
+
SOFTWARE.
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
## Naybr, "Copyright Free Gameplay (No Commentary) - Minecraft Survival"
|
|
611
|
+
|
|
612
|
+
- Source: https://www.youtube.com/watch?v=GPsGyv5zTlM, by Naybr (youtube.com/@Naybr)
|
|
613
|
+
- What: the launch film opens on four shots from 0:30 to 2:30 of this video
|
|
614
|
+
(`clip` in `packages/lab/video/src/film/media.ts`). The footage is not in
|
|
615
|
+
the repository; `packages/lab/video/README.md` says how to fetch it.
|
|
616
|
+
|
|
617
|
+
License: Creative Commons Attribution, as published on YouTube. The author
|
|
618
|
+
allows use, modification, redistribution and monetisation, with this credit
|
|
619
|
+
wherever the gameplay is used: "Gameplay – youtube.com/@Naybr".
|
|
620
|
+
|
|
621
|
+
## Photographs in the launch film
|
|
622
|
+
|
|
623
|
+
- Source: Wikimedia Commons; each file's author and source page are listed in
|
|
624
|
+
`photos` in `packages/lab/video/src/film/media.ts`.
|
|
625
|
+
- What: eleven photographs the launch film cuts between. They are not in the
|
|
626
|
+
repository.
|
|
627
|
+
|
|
628
|
+
License: every one is public domain or CC0. None requires attribution.
|
|
629
|
+
|
|
564
630
|
## Design references
|
|
565
631
|
|
|
566
632
|
These credits record design sources. They do not grant a license to the
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// src/find-on-path.ts
|
|
2
|
+
import { constants } from "node:fs";
|
|
3
|
+
import { access } from "node:fs/promises";
|
|
4
|
+
import { delimiter, join } from "node:path";
|
|
5
|
+
async function executable2(path) {
|
|
6
|
+
try {
|
|
7
|
+
await access(path, constants.X_OK);
|
|
8
|
+
return true;
|
|
9
|
+
} catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
async function findOnPath2(name, path) {
|
|
14
|
+
const names = process.platform === "win32" ? [`${name}.exe`, `${name}.cmd`, name] : [name];
|
|
15
|
+
for (const dir of path.split(delimiter))
|
|
16
|
+
for (const candidate of names)
|
|
17
|
+
if (dir !== "" && await executable2(join(dir, candidate)))
|
|
18
|
+
return join(dir, candidate);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { executable2, findOnPath2 };
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
executable2,
|
|
3
|
+
findOnPath2
|
|
4
|
+
} from "./billing-4vz9pxyx.js";
|
|
5
|
+
|
|
1
6
|
// src/acp/registry.ts
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { basename, delimiter, dirname, join } from "node:path";
|
|
7
|
+
import { readFile, realpath } from "node:fs/promises";
|
|
8
|
+
import { basename, dirname, join } from "node:path";
|
|
5
9
|
import { Type } from "typebox";
|
|
6
10
|
import { Value } from "typebox/value";
|
|
7
11
|
var launch = {
|
|
@@ -29,22 +33,6 @@ function platformTarget() {
|
|
|
29
33
|
const arch = process.arch === "arm64" ? "aarch64" : process.arch === "x64" ? "x86_64" : process.arch;
|
|
30
34
|
return `${os}-${arch}`;
|
|
31
35
|
}
|
|
32
|
-
async function executable(path) {
|
|
33
|
-
try {
|
|
34
|
-
await access(path, constants.X_OK);
|
|
35
|
-
return true;
|
|
36
|
-
} catch {
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
async function findOnPath(name, path) {
|
|
41
|
-
const names = process.platform === "win32" ? [`${name}.exe`, `${name}.cmd`, name] : [name];
|
|
42
|
-
for (const dir of path.split(delimiter))
|
|
43
|
-
for (const candidate of names)
|
|
44
|
-
if (dir !== "" && await executable(join(dir, candidate)))
|
|
45
|
-
return join(dir, candidate);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
36
|
async function resolved(path) {
|
|
49
37
|
try {
|
|
50
38
|
return await realpath(path);
|
|
@@ -54,7 +42,7 @@ async function resolved(path) {
|
|
|
54
42
|
}
|
|
55
43
|
async function globalBin(spec, path) {
|
|
56
44
|
const name = PACKAGE.exec(spec)?.[1] ?? spec;
|
|
57
|
-
const npx = await
|
|
45
|
+
const npx = await findOnPath2("npx", path);
|
|
58
46
|
if (npx === undefined)
|
|
59
47
|
return;
|
|
60
48
|
const bin = dirname(npx);
|
|
@@ -79,12 +67,12 @@ async function globalBin(spec, path) {
|
|
|
79
67
|
}
|
|
80
68
|
const linked = join(bin, command);
|
|
81
69
|
const [from, to] = await Promise.all([resolved(linked), resolved(join(root, target))]);
|
|
82
|
-
return from !== undefined && from === to && await
|
|
70
|
+
return from !== undefined && from === to && await executable2(linked) ? linked : undefined;
|
|
83
71
|
}
|
|
84
72
|
async function installed(agent, path) {
|
|
85
73
|
const binary = agent.distribution.binary?.[platformTarget()];
|
|
86
74
|
if (binary !== undefined) {
|
|
87
|
-
const command = await
|
|
75
|
+
const command = await findOnPath2(basename(binary.cmd).replace(/\.exe$/, ""), path);
|
|
88
76
|
if (command !== undefined)
|
|
89
77
|
return {
|
|
90
78
|
id: agent.id,
|
|
@@ -164,7 +164,8 @@ class ClaudeCodeSession2 {
|
|
|
164
164
|
CLAUDE_AGENT_SDK_CLIENT_APP: "nyte",
|
|
165
165
|
CLAUDE_CODE_EMIT_SESSION_STATE_EVENTS: "1"
|
|
166
166
|
},
|
|
167
|
-
stderr: (chunk) => this.#stderr = (this.#stderr + chunk).slice(-4096)
|
|
167
|
+
stderr: (chunk) => this.#stderr = (this.#stderr + chunk).slice(-4096),
|
|
168
|
+
pathToClaudeCodeExecutable: launch.claude
|
|
168
169
|
};
|
|
169
170
|
if (launch.effort !== undefined)
|
|
170
171
|
options.effort = launch.effort;
|
|
@@ -15,7 +15,7 @@ import { processEnvironment } from "@nyte-ai/core";
|
|
|
15
15
|
// package.json
|
|
16
16
|
var package_default = {
|
|
17
17
|
name: "@nyte-ai/plugin",
|
|
18
|
-
version: "0.0.
|
|
18
|
+
version: "0.0.19",
|
|
19
19
|
private: false,
|
|
20
20
|
license: "MIT",
|
|
21
21
|
repository: {
|
|
@@ -195,7 +195,7 @@ var package_default = {
|
|
|
195
195
|
scripts: {
|
|
196
196
|
clean: "rm -rf node_modules .turbo",
|
|
197
197
|
test: "vitest --run",
|
|
198
|
-
typecheck: "
|
|
198
|
+
typecheck: "tsrs --noEmit",
|
|
199
199
|
"build:package": "bun ../../scripts/sdk-packages.mjs build plugin"
|
|
200
200
|
},
|
|
201
201
|
dependencies: {
|
package/dist/src/acp/index.js
CHANGED
|
@@ -8,11 +8,12 @@ import {
|
|
|
8
8
|
import"../../chunks/billing-svrhh5a5.js";
|
|
9
9
|
import {
|
|
10
10
|
AcpProcess2
|
|
11
|
-
} from "../../chunks/billing-
|
|
11
|
+
} from "../../chunks/billing-v3hg5rc7.js";
|
|
12
|
+
import"../../chunks/billing-4vz9pxyx.js";
|
|
12
13
|
import {
|
|
13
14
|
registryEntries2,
|
|
14
15
|
installedAgents2
|
|
15
|
-
} from "../../chunks/billing-
|
|
16
|
+
} from "../../chunks/billing-hg64tqf1.js";
|
|
16
17
|
import {
|
|
17
18
|
messageKey2,
|
|
18
19
|
userBlocks2,
|
package/dist/src/acp/registry.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
registryEntries2,
|
|
3
3
|
installedAgents2
|
|
4
|
-
} from "../../chunks/billing-
|
|
4
|
+
} from "../../chunks/billing-hg64tqf1.js";
|
|
5
|
+
import"../../chunks/billing-4vz9pxyx.js";
|
|
5
6
|
export {
|
|
6
7
|
installedAgents2 as installedAgents,
|
|
7
8
|
registryEntries2 as registryEntries
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
findOnPath2
|
|
3
|
+
} from "../../chunks/billing-4vz9pxyx.js";
|
|
1
4
|
import {
|
|
2
5
|
answerInput2
|
|
3
6
|
} from "../../chunks/billing-6z2kgtyt.js";
|
|
@@ -13,7 +16,7 @@ import {
|
|
|
13
16
|
} from "../../chunks/billing-ye3wk5r3.js";
|
|
14
17
|
import {
|
|
15
18
|
ClaudeCodeSession2
|
|
16
|
-
} from "../../chunks/billing-
|
|
19
|
+
} from "../../chunks/billing-tm34gm2p.js";
|
|
17
20
|
import {
|
|
18
21
|
mirrorArguments3,
|
|
19
22
|
userBlocks3,
|
|
@@ -74,7 +77,13 @@ function effortFor(model, reasoning) {
|
|
|
74
77
|
const mapped = model.thinkingLevelMap?.[level] ?? level;
|
|
75
78
|
return EFFORTS.find((effort) => effort === mapped) ?? (level === "minimal" ? "low" : undefined);
|
|
76
79
|
}
|
|
80
|
+
async function findClaudeCode() {
|
|
81
|
+
await processEnvironment();
|
|
82
|
+
return await findOnPath2("claude", process.env.PATH ?? "");
|
|
83
|
+
}
|
|
77
84
|
async function claudeCodeConfigured() {
|
|
85
|
+
if (await findClaudeCode() === undefined)
|
|
86
|
+
return false;
|
|
78
87
|
try {
|
|
79
88
|
await access(process.env.CLAUDE_CONFIG_DIR ?? join(homedir(), ".claude"));
|
|
80
89
|
return true;
|
|
@@ -92,7 +101,7 @@ function answerOnce(start, model, context, options) {
|
|
|
92
101
|
(async () => {
|
|
93
102
|
try {
|
|
94
103
|
stream.push({ type: "start", partial: output });
|
|
95
|
-
await
|
|
104
|
+
const claude = await findClaudeCode();
|
|
96
105
|
for await (const message of start({
|
|
97
106
|
prompt: flatPrompt2(context.messages),
|
|
98
107
|
options: {
|
|
@@ -106,7 +115,8 @@ function answerOnce(start, model, context, options) {
|
|
|
106
115
|
persistSession: false,
|
|
107
116
|
includePartialMessages: true,
|
|
108
117
|
thinking: { type: "disabled" },
|
|
109
|
-
env: { ...process.env, ...options?.env }
|
|
118
|
+
env: { ...process.env, ...options?.env },
|
|
119
|
+
pathToClaudeCodeExecutable: claude
|
|
110
120
|
}
|
|
111
121
|
})) {
|
|
112
122
|
if (message.type === "stream_event" && message.parent_tool_use_id === null)
|
|
@@ -267,7 +277,7 @@ function claudeCodeSdk(start = query) {
|
|
|
267
277
|
session?.close();
|
|
268
278
|
if (prompt.length === 0)
|
|
269
279
|
throw new Error(NOT_RUNNING);
|
|
270
|
-
await
|
|
280
|
+
const claude = await findClaudeCode();
|
|
271
281
|
const claudeSession = randomUUID();
|
|
272
282
|
session = new ClaudeCodeSession2({
|
|
273
283
|
key,
|
|
@@ -285,6 +295,7 @@ function claudeCodeSdk(start = query) {
|
|
|
285
295
|
}),
|
|
286
296
|
tools,
|
|
287
297
|
query: start,
|
|
298
|
+
claude,
|
|
288
299
|
approve: binding.approve
|
|
289
300
|
});
|
|
290
301
|
sessions.set(id, session);
|
|
@@ -13,6 +13,8 @@ interface Launch {
|
|
|
13
13
|
readonly history: readonly SessionStoreEntry[];
|
|
14
14
|
readonly tools: readonly Tool[];
|
|
15
15
|
readonly query: StartQuery;
|
|
16
|
+
/** The installed `claude` to run; without one the Agent SDK looks for its own. */
|
|
17
|
+
readonly claude: string | undefined;
|
|
16
18
|
readonly approve: Approve;
|
|
17
19
|
}
|
|
18
20
|
/** Decides a call Claude Code asks to run under Nyte's permissions policy, by the tool's own name. */
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { RunEnd } from "@nyte-ai/schema";
|
|
2
2
|
/**
|
|
3
3
|
* Tells the user when a run ends in any session this client can see:
|
|
4
|
-
* finished,
|
|
5
|
-
*
|
|
4
|
+
* finished, or failed with the reason. A stopped run stays quiet because
|
|
5
|
+
* someone asked for it, and so do sessions a parent spawned, so a delegation
|
|
6
|
+
* does not ring once per child.
|
|
6
7
|
*
|
|
7
8
|
* @category plugins
|
|
8
9
|
* @since 0.1.0
|
|
@@ -10,9 +10,7 @@ var notifications_default = {
|
|
|
10
10
|
const { end } = event;
|
|
11
11
|
if (end.kind === "completed")
|
|
12
12
|
api.ui.notify({ title, message: "Run finished", level: "info" });
|
|
13
|
-
else if (end.kind === "
|
|
14
|
-
api.ui.notify({ title, message: "Run stopped", level: "warning" });
|
|
15
|
-
else
|
|
13
|
+
else if (end.kind === "failed")
|
|
16
14
|
api.ui.notify({ title, message: `Run failed: ${line(end)}`, level: "error" });
|
|
17
15
|
}
|
|
18
16
|
}
|
|
@@ -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 } from "@nyte-ai/schema";
|
|
3
|
+
import type { Execution, Failure, HeadInfo, Message, MessageSource, SessionInfo, ToolClass, ToolPartState, UserContent, UserStatus } 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,6 +92,32 @@ 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;
|
|
95
121
|
/**
|
|
96
122
|
* What a user message shows: an action's label in place of the prompt it sent.
|
|
97
123
|
*
|
|
@@ -21,6 +21,23 @@ 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
|
+
}
|
|
24
41
|
function shownContent(message) {
|
|
25
42
|
return message.source.kind === "action" ? message.source.label : message.content;
|
|
26
43
|
}
|
|
@@ -369,5 +386,6 @@ export {
|
|
|
369
386
|
toolStatus,
|
|
370
387
|
toolSubject,
|
|
371
388
|
toolTitle,
|
|
372
|
-
toolVerbs
|
|
389
|
+
toolVerbs,
|
|
390
|
+
waitsInQueue
|
|
373
391
|
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Whether `path` is a file this process may run. */
|
|
2
|
+
export declare function executable(path: string): Promise<boolean>;
|
|
3
|
+
/** The first executable `name` in the directories of `path`, a `PATH`-style list. */
|
|
4
|
+
export declare function findOnPath(name: string, path: string): Promise<string | undefined>;
|
package/dist/src/rename.d.ts
CHANGED
|
@@ -8,12 +8,14 @@ import type { Command } from "@nyte-ai/plugin/core";
|
|
|
8
8
|
*/
|
|
9
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
10
|
/**
|
|
11
|
-
* Names an unnamed root session
|
|
12
|
-
* the
|
|
13
|
-
* session
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
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.
|
|
17
19
|
*
|
|
18
20
|
* @category plugins
|
|
19
21
|
* @since 0.1.0
|
|
@@ -24,31 +26,30 @@ declare const _default: {
|
|
|
24
26
|
commands: Command<"core">[];
|
|
25
27
|
};
|
|
26
28
|
hooks: {
|
|
27
|
-
|
|
28
|
-
readonly
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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;
|
|
29
|
+
run_started: (run: Readonly<{
|
|
30
|
+
readonly configuration: {
|
|
31
|
+
readonly model: {
|
|
32
|
+
readonly id: string;
|
|
33
|
+
readonly provider: string;
|
|
42
34
|
};
|
|
35
|
+
readonly thinking: "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
|
|
36
|
+
readonly kind: "exact";
|
|
37
|
+
readonly settings: {
|
|
38
|
+
readonly [x: string]: import("@nyte-ai/schema").Json;
|
|
39
|
+
};
|
|
40
|
+
readonly agent: string | null;
|
|
41
|
+
readonly settingsVersion: string;
|
|
43
42
|
};
|
|
44
|
-
|
|
45
|
-
readonly
|
|
46
|
-
|
|
47
|
-
readonly
|
|
48
|
-
readonly
|
|
49
|
-
readonly
|
|
50
|
-
readonly
|
|
51
|
-
|
|
43
|
+
readonly id: import("@nyte-ai/schema").Id<"run">;
|
|
44
|
+
readonly head: import("@nyte-ai/schema").Id<"head">;
|
|
45
|
+
readonly startedAt: number;
|
|
46
|
+
readonly attempt: number;
|
|
47
|
+
readonly origin: {
|
|
48
|
+
readonly message: import("@nyte-ai/schema").Id<"message">;
|
|
49
|
+
readonly kind: "input";
|
|
50
|
+
} | {
|
|
51
|
+
readonly kind: "continuation";
|
|
52
|
+
readonly from: "child" | "job" | "wake";
|
|
52
53
|
};
|
|
53
54
|
}>, { api }: {
|
|
54
55
|
readonly api: {
|
package/dist/src/rename.js
CHANGED
|
@@ -19,10 +19,12 @@ var rename_default = {
|
|
|
19
19
|
id: "rename",
|
|
20
20
|
contribute: { commands: [renameCommand] },
|
|
21
21
|
hooks: {
|
|
22
|
-
|
|
22
|
+
run_started: (run, { api }) => {
|
|
23
|
+
if (run.origin.kind !== "input")
|
|
24
|
+
return;
|
|
23
25
|
nameUnnamed(api).catch((error) => api.report({
|
|
24
26
|
severity: "warning",
|
|
25
|
-
path: ["
|
|
27
|
+
path: ["run_started"],
|
|
26
28
|
message: `Naming the session failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
27
29
|
source: { plugin: "rename" }
|
|
28
30
|
}));
|
|
@@ -33,7 +35,17 @@ async function nameUnnamed(api) {
|
|
|
33
35
|
const info = await api.session.info();
|
|
34
36
|
if (info.name !== null || info.parent !== null)
|
|
35
37
|
return;
|
|
36
|
-
await api.session.
|
|
38
|
+
const view = await api.session.view();
|
|
39
|
+
const words = view.messages.flatMap((message) => message.kind === "user" ? [userWords(message.content)] : [])[0];
|
|
40
|
+
const firstLine = words?.split(`
|
|
41
|
+
`).find((line) => line.trim() !== "")?.trim().slice(0, NAME_LIMIT);
|
|
42
|
+
if (firstLine === undefined)
|
|
43
|
+
return;
|
|
44
|
+
await api.session.update({ name: firstLine });
|
|
45
|
+
const title = await requestTitle(api, api.signal);
|
|
46
|
+
if ((await api.session.info()).name !== firstLine)
|
|
47
|
+
return;
|
|
48
|
+
await api.session.update({ name: title });
|
|
37
49
|
}
|
|
38
50
|
async function requestTitle(api, signal) {
|
|
39
51
|
const view = await api.session.view();
|
|
@@ -63,15 +75,16 @@ async function requestTitle(api, signal) {
|
|
|
63
75
|
}
|
|
64
76
|
function transcript(messages) {
|
|
65
77
|
return messages.flatMap((message) => {
|
|
66
|
-
if (message.kind === "user")
|
|
67
|
-
|
|
68
|
-
return [`User: ${words}`];
|
|
69
|
-
}
|
|
78
|
+
if (message.kind === "user")
|
|
79
|
+
return [`User: ${userWords(message.content)}`];
|
|
70
80
|
return isPart(message, text) ? [`Assistant: ${message.state.markdown}`] : [];
|
|
71
81
|
}).join(`
|
|
72
82
|
|
|
73
83
|
`).slice(0, 4000);
|
|
74
84
|
}
|
|
85
|
+
function userWords(content) {
|
|
86
|
+
return typeof content === "string" ? content : content.flatMap((block) => block.kind === "text" ? [block.text] : []).join(" ");
|
|
87
|
+
}
|
|
75
88
|
export {
|
|
76
89
|
TITLE_PROMPT,
|
|
77
90
|
rename_default as default
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nyte-ai/plugin",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.19",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -148,9 +148,9 @@
|
|
|
148
148
|
"@agentclientprotocol/sdk": "1.9.0",
|
|
149
149
|
"@anthropic-ai/claude-agent-sdk": "0.3.296",
|
|
150
150
|
"@earendil-works/pi-codemode": "1.0.0",
|
|
151
|
-
"@nyte-ai/ai": "0.0.
|
|
152
|
-
"@nyte-ai/core": "0.0.
|
|
153
|
-
"@nyte-ai/schema": "0.0.
|
|
151
|
+
"@nyte-ai/ai": "0.0.19",
|
|
152
|
+
"@nyte-ai/core": "0.0.19",
|
|
153
|
+
"@nyte-ai/schema": "0.0.19",
|
|
154
154
|
"@opentelemetry/api": "^1.9.1",
|
|
155
155
|
"@opentelemetry/exporter-trace-otlp-http": "^0.223.0",
|
|
156
156
|
"@opentelemetry/resources": "^2.12.0",
|
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
"scripts": {
|
|
188
188
|
"clean": "rm -rf node_modules .turbo",
|
|
189
189
|
"test": "vitest --run",
|
|
190
|
-
"typecheck": "
|
|
190
|
+
"typecheck": "tsrs --noEmit",
|
|
191
191
|
"build:package": "bun ../../scripts/sdk-packages.mjs build plugin"
|
|
192
192
|
}
|
|
193
193
|
}
|