neodrop-cli 2.0.0 → 2.0.1
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/SKILL.md +1 -1
- package/bin/neodrop.mjs +5 -6
- package/lib/chat.mjs +44 -8
- package/package.json +1 -1
package/SKILL.md
CHANGED
package/bin/neodrop.mjs
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import { hostname } from "node:os";
|
|
15
15
|
import { parseArgs } from "node:util";
|
|
16
16
|
import { ApiError, trpcMutation, trpcQuery } from "../lib/api.mjs";
|
|
17
|
-
import { resolveChatSession, sendAndAwaitReply } from "../lib/chat.mjs";
|
|
17
|
+
import { resolveChatSession, sendAndAwaitReply, slimMessage } from "../lib/chat.mjs";
|
|
18
18
|
import {
|
|
19
19
|
clearCredentials,
|
|
20
20
|
credentialsPath,
|
|
@@ -572,11 +572,10 @@ async function cmdChatHistory(argv) {
|
|
|
572
572
|
throw new UsageError("Usage: neodrop chat history --session <id>");
|
|
573
573
|
}
|
|
574
574
|
const { apiOrigin, token } = authedCtx();
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
);
|
|
575
|
+
const messages = await trpcQuery({ apiOrigin, token }, "session.getMessages", {
|
|
576
|
+
sessionId: values.session,
|
|
577
|
+
});
|
|
578
|
+
emit(messages.map(slimMessage));
|
|
580
579
|
}
|
|
581
580
|
|
|
582
581
|
async function cmdChatSessions() {
|
package/lib/chat.mjs
CHANGED
|
@@ -106,6 +106,43 @@ function extractText(parts) {
|
|
|
106
106
|
.join("");
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
// Noise the raw message payload carries but a CLI consumer never needs: multi-KB
|
|
110
|
+
// provider signatures, provider metadata, and per-call execution plumbing.
|
|
111
|
+
const NOISE_KEYS = new Set([
|
|
112
|
+
"providerMetadata",
|
|
113
|
+
"callProviderMetadata",
|
|
114
|
+
"resultProviderMetadata",
|
|
115
|
+
"signature",
|
|
116
|
+
"startedAt",
|
|
117
|
+
"finishedAt",
|
|
118
|
+
"durationMs",
|
|
119
|
+
"stepNumber",
|
|
120
|
+
"toolCallId",
|
|
121
|
+
]);
|
|
122
|
+
|
|
123
|
+
function stripNoise(value) {
|
|
124
|
+
if (Array.isArray(value)) return value.map(stripNoise);
|
|
125
|
+
if (value && typeof value === "object") {
|
|
126
|
+
const out = {};
|
|
127
|
+
for (const [k, v] of Object.entries(value)) {
|
|
128
|
+
if (NOISE_KEYS.has(k)) continue;
|
|
129
|
+
out[k] = stripNoise(v);
|
|
130
|
+
}
|
|
131
|
+
return out;
|
|
132
|
+
}
|
|
133
|
+
return value;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Slim a message for output: drop chain-of-thought `reasoning` parts (internal
|
|
137
|
+
// thinking, not the answer) and strip the noise keys above from what remains.
|
|
138
|
+
export function slimMessage(m) {
|
|
139
|
+
const cleaned = stripNoise(m);
|
|
140
|
+
if (Array.isArray(cleaned.parts)) {
|
|
141
|
+
cleaned.parts = cleaned.parts.filter((p) => p && p.type !== "reasoning");
|
|
142
|
+
}
|
|
143
|
+
return cleaned;
|
|
144
|
+
}
|
|
145
|
+
|
|
109
146
|
/**
|
|
110
147
|
* Send one message and wait for the complete reply.
|
|
111
148
|
*
|
|
@@ -163,17 +200,16 @@ export async function sendAndAwaitReply({
|
|
|
163
200
|
// as tool / data cards).
|
|
164
201
|
const fresh = messages.filter((m) => !beforeIds.has(m.id));
|
|
165
202
|
const lastUserIdx = fresh.map((m) => m.role).lastIndexOf("user");
|
|
166
|
-
const
|
|
167
|
-
const lastAssistant = [...
|
|
168
|
-
.reverse()
|
|
169
|
-
.find((m) => m.role === "assistant");
|
|
203
|
+
const turn = lastUserIdx >= 0 ? fresh.slice(lastUserIdx + 1) : fresh;
|
|
204
|
+
const lastAssistant = [...turn].reverse().find((m) => m.role === "assistant");
|
|
170
205
|
|
|
171
206
|
return {
|
|
172
207
|
sessionId,
|
|
173
|
-
reply
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
208
|
+
// reply.text is the assistant's final text — empty when it only asked a
|
|
209
|
+
// clarifying question via a tool (read newMessages then). The structured
|
|
210
|
+
// content lives in newMessages, so reply carries just the text (no dup).
|
|
211
|
+
reply: lastAssistant ? { text: extractText(lastAssistant.parts) } : null,
|
|
212
|
+
newMessages: turn.map(slimMessage),
|
|
177
213
|
};
|
|
178
214
|
}
|
|
179
215
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neodrop-cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Neodrop (neodrop.ai) CLI — let your AI agent (Claude Code / Cursor / Codex) browse channels, read posts, manage subscriptions, create channels and chat with Neodrop's AI assistants as you. stdout is always valid JSON. npx neodrop-cli login and go.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|