dsh-ab-wechat-scrape 0.4.0

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.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +330 -0
  3. package/cordis.patch.yml +8 -0
  4. package/lib/clean.d.ts +32 -0
  5. package/lib/clean.d.ts.map +1 -0
  6. package/lib/clean.js +193 -0
  7. package/lib/clean.js.map +1 -0
  8. package/lib/document.d.ts +27 -0
  9. package/lib/document.d.ts.map +1 -0
  10. package/lib/document.js +79 -0
  11. package/lib/document.js.map +1 -0
  12. package/lib/fetch.d.ts +84 -0
  13. package/lib/fetch.d.ts.map +1 -0
  14. package/lib/fetch.js +238 -0
  15. package/lib/fetch.js.map +1 -0
  16. package/lib/filename.d.ts +36 -0
  17. package/lib/filename.d.ts.map +1 -0
  18. package/lib/filename.js +92 -0
  19. package/lib/filename.js.map +1 -0
  20. package/lib/html.d.ts +114 -0
  21. package/lib/html.d.ts.map +1 -0
  22. package/lib/html.js +402 -0
  23. package/lib/html.js.map +1 -0
  24. package/lib/index.d.ts +219 -0
  25. package/lib/index.d.ts.map +1 -0
  26. package/lib/index.js +2523 -0
  27. package/lib/index.js.map +1 -0
  28. package/lib/list.d.ts +55 -0
  29. package/lib/list.d.ts.map +1 -0
  30. package/lib/list.js +191 -0
  31. package/lib/list.js.map +1 -0
  32. package/lib/markdown.d.ts +20 -0
  33. package/lib/markdown.d.ts.map +1 -0
  34. package/lib/markdown.js +250 -0
  35. package/lib/markdown.js.map +1 -0
  36. package/lib/render.d.ts +103 -0
  37. package/lib/render.d.ts.map +1 -0
  38. package/lib/render.js +209 -0
  39. package/lib/render.js.map +1 -0
  40. package/lib/store.d.ts +50 -0
  41. package/lib/store.d.ts.map +1 -0
  42. package/lib/store.js +173 -0
  43. package/lib/store.js.map +1 -0
  44. package/lib/types.d.ts +133 -0
  45. package/lib/types.d.ts.map +1 -0
  46. package/lib/types.js +8 -0
  47. package/lib/types.js.map +1 -0
  48. package/package.json +91 -0
  49. package/tsconfig.json +30 -0
  50. package/tsdown.config.ts +18 -0
