@klarkxy/dsh-zhihu 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.js","names":[],"sources":["../src/usage.ts"],"sourcesContent":["import { defineDomain, domainTable } from '@deepseek-ai/dsh-storage-domain'\nimport { z } from 'zod'\nexport class UsageInputError extends Error {\n constructor(message: string, readonly code: string) { super(message); this.name = 'UsageInputError' }\n}\nexport function dayKey(now: Date = new Date()): string {\n return [now.getFullYear(), String(now.getMonth() + 1).padStart(2, '0'), String(now.getDate()).padStart(2, '0')].join('-')\n}\nexport function resolveDays(value: unknown): number {\n const days = typeof value === 'number' && Number.isFinite(value) ? Math.trunc(value) : 30\n if (days < 1) throw new UsageInputError('days must be at least 1', 'DAYS_OUT_OF_RANGE')\n if (days > 90) throw new UsageInputError('days must be no more than 90', 'DAYS_OUT_OF_RANGE')\n return days\n}\nexport function recentDayKeys(count: number, now: Date = new Date()): string[] {\n const days: string[] = []\n const base = new Date(now.getFullYear(), now.getMonth(), now.getDate())\n for (let offset = count - 1; offset >= 0; offset -= 1) {\n const cursor = new Date(base); cursor.setDate(base.getDate() - offset); days.push(dayKey(cursor))\n }\n return days\n}\n\n/** Daily counters for zhihu tool executions (search/global search/hot list/ask/knowledge). `results` accumulates returned items on successful calls. */\nexport type ZhihuDailyUsage = {\n date: string\n calls: number\n failures: number\n results: number\n}\n\n/** Metering payload emitted by novel tool hosts after each zhihu_search execution. */\nexport type ZhihuSearchEvent = { ok: boolean; results?: number }\n\nconst dailyRowSchema = z.object({\n date: z.string(),\n calls: z.number().int().nonnegative(),\n failures: z.number().int().nonnegative(),\n results: z.number().int().nonnegative(),\n})\n\nexport const zhihuUsageDomainSpec = defineDomain({\n name: 'dsh_editor_zhihu_usage',\n version: 1,\n tables: { daily: domainTable<string, z.infer<typeof dailyRowSchema>>(dailyRowSchema) },\n})\n\nfunction int(value: number | undefined): number {\n return typeof value === 'number' && Number.isFinite(value) && value > 0 ? Math.trunc(value) : 0\n}\n\nfunction emptyDay(date: string): ZhihuDailyUsage {\n return { date, calls: 0, failures: 0, results: 0 }\n}\n\n/** Fold one zhihu_search execution into a daily row. */\nexport function mergeZhihuUsage(day: ZhihuDailyUsage | undefined, event: ZhihuSearchEvent): ZhihuDailyUsage {\n const next: ZhihuDailyUsage = day ? { ...day } : emptyDay('')\n next.calls += 1\n if (event.ok) next.results += int(event.results)\n else next.failures += 1\n return next\n}\n\nexport interface ZhihuUsageTableLike {\n get(key: string): z.infer<typeof dailyRowSchema> | undefined\n put(key: string, value: z.infer<typeof dailyRowSchema>): Promise<void>\n}\n\nexport interface ZhihuUsageRecorder {\n record(event: ZhihuSearchEvent): Promise<void>\n read(days: number): Promise<ZhihuDailyUsage[]>\n}\n\n/** Read-modify-write adapter over a storage-domain table, mirroring `createUsageRecorder`. */\nexport function createZhihuUsageRecorder(table: ZhihuUsageTableLike): ZhihuUsageRecorder {\n return {\n async record(event) {\n const date = dayKey()\n let stored: z.infer<typeof dailyRowSchema> | undefined\n try {\n stored = table.get(date)\n } catch {\n stored = undefined\n }\n const merged = mergeZhihuUsage(stored, event)\n await table.put(date, { ...merged, date })\n },\n async read(days) {\n const count = resolveDays(days)\n const keys = recentDayKeys(count)\n const byDate = new Map<string, ZhihuDailyUsage>()\n for (const key of keys) {\n const row = table.get(key)\n if (row) byDate.set(row.date, row)\n }\n return keys.map((date) => byDate.get(date) ?? emptyDay(date))\n },\n }\n}\n"],"mappings":";;;AAEA,IAAa,kBAAb,cAAqC,MAAM;CACH;CAAtC,YAAY,SAAiB,MAAuB;EAAE,MAAM,OAAO;EAA7B,KAAA,OAAA;EAAgC,KAAK,OAAO;CAAkB;AACtG;AACA,SAAgB,OAAO,sBAAY,IAAI,KAAK,GAAW;CACrD,OAAO;EAAC,IAAI,YAAY;EAAG,OAAO,IAAI,SAAS,IAAI,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;EAAG,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;CAAC,CAAC,CAAC,KAAK,GAAG;AAC1H;AACA,SAAgB,YAAY,OAAwB;CAClD,MAAM,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,KAAK,MAAM,KAAK,IAAI;CACvF,IAAI,OAAO,GAAG,MAAM,IAAI,gBAAgB,2BAA2B,mBAAmB;CACtF,IAAI,OAAO,IAAI,MAAM,IAAI,gBAAgB,gCAAgC,mBAAmB;CAC5F,OAAO;AACT;AACA,SAAgB,cAAc,OAAe,sBAAY,IAAI,KAAK,GAAa;CAC7E,MAAM,OAAiB,CAAC;CACxB,MAAM,OAAO,IAAI,KAAK,IAAI,YAAY,GAAG,IAAI,SAAS,GAAG,IAAI,QAAQ,CAAC;CACtE,KAAK,IAAI,SAAS,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG;EACrD,MAAM,SAAS,IAAI,KAAK,IAAI;EAAG,OAAO,QAAQ,KAAK,QAAQ,IAAI,MAAM;EAAG,KAAK,KAAK,OAAO,MAAM,CAAC;CAClG;CACA,OAAO;AACT;AAaA,MAAM,iBAAiB,EAAE,OAAO;CAC9B,MAAM,EAAE,OAAO;CACf,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY;CACpC,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY;CACvC,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY;AACxC,CAAC;AAED,MAAa,uBAAuB,aAAa;CAC/C,MAAM;CACN,SAAS;CACT,QAAQ,EAAE,OAAO,YAAoD,cAAc,EAAE;AACvF,CAAC;AAED,SAAS,IAAI,OAAmC;CAC9C,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,QAAQ,IAAI,KAAK,MAAM,KAAK,IAAI;AAChG;AAEA,SAAS,SAAS,MAA+B;CAC/C,OAAO;EAAE;EAAM,OAAO;EAAG,UAAU;EAAG,SAAS;CAAE;AACnD;;AAGA,SAAgB,gBAAgB,KAAkC,OAA0C;CAC1G,MAAM,OAAwB,MAAM,EAAE,GAAG,IAAI,IAAI,SAAS,EAAE;CAC5D,KAAK,SAAS;CACd,IAAI,MAAM,IAAI,KAAK,WAAW,IAAI,MAAM,OAAO;MAC1C,KAAK,YAAY;CACtB,OAAO;AACT;;AAaA,SAAgB,yBAAyB,OAAgD;CACvF,OAAO;EACL,MAAM,OAAO,OAAO;GAClB,MAAM,OAAO,OAAO;GACpB,IAAI;GACJ,IAAI;IACF,SAAS,MAAM,IAAI,IAAI;GACzB,QAAQ;IACN,SAAS,KAAA;GACX;GACA,MAAM,SAAS,gBAAgB,QAAQ,KAAK;GAC5C,MAAM,MAAM,IAAI,MAAM;IAAE,GAAG;IAAQ;GAAK,CAAC;EAC3C;EACA,MAAM,KAAK,MAAM;GAEf,MAAM,OAAO,cADC,YAAY,IACK,CAAC;GAChC,MAAM,yBAAS,IAAI,IAA6B;GAChD,KAAK,MAAM,OAAO,MAAM;IACtB,MAAM,MAAM,MAAM,IAAI,GAAG;IACzB,IAAI,KAAK,OAAO,IAAI,IAAI,MAAM,GAAG;GACnC;GACA,OAAO,KAAK,KAAK,SAAS,OAAO,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC;EAC9D;CACF;AACF"}
package/package.json ADDED
@@ -0,0 +1,135 @@
1
+ {
2
+ "name": "@klarkxy/dsh-zhihu",
3
+ "version": "0.1.0",
4
+ "description": "Independent Zhihu services, tools and UI for DSH",
5
+ "license": "SEE LICENSE IN LICENSE",
6
+ "type": "module",
7
+ "engines": {
8
+ "node": ">=22"
9
+ },
10
+ "main": "./lib/index.js",
11
+ "types": "./lib/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./lib/index.d.ts",
15
+ "import": "./lib/index.js",
16
+ "default": "./lib/index.js"
17
+ },
18
+ "./tools": {
19
+ "types": "./lib/tools.d.ts",
20
+ "import": "./lib/tools.js",
21
+ "default": "./lib/tools.js"
22
+ },
23
+ "./contracts": {
24
+ "types": "./lib/contracts.d.ts",
25
+ "import": "./lib/contracts.js",
26
+ "default": "./lib/contracts.js"
27
+ },
28
+ "./usage": {
29
+ "types": "./lib/usage.d.ts",
30
+ "import": "./lib/usage.js",
31
+ "default": "./lib/usage.js"
32
+ },
33
+ "./client": {
34
+ "default": "./lib/client.js"
35
+ },
36
+ "./package.json": "./package.json"
37
+ },
38
+ "files": [
39
+ "lib/*.js",
40
+ "lib/*.js.map",
41
+ "lib/*.d.ts",
42
+ "cordis.patch.yml",
43
+ "README.md",
44
+ "LICENSE"
45
+ ],
46
+ "dsh": {
47
+ "bundle": {
48
+ "patch": "./cordis.patch.yml"
49
+ },
50
+ "client": {
51
+ "platform": "web",
52
+ "inject": [
53
+ "@deepseek-ai/dsh-client-connection",
54
+ "@deepseek-ai/dsh-api-remotes"
55
+ ]
56
+ }
57
+ },
58
+ "dshEditor": {
59
+ "role": "feature",
60
+ "visibility": "public",
61
+ "wrapClient": true,
62
+ "entries": [
63
+ {
64
+ "id": "zhihu",
65
+ "title": "知乎资料",
66
+ "description": "知乎搜索、知识库与用量",
67
+ "feature": "zhihu",
68
+ "service": "zhihu"
69
+ }
70
+ ],
71
+ "inserts": [
72
+ {
73
+ "id": "zhihu-tools",
74
+ "name": "@klarkxy/dsh-zhihu/tools",
75
+ "title": "知乎工具",
76
+ "description": "供写作搭档调用的知乎检索",
77
+ "feature": "zhihu-tools",
78
+ "requires": [
79
+ "zhihu"
80
+ ]
81
+ }
82
+ ]
83
+ },
84
+ "dependencies": {
85
+ "@deepseek-ai/dsh-storage-domain": "0.1.5-rc.2",
86
+ "zod": "^4.1.5"
87
+ },
88
+ "peerDependencies": {
89
+ "@deepseek-ai/cordis": "^4.0.2",
90
+ "@deepseek-ai/dsh-credentials": "0.1.5-rc.2",
91
+ "@deepseek-ai/dsh-tools": ">=0.1.5-rc.2 <0.2.0"
92
+ },
93
+ "devDependencies": {
94
+ "@deepseek-ai/cordis": "^4.0.2",
95
+ "@deepseek-ai/dsh-credentials": "0.1.5-rc.2",
96
+ "@deepseek-ai/dsh-tools": "0.1.5-rc.2",
97
+ "react": "^18.2.0",
98
+ "@types/react": "18.3.31",
99
+ "dsh-editor-seats": "0.1.0"
100
+ },
101
+ "peerDependenciesMeta": {
102
+ "@deepseek-ai/dsh-tools": {
103
+ "optional": true
104
+ }
105
+ },
106
+ "keywords": [
107
+ "dsh",
108
+ "dsh-plugin",
109
+ "deepseek-harness",
110
+ "zhihu",
111
+ "search",
112
+ "knowledge-base"
113
+ ],
114
+ "repository": {
115
+ "type": "git",
116
+ "url": "git+https://github.com/klarkxy/dsh-editor.git",
117
+ "directory": "packages/dsh-zhihu"
118
+ },
119
+ "homepage": "https://github.com/klarkxy/dsh-editor/tree/main/packages/dsh-zhihu#readme",
120
+ "bugs": {
121
+ "url": "https://github.com/klarkxy/dsh-editor/issues"
122
+ },
123
+ "publishConfig": {
124
+ "access": "public",
125
+ "registry": "https://registry.npmjs.org/"
126
+ },
127
+ "dshRelease": {
128
+ "contentHash": "sha256-71337b27e6e3f01b26823ca0fcfc9560d49e0868be8ddbcf597a9b4926f02754"
129
+ },
130
+ "scripts": {
131
+ "build": "tsdown && node ../../scripts/wrap-client.mjs @klarkxy/dsh-zhihu",
132
+ "typecheck": "tsc --noEmit -p tsconfig.json",
133
+ "test": "vitest run --root ../.. packages/dsh-zhihu/src"
134
+ }
135
+ }