agent-sh 0.12.25 → 0.12.27

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.
@@ -4,9 +4,7 @@
4
4
  * Provides two tools:
5
5
  * - web_search: Search the web via Exa MCP (free, no API key)
6
6
  * - web_fetch: Extract page content as clean markdown
7
- * Fallback chain: Z.AI reader → Jina Reader → direct fetch
8
- *
9
- * Optional: ZAI_API_KEY environment variable (for Z.AI reader, best quality)
7
+ * Fallback chain: Jina Reader → direct fetch
10
8
  *
11
9
  * Optional configuration (~/.agent-sh/settings.json):
12
10
  * {
@@ -24,9 +22,6 @@ import type { ExtensionContext } from "agent-sh/types";
24
22
 
25
23
  const EXA_MCP_URL = "https://mcp.exa.ai/mcp";
26
24
 
27
- const ZAI_BASE = "https://api.z.ai";
28
- const ZAI_READER_PATH = "/api/mcp/web_reader/mcp";
29
-
30
25
  const JINA_READER_URL = "https://r.jina.ai";
31
26
 
32
27
  // ── Exa MCP search (free, no key, no session) ───────────────────────
@@ -97,97 +92,6 @@ async function exaSearch(
97
92
  return text;
98
93
  }
99
94
 
100
- // ── Z.AI MCP reader (requires API key + session) ────────────────────
101
-
102
- let zaiRpcId = 0;
103
- const zaiSessionId = { current: "" };
104
-
105
- async function zaiMcpPost(
106
- apiKey: string,
107
- body: Record<string, unknown>,
108
- timeout: number,
109
- ): Promise<any> {
110
- const headers: Record<string, string> = {
111
- "Content-Type": "application/json",
112
- Accept: "application/json, text/event-stream",
113
- Authorization: `Bearer ${apiKey}`,
114
- };
115
- if (zaiSessionId.current) headers["mcp-session-id"] = zaiSessionId.current;
116
-
117
- const res = await fetch(`${ZAI_BASE}${ZAI_READER_PATH}`, {
118
- method: "POST",
119
- headers,
120
- body: JSON.stringify(body),
121
- signal: AbortSignal.timeout(timeout),
122
- });
123
-
124
- if (!res.ok) throw new Error(`Z.AI MCP ${res.status}`);
125
-
126
- const sid = res.headers.get("mcp-session-id");
127
- if (sid) zaiSessionId.current = sid;
128
-
129
- const ct = res.headers.get("content-type") ?? "";
130
- if (ct.includes("text/event-stream")) {
131
- const text = await res.text();
132
- for (const line of text.split("\n")) {
133
- if (!line.startsWith("data:")) continue;
134
- const payload = line.slice(line.charAt(5) === " " ? 6 : 5);
135
- if (!payload) continue;
136
- const parsed = JSON.parse(payload);
137
- if (parsed.error) throw new Error(parsed.error.message);
138
- return parsed.result;
139
- }
140
- throw new Error("No data in Z.AI SSE response");
141
- }
142
-
143
- const json = await res.json();
144
- const response = Array.isArray(json) ? json[0] : json;
145
- if (response?.error) throw new Error(response.error.message);
146
- return response?.result;
147
- }
148
-
149
- async function zaiRead(apiKey: string, url: string, timeout: number): Promise<string> {
150
- // Initialize session if needed
151
- if (!zaiSessionId.current) {
152
- await zaiMcpPost(apiKey, {
153
- jsonrpc: "2.0", id: ++zaiRpcId, method: "initialize",
154
- params: {
155
- protocolVersion: "2024-11-05", capabilities: {},
156
- clientInfo: { name: "ash-web-access", version: "1.0.0" },
157
- },
158
- }, timeout);
159
- await zaiMcpPost(apiKey, {
160
- jsonrpc: "2.0", method: "notifications/initialized",
161
- }, timeout);
162
- }
163
-
164
- const result = await zaiMcpPost(apiKey, {
165
- jsonrpc: "2.0", id: ++zaiRpcId, method: "tools/call",
166
- params: { name: "webReader", arguments: { url } },
167
- }, timeout);
168
-
169
- // Unwrap double-encoded JSON response
170
- const textBlock = result?.content?.find((c: any) => c.type === "text" && c.text);
171
- if (!textBlock) return JSON.stringify(result, null, 2);
172
-
173
- let data: any;
174
- try {
175
- data = JSON.parse(textBlock.text);
176
- if (typeof data === "string") data = JSON.parse(data);
177
- } catch {
178
- return textBlock.text;
179
- }
180
-
181
- if (data && typeof data === "object" && !Array.isArray(data)) {
182
- const title = data.title ? `# ${data.title}\n\n` : "";
183
- const source = data.url ? `**Source:** ${data.url}\n\n` : "";
184
- const body = data.content ?? data.markdown ?? data.text ?? JSON.stringify(data, null, 2);
185
- return `${title}${source}${body}`;
186
- }
187
-
188
- return typeof data === "string" ? data : JSON.stringify(data, null, 2);
189
- }
190
-
191
95
  // ── Jina Reader (free, no key) ───────────────────────────────────────
192
96
 
193
97
  async function jinaRead(url: string, timeout: number): Promise<string> {
@@ -220,8 +124,6 @@ async function directFetch(url: string, timeout: number): Promise<string> {
220
124
  // ── Extension entry point ────────────────────────────────────────────
221
125
 
222
126
  export default function activate(ctx: ExtensionContext) {
223
- const apiKey = process.env.ZAI_API_KEY ?? "";
224
-
225
127
  const config = ctx.getExtensionSettings("web-access", {
226
128
  timeout: 30000,
227
129
  searchNumResults: 5,
@@ -282,7 +184,7 @@ export default function activate(ctx: ExtensionContext) {
282
184
  description:
283
185
  "Fetch a URL and extract its content as clean markdown. " +
284
186
  "Handles web pages, articles, and documentation. " +
285
- "Uses Z.AI reader (best quality), Jina Reader, or direct fetch as fallback.",
187
+ "Uses Jina Reader, with direct fetch as fallback.",
286
188
  input_schema: {
287
189
  type: "object" as const,
288
190
  properties: {
@@ -308,14 +210,7 @@ export default function activate(ctx: ExtensionContext) {
308
210
  }
309
211
  }
310
212
 
311
- // Fallback chain: Z.AI reader → Jina Reader → direct fetch
312
- if (apiKey) {
313
- try {
314
- const content = await zaiRead(apiKey, args.url, timeout);
315
- return { content, exitCode: 0, isError: false };
316
- } catch { /* fall through */ }
317
- }
318
-
213
+ // Fallback chain: Jina Reader → direct fetch
319
214
  try {
320
215
  const content = await jinaRead(args.url, timeout);
321
216
  return { content, exitCode: 0, isError: false };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-sh",
3
- "version": "0.12.25",
3
+ "version": "0.12.27",
4
4
  "description": "A shell-first terminal where AI is one keystroke away",
5
5
  "type": "module",
6
6
  "main": "dist/core.js",