package/lib/index.d.ts ADDED
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Model-facing wechat_scrape tool. One call retrieves articles from WeChat
3
+ * official accounts and saves each as its own Markdown file named after the
4
+ * article title. A link may be an article page, or a list or collection page
5
+ * whose article links are parsed out and then scraped one by one the same way;
6
+ * a page that carries no article body is read as a list page. The HTTP layer
7
+ * paces, retries, carries the session cookies WeChat sets, and reports WeChat's
8
+ * block pages; a page whose body is built by client script, and a page the plain
9
+ * path is refused for, fall back to the optional browser renderer. Only a page
10
+ * that is still an article with a usable body after promotion filtering is ever
11
+ * written to a file: a block page, a withdrawn article, and an article the
12
+ * filtering left empty are reported as failures instead. The tool reads no
13
+ * session state beyond the workspace directory it writes into and returns the
14
+ * canonical value alone, so model-facing text and any replay read the same
15
+ * recorded call.
16
+ * @module @deepseek-ai/dsh-ab-wechat-scrape
17
+ */
18
+ import type { Context } from '@deepseek-ai/cordis';
19
+ import type { SandboxExecutionPolicy } from '@deepseek-ai/dsh-sandbox';
20
+ import z from '@deepseek-ai/schemastery';
21
+ import type FileSystem from '@deepseek-ai/dsh-fs';
22
+ import { type CleanPolicy } from './clean.ts';
23
+ import { type Fetcher } from './fetch.ts';
24
+ import { type Renderer } from './render.ts';
25
+ import type { DraftedArticle, WechatArgs, WechatFormat, WechatScrape } from './types.ts';
26
+ export type * from './types.ts';
27
+ export { articleDocument, renderArticle } from './document.ts';
28
+ export { recordedArticle } from './store.ts';
29
+ export { albumPageUrl, parseListPage } from './list.ts';
30
+ export type { ListCursor, ListItem, ListPage } from './list.ts';
31
+ export declare const name = "wechat-scrape";
32
+ export declare const inject: string[];
33
+ /** Wire name this plugin registers. */
34
+ export declare const TOOL_NAME = "wechat_scrape";
35
+ /** Body formats the tool accepts, in the order the model sees them. */
36
+ export declare const BODY_FORMATS: readonly WechatFormat[];
37
+ /**
38
+ * Name and order of the routing section this plugin contributes. Repository-owned
39
+ * tool sections allocate their order centrally; an external contribution states
40
+ * its own finite order and sits after the built-in tool band (TOOL_REPORT, 2900).
41
+ */
42
+ export declare const SECTION_NAME = "tool:wechat_scrape";
43
+ /** Order of {@link SECTION_NAME}, after the built-in tool sections. */
44
+ export declare const SECTION_ORDER = 2970;
45
+ /** Deployment-varying values for retrieval, list walking, filtering, output, pacing, and rendering. */
46
+ export interface Config {
47
+ /** User agent every request and browser context sends. */
48
+ userAgent: string;
49
+ /** Referer every request and browser sends; empty omits the header. */
50
+ referer: string;
51
+ /** Cookie header for a logged-in session; empty sends none. */
52
+ cookie: string;
53
+ /** Whether cookies WeChat sets during a call are replayed for the rest of it. */
54
+ cookieJar: boolean;
55
+ /** Minimum milliseconds between two requests from this plugin instance. */
56
+ minIntervalMs: number;
57
+ /** Random milliseconds added to each wait, so the cadence is not a fixed period. */
58
+ minIntervalJitterMs: number;
59
+ /** Milliseconds the instance stands down for after WeChat refuses a page. */
60
+ blockCooldownMs: number;
61
+ /** Per-request timeout in milliseconds. */
62
+ timeoutMs: number;
63
+ /** Retries after the first attempt. */
64
+ maxRetries: number;
65
+ /** Base delay of the exponential backoff, in milliseconds. */
66
+ backoffBaseMs: number;
67
+ /** Longest wait a server-supplied retry hint may impose, in milliseconds. */
68
+ maxRetryAfterMs: number;
69
+ /** Maximum characters of the body the model reads; the saved file always holds all of it. */
70
+ maxChars: number;
71
+ /** Maximum image URLs the recorded value may carry. */
72
+ maxImages: number;
73
+ /** Maximum articles one call may scrape. */
74
+ maxArticles: number;
75
+ /** Collection pages one list walk may read; 0 reads until the collection ends. */
76
+ maxListPages: number;
77
+ /** Whether WeChat's advertising and follow-promotion blocks are removed from the body. */
78
+ filterAds: boolean;
79
+ /** Longest block the promotion text rule may drop, in characters. */
80
+ promoMaxChars: number;
81
+ /** Extra promotion rules, as regular-expression sources, beside the built-in ones. */
82
+ promoPatterns: string[];
83
+ /** Shortest filtered body, in characters, an article may carry and still be saved. */
84
+ minBodyChars: number;
85
+ /** Directory article files are written to; a relative value resolves against the session workspace. */
86
+ outputDir: string;
87
+ /** Longest article file name, in code points, before the extension. */
88
+ fileNameMaxChars: number;
89
+ /** auto renders a bodyless or refused page; always renders every page; never renders. */
90
+ renderer: 'auto' | 'never' | 'always';
91
+ /** Which renderer driver produces client-rendered HTML. */
92
+ rendererDriver: 'playwright' | 'http';
93
+ /** Endpoint the http renderer driver posts to. */
94
+ rendererUrl: string;
95
+ /** Playwright browser channel used when no executable path is set. */
96
+ browserChannel: string;
97
+ /** Explicit browser executable, overriding the channel. */
98
+ browserExecutablePath: string;
99
+ /** Whether the browser runs headless. */
100
+ headless: boolean;
101
+ /** Milliseconds an idle browser is kept before it is closed. */
102
+ browserIdleMs: number;
103
+ /** Selector the rendered article body must fill; empty skips the readiness wait. */
104
+ renderReadySelector: string;
105
+ /** Longest milliseconds a render waits for that body before reading the page as it stands. */
106
+ renderWaitMs: number;
107
+ /** Extra milliseconds to wait after navigation for lazy content. */
108
+ renderSettleMs: number;
109
+ }
110
+ /**
111
+ * Schemastery configuration for the tool. Defaults cover a single-machine
112
+ * deployment that writes into the calling session's workspace; the
113
+ * request-identity, list-depth, and output values are the ones a restricted or
114
+ * authenticated deployment overrides from cordis.yml.
115
+ */
116
+ export declare const Config: z<Config>;
117
+ /** Model-facing routing rule: when to make a call, which a schema cannot carry. */
118
+ export declare const SECTION_TEXT: string;
119
+ /** How one call reaches the network, the optional browser, and the file system. */
120
+ export interface CollectDeps {
121
+ /** Fetcher that applies the deployment's headers, pacing, and retries. */
122
+ fetcher: Fetcher;
123
+ /** Renderer used for a page the plain path cannot serve; absent when disabled. */
124
+ renderer: Renderer | undefined;
125
+ /** The deployment values that bound and shape the result. */
126
+ config: Config;
127
+ }
128
+ /** One scrape call's dependencies, including where and how its files are written. */
129
+ export interface ScrapeDeps extends CollectDeps {
130
+ /** Filesystem capability every article file is written through. */
131
+ fs: FileSystem;
132
+ /** Absolute directory every article file is written to. */
133
+ outputDir: string;
134
+ /** Per-call policy a confining filesystem fences the write by; absent on a bare backend. */
135
+ sandboxPolicy?: SandboxExecutionPolicy | undefined;
136
+ }
137
+ /**
138
+ * Validate the model-supplied link before any request is made.
139
+ * @param raw - the link as the model supplied it.
140
+ * @returns the trimmed link.
141
+ * @throws Error when the link is empty or names another host.
142
+ */
143
+ export declare function normalizeUrl(raw: string): string;
144
+ /**
145
+ * Collect the links one call asked for.
146
+ * @param args - the model-supplied call arguments.
147
+ * @param maxArticles - most links one call may start from.
148
+ * @returns the distinct links, in request order.
149
+ * @throws Error when the call names no link, a foreign link, or more links than the ceiling.
150
+ */
151
+ export declare function requestUrls(args: WechatArgs, maxArticles: number): string[];
152
+ /**
153
+ * Resolve the deployment's output directory.
154
+ *
155
+ * A relative value resolves against the workspace the calling session runs in.
156
+ * Under a confining filesystem that workspace is the per-call sandbox policy's
157
+ * root, not merely the session header's cwd: the policy is what the backend
158
+ * fences the write by, so a relative outputDir resolved against anything else
159
+ * would land outside the fence and be refused.
160
+ * @param configured - the row's outputDir value.
161
+ * @param cwd - the workspace this call resolves against, absent for a call without a session.
162
+ * @returns the absolute directory article files are written to.
163
+ */
164
+ export declare function resolveOutputDir(configured: string, cwd: string | undefined): string;
165
+ /**
166
+ * Cut text at the deployment ceiling, reporting whether anything was dropped.
167
+ * @param text - the whole converted body.
168
+ * @param maxChars - the deployment's excerpt ceiling.
169
+ * @returns the head within the ceiling and whether anything was dropped.
170
+ */
171
+ export declare function clip(text: string, maxChars: number): {
172
+ text: string;
173
+ truncated: boolean;
174
+ };
175
+ /**
176
+ * The promotion rules one instance filters with.
177
+ * @param config - the deployment's filtering values.
178
+ * @returns the length ceiling and the compiled extra rules.
179
+ * @throws Error when an extra rule is not a valid regular expression.
180
+ */
181
+ export declare function cleanPolicy(config: Config): CleanPolicy;
182
+ /**
183
+ * Retrieve and parse one article.
184
+ * @param args - the model-supplied call arguments.
185
+ * @param deps - the instance's fetcher, optional renderer, and bounds.
186
+ * @param signal - caller cancellation.
187
+ * @returns the drafted article, before it is saved.
188
+ * @throws Error for an invalid link, a block page, a failed request, or a link that is a list page.
189
+ */
190
+ export declare function collectArticle(args: WechatArgs, deps: CollectDeps, signal?: AbortSignal): Promise<DraftedArticle>;
191
+ /**
192
+ * Scrape every link one call named, saving each article to its own file. A link
193
+ * may be an article or a list page; a list page's article links are scraped the
194
+ * same way as a named article. One failing link or article does not discard
195
+ * what the other links produced.
196
+ * @param args - the model-supplied call arguments.
197
+ * @param deps - the instance's fetcher, renderer, bounds, and output directory.
198
+ * @param signal - caller cancellation.
199
+ * @returns the saved articles, the list pages walked, and the links that failed.
200
+ * @throws Error when the call names no usable link, or when the caller cancels.
201
+ */
202
+ export declare function scrape(args: WechatArgs, deps: ScrapeDeps, signal?: AbortSignal): Promise<WechatScrape>;
203
+ /**
204
+ * Compose the model-facing text of one call's result.
205
+ * @param value - the canonical scrape value.
206
+ * @returns every list page walked, every saved article, then every failure.
207
+ */
208
+ export declare function renderScrape(value: WechatScrape): string;
209
+ /**
210
+ * Contribute the routing section, own the renderer's lifetime, and register the
211
+ * wechat_scrape tool. The section is empty wherever the tool is not visible in
212
+ * that scope, so a restricted composition is not told to call a hidden tool.
213
+ * @param ctx - registrant context carrying the tool, system-prompt, and filesystem registries.
214
+ * @param config - the deployment's retrieval, list, filtering, output, and renderer values.
215
+ * @throws Error when a confining filesystem is mounted with no sandbox-policy service,
216
+ * because no per-call workspace root could then be resolved for the article writes.
217
+ */
218
+ export declare function apply(ctx: Context, config: Config): void;
219
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}