@meetopenbot/claude-code 0.1.15 → 0.1.17
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/dist/index.js +119 -41
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -29,13 +29,12 @@ var resolveClaudeConfig = (context) => {
|
|
|
29
29
|
import { execSync } from "node:child_process";
|
|
30
30
|
import { existsSync } from "node:fs";
|
|
31
31
|
import { join } from "node:path";
|
|
32
|
-
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
33
32
|
import {
|
|
34
|
-
creditsErrorMessage,
|
|
35
33
|
llmAuthNotConfiguredMessage,
|
|
36
34
|
resolveByokApiKey,
|
|
37
35
|
resolveCreditsAuthConfig as resolveCreditsAuthConfig2,
|
|
38
|
-
isCloudMode
|
|
36
|
+
isCloudMode,
|
|
37
|
+
textReply as textReply2
|
|
39
38
|
} from "@meetopenbot/plugin-sdk";
|
|
40
39
|
|
|
41
40
|
// src/credits.ts
|
|
@@ -62,6 +61,109 @@ var buildCreditsAnthropicEnv = () => {
|
|
|
62
61
|
import { threadSession } from "@meetopenbot/plugin-sdk";
|
|
63
62
|
var claudeSession = threadSession("claudeSessionId");
|
|
64
63
|
|
|
64
|
+
// src/stream.ts
|
|
65
|
+
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
66
|
+
import {
|
|
67
|
+
createTextReplyBuffer,
|
|
68
|
+
creditsErrorMessage,
|
|
69
|
+
textReply
|
|
70
|
+
} from "@meetopenbot/plugin-sdk";
|
|
71
|
+
var extractText = (content) => {
|
|
72
|
+
if (typeof content === "string") return content;
|
|
73
|
+
if (!Array.isArray(content)) return "";
|
|
74
|
+
const parts = [];
|
|
75
|
+
for (const block of content) {
|
|
76
|
+
if (block && typeof block === "object" && block.type === "text") {
|
|
77
|
+
const text = block.text;
|
|
78
|
+
if (typeof text === "string" && text) parts.push(text);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return parts.join("\n");
|
|
82
|
+
};
|
|
83
|
+
var streamEventText = (event) => {
|
|
84
|
+
if (!event || typeof event !== "object") return "";
|
|
85
|
+
const delta = event.delta;
|
|
86
|
+
if (delta?.type === "text_delta" && typeof delta.text === "string") return delta.text;
|
|
87
|
+
return "";
|
|
88
|
+
};
|
|
89
|
+
var parseToolUse = (block) => {
|
|
90
|
+
if (!block || typeof block !== "object" || !("type" in block)) return null;
|
|
91
|
+
const type = block.type;
|
|
92
|
+
if (type !== "tool_use" && type !== "mcp_tool_use" && type !== "server_tool_use") return null;
|
|
93
|
+
const { id, name, input, server_name } = block;
|
|
94
|
+
if (typeof id !== "string" || typeof name !== "string") return null;
|
|
95
|
+
const title = typeof server_name === "string" ? `${server_name}: ${name}` : name;
|
|
96
|
+
return { type: "tool_call", id, name: title, input };
|
|
97
|
+
};
|
|
98
|
+
var parseToolResult = (block) => {
|
|
99
|
+
if (!block || typeof block !== "object" || !("type" in block)) return null;
|
|
100
|
+
const type = block.type;
|
|
101
|
+
if (type !== "tool_result" && type !== "mcp_tool_result") return null;
|
|
102
|
+
const { tool_use_id, content, is_error } = block;
|
|
103
|
+
if (typeof tool_use_id !== "string") return null;
|
|
104
|
+
return { type: "tool_result", id: tool_use_id, output: content, error: is_error };
|
|
105
|
+
};
|
|
106
|
+
var classifyClaudeEvent = (message) => {
|
|
107
|
+
if (message.type === "assistant") {
|
|
108
|
+
const content = message.message?.content;
|
|
109
|
+
const hints = [];
|
|
110
|
+
const text = extractText(content);
|
|
111
|
+
if (text) hints.push({ type: "text", text });
|
|
112
|
+
if (Array.isArray(content)) {
|
|
113
|
+
for (const block of content) {
|
|
114
|
+
const tool = parseToolUse(block);
|
|
115
|
+
if (tool) hints.push(tool);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return hints.length > 0 ? hints : { type: "skip" };
|
|
119
|
+
}
|
|
120
|
+
if (message.type === "user") {
|
|
121
|
+
const content = message.message?.content;
|
|
122
|
+
if (!Array.isArray(content)) return { type: "skip" };
|
|
123
|
+
const hints = [];
|
|
124
|
+
for (const block of content) {
|
|
125
|
+
const result = parseToolResult(block);
|
|
126
|
+
if (result) hints.push(result);
|
|
127
|
+
}
|
|
128
|
+
return hints.length > 0 ? hints : { type: "skip" };
|
|
129
|
+
}
|
|
130
|
+
if (message.type === "stream_event") {
|
|
131
|
+
const text = streamEventText(message.event);
|
|
132
|
+
return text ? { type: "delta", text } : { type: "skip" };
|
|
133
|
+
}
|
|
134
|
+
return { type: "skip" };
|
|
135
|
+
};
|
|
136
|
+
async function* runClaudeQuery(args) {
|
|
137
|
+
const { prompt, sdkOptions, resumeId, state, storage } = args;
|
|
138
|
+
const replies = createTextReplyBuffer({ groupId: "claude-code:tools" });
|
|
139
|
+
let lastSessionId = resumeId;
|
|
140
|
+
try {
|
|
141
|
+
for await (const message of query({ prompt, options: sdkOptions })) {
|
|
142
|
+
if ("session_id" in message && typeof message.session_id === "string") {
|
|
143
|
+
lastSessionId = message.session_id;
|
|
144
|
+
}
|
|
145
|
+
if (message.type === "result" && message.subtype !== "success") {
|
|
146
|
+
yield* replies.end();
|
|
147
|
+
const resultText = "result" in message && typeof message.result === "string" ? message.result : message.subtype;
|
|
148
|
+
yield textReply(
|
|
149
|
+
creditsErrorMessage(resultText, {
|
|
150
|
+
agentName: "Claude",
|
|
151
|
+
providerLabel: "Anthropic",
|
|
152
|
+
provider: "anthropic"
|
|
153
|
+
}) ?? resultText
|
|
154
|
+
);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
yield* replies.apply(classifyClaudeEvent(message));
|
|
158
|
+
}
|
|
159
|
+
yield* replies.end();
|
|
160
|
+
} finally {
|
|
161
|
+
if (lastSessionId && lastSessionId !== resumeId) {
|
|
162
|
+
await claudeSession.write(state, storage, lastSessionId);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
65
167
|
// src/system-prompt.ts
|
|
66
168
|
var CLAUDE_CODE_SYSTEM_PROMPT = `
|
|
67
169
|
You are Claude, an AI assistant powered by Anthropic's Claude Agent SDK (Claude Code).
|
|
@@ -83,23 +185,16 @@ var findClaudeExecutable = () => {
|
|
|
83
185
|
}
|
|
84
186
|
return void 0;
|
|
85
187
|
};
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (block && typeof block === "object" && block.type === "text") {
|
|
92
|
-
const text = block.text;
|
|
93
|
-
if (typeof text === "string" && text) parts.push(text);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return parts.join("\n");
|
|
97
|
-
};
|
|
98
|
-
async function runClaudeTurn({ prompt, handlerCtx, context }) {
|
|
188
|
+
async function* runClaudeTurn({
|
|
189
|
+
prompt,
|
|
190
|
+
handlerCtx,
|
|
191
|
+
context
|
|
192
|
+
}) {
|
|
99
193
|
const byok = resolveByokApiKey("anthropic");
|
|
100
194
|
const credits = !byok && isCloudMode() ? resolveCreditsAuthConfig2() : void 0;
|
|
101
195
|
if (!byok && !credits) {
|
|
102
|
-
|
|
196
|
+
yield textReply2(llmAuthNotConfiguredMessage("ANTHROPIC_API_KEY"));
|
|
197
|
+
return;
|
|
103
198
|
}
|
|
104
199
|
const config = resolveClaudeConfig(context);
|
|
105
200
|
const workingDir = handlerCtx.state.channelDetails?.cwd;
|
|
@@ -122,30 +217,13 @@ async function runClaudeTurn({ prompt, handlerCtx, context }) {
|
|
|
122
217
|
...workingDir ? { cwd: workingDir } : {},
|
|
123
218
|
...executablePath ? { pathToClaudeCodeExecutable: executablePath } : {}
|
|
124
219
|
};
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const next = extractText(message.message?.content);
|
|
133
|
-
if (next) text = text ? `${text}
|
|
134
|
-
${next}` : next;
|
|
135
|
-
}
|
|
136
|
-
if (message.type === "result" && message.subtype !== "success") {
|
|
137
|
-
const resultText = "result" in message && typeof message.result === "string" ? message.result : message.subtype;
|
|
138
|
-
return creditsErrorMessage(resultText, {
|
|
139
|
-
agentName: "Claude",
|
|
140
|
-
providerLabel: "Anthropic",
|
|
141
|
-
provider: "anthropic"
|
|
142
|
-
}) ?? resultText;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
if (lastSessionId && lastSessionId !== resumeId) {
|
|
146
|
-
await claudeSession.write(handlerCtx.state, context.storage, lastSessionId);
|
|
147
|
-
}
|
|
148
|
-
return text.trim();
|
|
220
|
+
yield* runClaudeQuery({
|
|
221
|
+
prompt,
|
|
222
|
+
sdkOptions,
|
|
223
|
+
resumeId,
|
|
224
|
+
state: handlerCtx.state,
|
|
225
|
+
storage: context.storage
|
|
226
|
+
});
|
|
149
227
|
}
|
|
150
228
|
|
|
151
229
|
// src/index.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meetopenbot/claude-code",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Claude Code plugin for OpenBot",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@anthropic-ai/claude-agent-sdk": "^0.2.138",
|
|
22
|
-
"@meetopenbot/plugin-sdk": "^0.
|
|
22
|
+
"@meetopenbot/plugin-sdk": "^0.5.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@types/node": "^20.10.1",
|