@native-knowledge/knowledge-sdk 0.0.0-stage → 0.1.0-rc.2

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 (203) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +29 -0
  3. package/README.md +34 -2
  4. package/dist/agent-entry.d.ts +291 -0
  5. package/dist/agent-entry.js +153 -0
  6. package/dist/agent-guidance-error.d.ts +15 -0
  7. package/dist/agent-guidance-error.js +46 -0
  8. package/dist/auth.d.ts +124 -0
  9. package/dist/auth.js +165 -0
  10. package/dist/index.d.ts +290 -0
  11. package/dist/index.js +166 -0
  12. package/dist/internal/contracts/artifact.d.ts +120 -0
  13. package/dist/internal/contracts/artifact.js +103 -0
  14. package/dist/internal/contracts/collection-control.d.ts +160 -0
  15. package/dist/internal/contracts/collection-control.js +69 -0
  16. package/dist/internal/contracts/collection.d.ts +263 -0
  17. package/dist/internal/contracts/collection.js +174 -0
  18. package/dist/internal/contracts/common.d.ts +17 -0
  19. package/dist/internal/contracts/common.js +16 -0
  20. package/dist/internal/contracts/currentness.d.ts +477 -0
  21. package/dist/internal/contracts/currentness.js +221 -0
  22. package/dist/internal/contracts/event.d.ts +60 -0
  23. package/dist/internal/contracts/event.js +35 -0
  24. package/dist/internal/contracts/evidence.d.ts +202 -0
  25. package/dist/internal/contracts/evidence.js +171 -0
  26. package/dist/internal/contracts/index.d.ts +54 -0
  27. package/dist/internal/contracts/index.js +54 -0
  28. package/dist/internal/contracts/material-capability.d.ts +88 -0
  29. package/dist/internal/contracts/material-capability.js +8 -0
  30. package/dist/internal/contracts/material-carrier.d.ts +104 -0
  31. package/dist/internal/contracts/material-carrier.js +15 -0
  32. package/dist/internal/contracts/material-context.d.ts +28 -0
  33. package/dist/internal/contracts/material-context.js +9 -0
  34. package/dist/internal/contracts/material-read.d.ts +152 -0
  35. package/dist/internal/contracts/material-read.js +12 -0
  36. package/dist/internal/contracts/observation.d.ts +75 -0
  37. package/dist/internal/contracts/observation.js +39 -0
  38. package/dist/internal/contracts/persistence.d.ts +370 -0
  39. package/dist/internal/contracts/persistence.js +239 -0
  40. package/dist/internal/contracts/project-intent.d.ts +218 -0
  41. package/dist/internal/contracts/project-intent.js +121 -0
  42. package/dist/internal/contracts/projection.d.ts +380 -0
  43. package/dist/internal/contracts/projection.js +194 -0
  44. package/dist/internal/contracts/public-reference.d.ts +237 -0
  45. package/dist/internal/contracts/public-reference.js +87 -0
  46. package/dist/internal/contracts/reference-record.d.ts +124 -0
  47. package/dist/internal/contracts/reference-record.js +55 -0
  48. package/dist/internal/contracts/remote-file.d.ts +128 -0
  49. package/dist/internal/contracts/remote-file.js +159 -0
  50. package/dist/internal/contracts/resource-scope.d.ts +40 -0
  51. package/dist/internal/contracts/resource-scope.js +38 -0
  52. package/dist/internal/contracts/review-packet.d.ts +274 -0
  53. package/dist/internal/contracts/review-packet.js +61 -0
  54. package/dist/internal/contracts/review-plane.d.ts +90 -0
  55. package/dist/internal/contracts/review-plane.js +89 -0
  56. package/dist/internal/contracts/rich-document.d.ts +641 -0
  57. package/dist/internal/contracts/rich-document.js +184 -0
  58. package/dist/internal/contracts/runtime-compatibility.d.ts +22 -0
  59. package/dist/internal/contracts/runtime-compatibility.js +55 -0
  60. package/dist/internal/contracts/runtime.d.ts +59 -0
  61. package/dist/internal/contracts/runtime.js +68 -0
  62. package/dist/internal/contracts/scheduler.d.ts +348 -0
  63. package/dist/internal/contracts/scheduler.js +256 -0
  64. package/dist/internal/contracts/signal.d.ts +113 -0
  65. package/dist/internal/contracts/signal.js +77 -0
  66. package/dist/internal/contracts/source-governance.d.ts +375 -0
  67. package/dist/internal/contracts/source-governance.js +194 -0
  68. package/dist/internal/contracts/source.d.ts +62 -0
  69. package/dist/internal/contracts/source.js +32 -0
  70. package/dist/internal/contracts/tenant-budget.d.ts +59 -0
  71. package/dist/internal/contracts/tenant-budget.js +34 -0
  72. package/dist/internal/contracts/tenant-collection-request.d.ts +209 -0
  73. package/dist/internal/contracts/tenant-collection-request.js +58 -0
  74. package/dist/internal/contracts/tenant-collection.d.ts +199 -0
  75. package/dist/internal/contracts/tenant-collection.js +66 -0
  76. package/dist/internal/contracts/tenant-currentness.d.ts +117 -0
  77. package/dist/internal/contracts/tenant-currentness.js +26 -0
  78. package/dist/internal/contracts/tenant-management.d.ts +286 -0
  79. package/dist/internal/contracts/tenant-management.js +27 -0
  80. package/dist/internal/contracts/tenant-material-api.d.ts +584 -0
  81. package/dist/internal/contracts/tenant-material-api.js +46 -0
  82. package/dist/internal/contracts/tenant-material-json-schema.js +16 -0
  83. package/dist/internal/contracts/tenant-pdf-text.d.ts +27 -0
  84. package/dist/internal/contracts/tenant-pdf-text.js +13 -0
  85. package/dist/internal/contracts/tenant-project-control.d.ts +94 -0
  86. package/dist/internal/contracts/tenant-project-control.js +19 -0
  87. package/dist/internal/contracts/tenant-public-reference.d.ts +179 -0
  88. package/dist/internal/contracts/tenant-public-reference.js +26 -0
  89. package/dist/internal/contracts/tenant-resource-api.d.ts +738 -0
  90. package/dist/internal/contracts/tenant-resource-api.js +70 -0
  91. package/dist/internal/contracts/tenant-resource.d.ts +298 -0
  92. package/dist/internal/contracts/tenant-resource.js +118 -0
  93. package/dist/internal/contracts/tenant-rich-document.d.ts +317 -0
  94. package/dist/internal/contracts/tenant-rich-document.js +17 -0
  95. package/dist/internal/contracts/tenant-source-binding.d.ts +44 -0
  96. package/dist/internal/contracts/tenant-source-binding.js +33 -0
  97. package/dist/internal/contracts/tenant-source-bridge.d.ts +70 -0
  98. package/dist/internal/contracts/tenant-source-bridge.js +9 -0
  99. package/dist/internal/contracts/tenant-source-cutover.d.ts +226 -0
  100. package/dist/internal/contracts/tenant-source-cutover.js +26 -0
  101. package/dist/internal/contracts/tenant-source-document.d.ts +163 -0
  102. package/dist/internal/contracts/tenant-source-document.js +38 -0
  103. package/dist/internal/contracts/tenant-source-lease.d.ts +1 -0
  104. package/dist/internal/contracts/tenant-source-lease.js +5 -0
  105. package/dist/internal/contracts/tenant-source.d.ts +223 -0
  106. package/dist/internal/contracts/tenant-source.js +83 -0
  107. package/dist/internal/contracts/tenant-web-collection.d.ts +287 -0
  108. package/dist/internal/contracts/tenant-web-collection.js +118 -0
  109. package/dist/internal/contracts/tenant-web-content-plan.d.ts +86 -0
  110. package/dist/internal/contracts/tenant-web-content-plan.js +39 -0
  111. package/dist/internal/contracts/tenant-web-content-result.d.ts +63 -0
  112. package/dist/internal/contracts/tenant-web-content-result.js +15 -0
  113. package/dist/internal/contracts/tenant-web-content.d.ts +383 -0
  114. package/dist/internal/contracts/tenant-web-content.js +16 -0
  115. package/dist/internal/contracts/tenant-web-crawl.d.ts +310 -0
  116. package/dist/internal/contracts/tenant-web-crawl.js +55 -0
  117. package/dist/internal/contracts/tenant-web-dynamic.d.ts +698 -0
  118. package/dist/internal/contracts/tenant-web-dynamic.js +68 -0
  119. package/dist/internal/contracts/tenant-web-results.d.ts +66 -0
  120. package/dist/internal/contracts/tenant-web-results.js +41 -0
  121. package/dist/internal/contracts/tenant-web-workflow.d.ts +494 -0
  122. package/dist/internal/contracts/tenant-web-workflow.js +29 -0
  123. package/dist/internal/serving-contracts/agent-catalog.d.ts +70 -0
  124. package/dist/internal/serving-contracts/agent-catalog.js +56 -0
  125. package/dist/internal/serving-contracts/agent-entry.d.ts +13148 -0
  126. package/dist/internal/serving-contracts/agent-entry.js +57 -0
  127. package/dist/internal/serving-contracts/agent-guidance-shapes.d.ts +263 -0
  128. package/dist/internal/serving-contracts/agent-guidance-shapes.js +12 -0
  129. package/dist/internal/serving-contracts/agent-input-hints.d.ts +24 -0
  130. package/dist/internal/serving-contracts/agent-input-hints.js +104 -0
  131. package/dist/internal/serving-contracts/body-search.d.ts +231 -0
  132. package/dist/internal/serving-contracts/body-search.js +16 -0
  133. package/dist/internal/serving-contracts/consumer.d.ts +989 -0
  134. package/dist/internal/serving-contracts/consumer.js +45 -0
  135. package/dist/internal/serving-contracts/core.d.ts +333 -0
  136. package/dist/internal/serving-contracts/core.js +76 -0
  137. package/dist/internal/serving-contracts/http.d.ts +2874 -0
  138. package/dist/internal/serving-contracts/http.js +64 -0
  139. package/dist/internal/serving-contracts/index.d.ts +24 -0
  140. package/dist/internal/serving-contracts/index.js +25 -0
  141. package/dist/internal/serving-contracts/management.d.ts +424 -0
  142. package/dist/internal/serving-contracts/management.js +15 -0
  143. package/dist/internal/serving-contracts/material-capabilities.d.ts +508 -0
  144. package/dist/internal/serving-contracts/material-capabilities.js +14 -0
  145. package/dist/internal/serving-contracts/material-index-status.d.ts +55 -0
  146. package/dist/internal/serving-contracts/material-index-status.js +5 -0
  147. package/dist/internal/serving-contracts/mcp.d.ts +2218 -0
  148. package/dist/internal/serving-contracts/mcp.js +140 -0
  149. package/dist/internal/serving-contracts/tenant-governance.d.ts +236 -0
  150. package/dist/internal/serving-contracts/tenant-governance.js +13 -0
  151. package/dist/internal/serving-contracts/tenant-management.d.ts +6276 -0
  152. package/dist/internal/serving-contracts/tenant-management.js +89 -0
  153. package/dist/internal/serving-contracts/tenant-project.d.ts +7550 -0
  154. package/dist/internal/serving-contracts/tenant-project.js +39 -0
  155. package/dist/internal/serving-contracts/tenant-runtime.d.ts +9674 -0
  156. package/dist/internal/serving-contracts/tenant-runtime.js +37 -0
  157. package/dist/internal/serving-contracts/tenant-session.d.ts +87 -0
  158. package/dist/internal/serving-contracts/tenant-session.js +8 -0
  159. package/dist/internal/serving-contracts/tenant-web-content.d.ts +4606 -0
  160. package/dist/internal/serving-contracts/tenant-web-content.js +20 -0
  161. package/dist/internal/serving-contracts/tenant-web-crawl.d.ts +2958 -0
  162. package/dist/internal/serving-contracts/tenant-web-crawl.js +13 -0
  163. package/dist/internal/serving-contracts/tenant-web-dynamic.d.ts +3902 -0
  164. package/dist/internal/serving-contracts/tenant-web-dynamic.js +20 -0
  165. package/dist/internal/serving-contracts/tenant-web-workflow.d.ts +5750 -0
  166. package/dist/internal/serving-contracts/tenant-web-workflow.js +36 -0
  167. package/dist/internal/serving-contracts/tenant-web.d.ts +6418 -0
  168. package/dist/internal/serving-contracts/tenant-web.js +53 -0
  169. package/dist/internal/serving-contracts/tenant-workspace.d.ts +6451 -0
  170. package/dist/internal/serving-contracts/tenant-workspace.js +28 -0
  171. package/dist/internal/serving-contracts/workflow.d.ts +439 -0
  172. package/dist/internal/serving-contracts/workflow.js +37 -0
  173. package/dist/material-stream.d.ts +18 -0
  174. package/dist/material-stream.js +29 -0
  175. package/dist/oauth.d.ts +268 -0
  176. package/dist/oauth.js +539 -0
  177. package/dist/resource.d.ts +88 -0
  178. package/dist/resource.js +123 -0
  179. package/dist/session.d.ts +4 -0
  180. package/dist/session.js +3 -0
  181. package/dist/tenant-client.d.ts +169 -0
  182. package/dist/tenant-client.js +58 -0
  183. package/dist/tenant-management.d.ts +240 -0
  184. package/dist/tenant-management.js +149 -0
  185. package/dist/tenant-project.d.ts +57 -0
  186. package/dist/tenant-project.js +63 -0
  187. package/dist/tenant-runtime.d.ts +174 -0
  188. package/dist/tenant-runtime.js +17 -0
  189. package/dist/tenant-web-content.d.ts +44 -0
  190. package/dist/tenant-web-content.js +70 -0
  191. package/dist/tenant-web-crawl.d.ts +42 -0
  192. package/dist/tenant-web-crawl.js +39 -0
  193. package/dist/tenant-web-dynamic.d.ts +42 -0
  194. package/dist/tenant-web-dynamic.js +39 -0
  195. package/dist/tenant-web-workflow.d.ts +43 -0
  196. package/dist/tenant-web-workflow.js +63 -0
  197. package/dist/tenant-web.d.ts +42 -0
  198. package/dist/tenant-web.js +39 -0
  199. package/dist/tenant-workspace.d.ts +36 -0
  200. package/dist/tenant-workspace.js +21 -0
  201. package/dist/token-provider.d.ts +14 -0
  202. package/dist/token-provider.js +21 -0
  203. package/package.json +45 -3
@@ -0,0 +1,118 @@
1
+ /** Tenant 网站采集意图;范围和内容要求不携带 Project 或执行权限。 */
2
+ import { createHash } from 'node:crypto';
3
+ import { z } from 'zod';
4
+ import { isoDateTimeSchema, sha256Schema } from './common.js';
5
+ import { materialTenantIdSchema } from './material-context.js';
6
+ import { tenantStorageKey } from './resource-scope.js';
7
+ import { knowledgeActorContextSchema } from './project-intent.js';
8
+ import { isTenantSourceCredentialParameter } from './tenant-source.js';
9
+ import { tenantCollectionCycleSchema, tenantCollectionMaxBytesSchema } from './tenant-collection.js';
10
+ import { tenantCollectionRequestAuthoritySchema } from './tenant-collection-request.js';
11
+ export const TENANT_WEB_SPEC_CAPABILITY = 'TENANT_WEB_COLLECTION_SPEC_V1';
12
+ export const tenantWebUrlSchema = z.string().url().max(2048).superRefine((raw, ctx) => {
13
+ let url;
14
+ try {
15
+ url = new URL(raw);
16
+ }
17
+ catch {
18
+ ctx.addIssue({ code: 'custom', message: 'A valid HTTP URL is required' });
19
+ return;
20
+ }
21
+ if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password || url.hash || url.port || [...url.searchParams.keys()].some(isTenantSourceCredentialParameter))
22
+ ctx.addIssue({ code: 'custom', message: 'Public HTTP URL without credentials, nonstandard port or fragment required' });
23
+ });
24
+ const originSchema = tenantWebUrlSchema.superRefine((value, ctx) => { try {
25
+ if (new URL(value).origin === value)
26
+ return;
27
+ }
28
+ catch { /* Report a schema issue, never an arbitrary URL parser error. */ } ctx.addIssue({ code: 'custom', message: 'An exact HTTP origin is required' }); });
29
+ const pathSchema = z.string().min(1).max(512).superRefine((value, ctx) => {
30
+ let decoded = '';
31
+ try {
32
+ decoded = decodeURIComponent(value);
33
+ }
34
+ catch { /* Invalid encoding fails closed below. */ }
35
+ if (!decoded.startsWith('/') || decoded.startsWith('//') || /[?#\\\x00-\x1f]/.test(decoded) || decoded.split('/').some(part => part === '.' || part === '..') || decoded.replace(/\/\*\*$/, '').includes('*'))
36
+ ctx.addIssue({ code: 'custom', message: 'Absolute path or terminal /** prefix required' });
37
+ });
38
+ export const tenantWebScopeSchema = z.object({
39
+ mode: z.enum(['SINGLE_PAGE', 'URL_LIST', 'SITE_SECTION', 'SITEMAP', 'FEED']),
40
+ allowedOrigins: z.array(originSchema).max(16).default([]),
41
+ includePaths: z.array(pathSchema).max(32).default([]),
42
+ excludePaths: z.array(pathSchema).max(32).default([]),
43
+ urls: z.array(tenantWebUrlSchema).max(64).default([]),
44
+ followPagination: z.boolean().default(false),
45
+ followDetailLinks: z.boolean().default(false),
46
+ }).strict();
47
+ const field = z.object({ name: z.string().regex(/^[A-Za-z][A-Za-z0-9_]{0,63}$/), type: z.enum(['string', 'number', 'boolean', 'object', 'array']), required: z.boolean().default(false) }).strict();
48
+ export const tenantWebRequirementsSchema = z.object({
49
+ instruction: z.string().trim().min(1).max(4000),
50
+ fields: z.array(field).max(64).default([]),
51
+ outputs: z.array(z.enum(['RAW', 'DOCUMENT', 'RECORDS'])).min(1).max(3).default(['RAW', 'DOCUMENT']),
52
+ attachments: z.array(z.enum(['PDF', 'IMAGE', 'AUDIO', 'VIDEO', 'OTHER'])).max(5).default([]),
53
+ }).strict().superRefine((value, ctx) => { if (new Set(value.fields.map(f => f.name)).size !== value.fields.length)
54
+ ctx.addIssue({ code: 'custom', message: 'Field names must be unique' }); });
55
+ export const tenantWebDefaultLimits = { maxPages: 100, maxDepth: 3, maxResourceBytes: 16 * 1024 * 1024, maxTotalBytes: 64 * 1024 * 1024, maxRuntimeMs: 300000, maxInteractions: 100, maxFiles: 100 };
56
+ export const tenantWebLimitsSchema = z.object({
57
+ maxPages: z.number().int().min(1).max(10000).default(100),
58
+ maxDepth: z.number().int().min(0).max(10).default(3),
59
+ maxResourceBytes: tenantCollectionMaxBytesSchema.default(16 * 1024 * 1024),
60
+ maxTotalBytes: z.number().int().min(1024).max(1024 * 1024 * 1024).default(64 * 1024 * 1024),
61
+ maxRuntimeMs: z.number().int().min(1000).max(900000).default(300000),
62
+ maxInteractions: z.number().int().min(0).max(1000).default(100),
63
+ maxFiles: z.number().int().min(0).max(1000).default(100),
64
+ }).strict();
65
+ export const tenantWebSpecSchema = z.object({
66
+ schemaVersion: z.literal(1), url: tenantWebUrlSchema, scope: tenantWebScopeSchema,
67
+ requirements: tenantWebRequirementsSchema, limits: tenantWebLimitsSchema.default(tenantWebDefaultLimits),
68
+ refresh: z.object({ mode: z.literal('ONCE') }).strict().default({ mode: 'ONCE' }),
69
+ }).strict().superRefine((value, ctx) => {
70
+ try {
71
+ const origins = value.scope.allowedOrigins.length ? value.scope.allowedOrigins : [new URL(value.url).origin];
72
+ if (!origins.includes(new URL(value.url).origin) || value.scope.urls.some(url => !origins.includes(new URL(url).origin)))
73
+ ctx.addIssue({ code: 'custom', path: ['scope'], message: 'Entry and explicit targets must remain in the declared origins' });
74
+ }
75
+ catch {
76
+ ctx.addIssue({ code: 'custom', path: ['scope'], message: 'Valid entry and target URLs are required' });
77
+ }
78
+ if ((value.scope.mode === 'URL_LIST') !== (value.scope.urls.length > 0))
79
+ ctx.addIssue({ code: 'custom', path: ['scope', 'urls'], message: 'Only URL_LIST requires explicit URLs' });
80
+ if (value.scope.mode === 'SITE_SECTION' && value.scope.includePaths.length === 0)
81
+ ctx.addIssue({ code: 'custom', path: ['scope', 'includePaths'], message: 'A site section requires an explicit path boundary' });
82
+ if (value.scope.mode === 'SINGLE_PAGE' && (value.scope.followPagination || value.scope.followDetailLinks))
83
+ ctx.addIssue({ code: 'custom', path: ['scope'], message: 'Single page cannot enable discovery' });
84
+ });
85
+ export function tenantWebCanonical(value) {
86
+ if (value === null || typeof value !== 'object')
87
+ return JSON.stringify(value);
88
+ if (Array.isArray(value))
89
+ return '[' + value.map(tenantWebCanonical).join(',') + ']';
90
+ const row = value;
91
+ return '{' + Object.keys(row).filter(key => row[key] !== undefined).sort().map(key => JSON.stringify(key) + ':' + tenantWebCanonical(row[key])).join(',') + '}';
92
+ }
93
+ const hash = (value) => createHash('sha256').update(tenantWebCanonical(value)).digest('hex');
94
+ export function tenantWebSpecRevision(spec) { return 'sha256:' + hash(tenantWebSpecSchema.parse(spec)); }
95
+ export function tenantWebRequestKey(requestId) { return hash(tenantCollectionCycleSchema.parse(requestId)); }
96
+ export function tenantWebJobRef(tenantId, requestId) { return `tenant-web-collection://${tenantStorageKey(tenantId)}/${tenantWebRequestKey(requestId)}`; }
97
+ export const tenantWebJobRefSchema = z.string().regex(/^tenant-web-collection:\/\/[a-f0-9]{64}\/[a-f0-9]{64}$/);
98
+ export const tenantWebIntentSchema = z.object({
99
+ schemaVersion: z.literal(1), tenantId: materialTenantIdSchema, requestId: tenantCollectionCycleSchema,
100
+ jobRef: tenantWebJobRefSchema, inputRevision: sha256Schema, specRevision: sha256Schema, requestedSpec: tenantWebSpecSchema, spec: tenantWebSpecSchema,
101
+ actor: knowledgeActorContextSchema, authority: tenantCollectionRequestAuthoritySchema, submittedAt: isoDateTimeSchema,
102
+ }).strict().superRefine((value, ctx) => {
103
+ if (value.actor.tenantId !== value.tenantId || value.jobRef !== tenantWebJobRef(value.tenantId, value.requestId) || value.specRevision !== tenantWebSpecRevision(value.spec) || value.inputRevision !== tenantWebSpecRevision(value.requestedSpec))
104
+ ctx.addIssue({ code: 'custom', message: 'Intent must preserve exact Tenant and frozen specification identity' });
105
+ if (value.spec.limits.maxResourceBytes > Math.min(value.requestedSpec.limits.maxResourceBytes, value.requestedSpec.limits.maxTotalBytes) || tenantWebCanonical({ ...value.spec, limits: { ...value.spec.limits, maxResourceBytes: value.requestedSpec.limits.maxResourceBytes } }) !== tenantWebCanonical(value.requestedSpec))
106
+ ctx.addIssue({ code: 'custom', message: 'Intake may only narrow the resource byte limit' });
107
+ });
108
+ /** S1 仅证明意图持久化;不制造待采列表、原件、时效或准入成功。 */
109
+ export const tenantWebSummarySchema = z.object({
110
+ requestId: tenantCollectionCycleSchema, jobRef: tenantWebJobRefSchema, specRevision: sha256Schema, submittedAt: isoDateTimeSchema,
111
+ phase: z.literal('WEB_INTENT_PERSISTED'), state: z.literal('ACCEPTED'), execution: z.literal('UNAVAILABLE'),
112
+ reason: z.literal('S2_NOT_IMPLEMENTED'), completion: z.null(), networkValidated: z.literal(false), budgetReserved: z.literal(false),
113
+ requirementsState: z.literal('DECLARED_NOT_EVALUATED'),
114
+ coverage: z.object({ state: z.literal('NOT_STARTED'), total: z.null(), discovered: z.literal(0), acquired: z.literal(0), extracted: z.literal(0), registered: z.literal(0) }).strict(),
115
+ }).strict().superRefine((value, ctx) => {
116
+ if (new URL(value.jobRef).pathname !== `/${tenantWebRequestKey(value.requestId)}`)
117
+ ctx.addIssue({ code: 'custom', message: 'Summary request identity must match its exact intent reference' });
118
+ });
@@ -0,0 +1,86 @@
1
+ import { z } from 'zod';
2
+ import { tenantWebRequirementsSchema } from './tenant-web-collection.js';
3
+ export declare const TENANT_WEB_CONTENT_CAPABILITY = "TENANT_WEB_CONTENT_V1";
4
+ export declare const TENANT_WEB_CONTENT_EXTRACTOR: {
5
+ readonly id: "native-knowledge.web-content";
6
+ readonly version: "1.0.0";
7
+ };
8
+ export declare const tenantWebContentSelectorSchema: z.ZodString;
9
+ export declare const tenantWebContentPlanSchema: z.ZodObject<{
10
+ schemaVersion: z.ZodLiteral<1>;
11
+ compiler: z.ZodEnum<{
12
+ CALLER_PLAN_V1: "CALLER_PLAN_V1";
13
+ BOUNDED_LANGUAGE_V1: "BOUNDED_LANGUAGE_V1";
14
+ }>;
15
+ extractor: z.ZodObject<{
16
+ id: z.ZodLiteral<"native-knowledge.web-content">;
17
+ version: z.ZodLiteral<"1.0.0">;
18
+ }, z.core.$strict>;
19
+ body: z.ZodBoolean;
20
+ tables: z.ZodBoolean;
21
+ links: z.ZodBoolean;
22
+ recordSelector: z.ZodNullable<z.ZodString>;
23
+ fields: z.ZodArray<z.ZodObject<{
24
+ name: z.ZodString;
25
+ selector: z.ZodString;
26
+ value: z.ZodDefault<z.ZodEnum<{
27
+ TEXT: "TEXT";
28
+ JSON: "JSON";
29
+ ATTRIBUTE: "ATTRIBUTE";
30
+ }>>;
31
+ attribute: z.ZodDefault<z.ZodNullable<z.ZodEnum<{
32
+ datetime: "datetime";
33
+ value: "value";
34
+ title: "title";
35
+ href: "href";
36
+ alt: "alt";
37
+ content: "content";
38
+ src: "src";
39
+ }>>>;
40
+ type: z.ZodEnum<{
41
+ string: "string";
42
+ number: "number";
43
+ boolean: "boolean";
44
+ object: "object";
45
+ array: "array";
46
+ }>;
47
+ required: z.ZodDefault<z.ZodBoolean>;
48
+ }, z.core.$strip>>;
49
+ maxRecords: z.ZodDefault<z.ZodNumber>;
50
+ }, z.core.$strict>;
51
+ export type TenantWebContentPlan = z.infer<typeof tenantWebContentPlanSchema>;
52
+ export declare const tenantWebContentInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
53
+ mode: z.ZodLiteral<"NATURAL_LANGUAGE">;
54
+ }, z.core.$strict>, z.ZodObject<{
55
+ mode: z.ZodLiteral<"COMPILED">;
56
+ extractor: z.ZodDefault<z.ZodObject<{
57
+ id: z.ZodLiteral<"native-knowledge.web-content">;
58
+ version: z.ZodLiteral<"1.0.0">;
59
+ }, z.core.$strict>>;
60
+ body: z.ZodDefault<z.ZodBoolean>;
61
+ tables: z.ZodDefault<z.ZodBoolean>;
62
+ links: z.ZodDefault<z.ZodBoolean>;
63
+ recordSelector: z.ZodDefault<z.ZodNullable<z.ZodString>>;
64
+ fields: z.ZodDefault<z.ZodArray<z.ZodObject<{
65
+ name: z.ZodString;
66
+ selector: z.ZodString;
67
+ value: z.ZodDefault<z.ZodEnum<{
68
+ TEXT: "TEXT";
69
+ JSON: "JSON";
70
+ ATTRIBUTE: "ATTRIBUTE";
71
+ }>>;
72
+ attribute: z.ZodDefault<z.ZodNullable<z.ZodEnum<{
73
+ datetime: "datetime";
74
+ value: "value";
75
+ title: "title";
76
+ href: "href";
77
+ alt: "alt";
78
+ content: "content";
79
+ src: "src";
80
+ }>>>;
81
+ }, z.core.$strict>>>;
82
+ maxRecords: z.ZodDefault<z.ZodNumber>;
83
+ }, z.core.$strict>], "mode">;
84
+ export type TenantWebContentInput = z.input<typeof tenantWebContentInputSchema>;
85
+ export declare function compileTenantWebContent(requirements: z.infer<typeof tenantWebRequirementsSchema>, raw: unknown): TenantWebContentPlan;
86
+ export declare const tenantWebContentRevision: (plan: TenantWebContentPlan) => string;
@@ -0,0 +1,39 @@
1
+ /** Read-only extraction plans; no executable selectors, scripts, prompts or authority. */
2
+ import { createHash } from 'node:crypto';
3
+ import { z } from 'zod';
4
+ import { tenantWebCanonical, tenantWebRequirementsSchema } from './tenant-web-collection.js';
5
+ export const TENANT_WEB_CONTENT_CAPABILITY = 'TENANT_WEB_CONTENT_V1';
6
+ export const TENANT_WEB_CONTENT_EXTRACTOR = { id: 'native-knowledge.web-content', version: '1.0.0' };
7
+ // A deliberately bounded CSS subset: compound tag/id/classes, descendant and child only.
8
+ const atom = '(?:[A-Za-z][A-Za-z0-9_-]*|\\*)?(?:[.#][A-Za-z_][A-Za-z0-9_-]*)*';
9
+ export const tenantWebContentSelectorSchema = z.string().trim().min(1).max(256).refine(s => s.split(/\s*>\s*|\s+/).length <= 8 && new RegExp('^' + atom + '(?:\\s*>\\s*' + atom + '|\\s+' + atom + ')*$').test(s) && s.split(/\s*>\s*|\s+/).every(Boolean), 'Unsupported read-only selector').describe('Read-only CSS subset: tag/id/classes, descendant or child (>) only; max 8 segments, no pseudos or scripts');
10
+ const rule = z.object({ name: z.string().regex(/^[A-Za-z][A-Za-z0-9_]{0,63}$/), selector: tenantWebContentSelectorSchema, value: z.enum(['TEXT', 'ATTRIBUTE', 'JSON']).default('TEXT'), attribute: z.enum(['href', 'src', 'content', 'datetime', 'value', 'title', 'alt']).nullable().default(null) }).strict().refine(v => (v.value === 'ATTRIBUTE') === (v.attribute !== null));
11
+ export const tenantWebContentPlanSchema = z.object({ schemaVersion: z.literal(1), compiler: z.enum(['CALLER_PLAN_V1', 'BOUNDED_LANGUAGE_V1']), extractor: z.object({ id: z.literal('native-knowledge.web-content'), version: z.literal('1.0.0') }).strict(), body: z.boolean(), tables: z.boolean(), links: z.boolean(), recordSelector: tenantWebContentSelectorSchema.nullable(), fields: z.array(z.object({ ...tenantWebRequirementsSchema.shape.fields.unwrap().element.shape, ...rule.shape })).max(64), maxRecords: z.number().int().min(1).max(100).default(50) }).strict().superRefine((v, c) => { if (v.fields.some(f => (f.value === 'ATTRIBUTE') !== (f.attribute !== null)) || new Set(v.fields.map(f => f.name)).size !== v.fields.length)
12
+ c.addIssue({ code: 'custom', message: 'Invalid field rule' }); });
13
+ export const tenantWebContentInputSchema = z.discriminatedUnion('mode', [z.object({ mode: z.literal('NATURAL_LANGUAGE') }).strict(), z.object({ mode: z.literal('COMPILED'), extractor: z.object({ id: z.literal('native-knowledge.web-content'), version: z.literal('1.0.0') }).strict().default(TENANT_WEB_CONTENT_EXTRACTOR), body: z.boolean().default(false), tables: z.boolean().default(false), links: z.boolean().default(false), recordSelector: tenantWebContentSelectorSchema.nullable().default(null), fields: z.array(rule).max(64).default([]), maxRecords: z.number().int().min(1).max(100).default(50) }).strict()]).describe('NATURAL_LANGUAGE supports bounded body/tables/links combinations in Chinese or English. Otherwise provide COMPILED rules; no model calls.');
14
+ export function compileTenantWebContent(requirements, raw) {
15
+ const input = tenantWebContentInputSchema.parse(raw);
16
+ let body = false, tables = false, links = false;
17
+ if (input.mode === 'NATURAL_LANGUAGE') {
18
+ const words = requirements.instruction.toLowerCase().replace(/^(?:请)?(?:采集|提取|获取|collect|extract)\s*/, '').split(/\s*(?:、|,|,|和|及|与|\band\b)\s*/).map(w => w.trim()).filter(Boolean);
19
+ for (const word of words) {
20
+ if (['正文', 'body', 'text', 'body text'].includes(word))
21
+ body = true;
22
+ else if (['表格', 'tables', 'table'].includes(word))
23
+ tables = true;
24
+ else if (['链接', 'links'].includes(word))
25
+ links = true;
26
+ else
27
+ throw new Error('TENANT_WEB_SEMANTIC_COMPILER_UNAVAILABLE');
28
+ }
29
+ if (!words.length || requirements.fields.length)
30
+ throw new Error('TENANT_WEB_SEMANTIC_COMPILER_UNAVAILABLE');
31
+ }
32
+ const rules = input.mode === 'COMPILED' ? input.fields : [];
33
+ if (rules.length !== requirements.fields.length || rules.some(f => !requirements.fields.some(v => v.name === f.name)))
34
+ throw new Error('TENANT_WEB_CONTENT_FIELD_PLAN_REQUIRED');
35
+ if (requirements.outputs.includes('RECORDS') && !requirements.fields.length)
36
+ throw new Error('TENANT_WEB_CONTENT_FIELD_PLAN_REQUIRED');
37
+ return tenantWebContentPlanSchema.parse({ schemaVersion: 1, compiler: input.mode === 'COMPILED' ? 'CALLER_PLAN_V1' : 'BOUNDED_LANGUAGE_V1', extractor: TENANT_WEB_CONTENT_EXTRACTOR, body: input.mode === 'COMPILED' ? input.body : body, tables: input.mode === 'COMPILED' ? input.tables : tables, links: input.mode === 'COMPILED' ? input.links : links, recordSelector: input.mode === 'COMPILED' ? input.recordSelector : null, fields: requirements.fields.map(f => ({ ...f, ...rules.find(r => r.name === f.name) })), maxRecords: input.mode === 'COMPILED' ? input.maxRecords : 50 });
38
+ }
39
+ export const tenantWebContentRevision = (plan) => 'sha256:' + createHash('sha256').update(tenantWebCanonical(tenantWebContentPlanSchema.parse(plan))).digest('hex');
@@ -0,0 +1,63 @@
1
+ import { z } from 'zod';
2
+ export declare const TENANT_WEB_CONTENT_MEDIA_TYPE = "application/vnd.knowledge-v2.tenant-web-content+json";
3
+ export declare const tenantWebContentDocumentSchema: z.ZodObject<{
4
+ schemaVersion: z.ZodLiteral<1>;
5
+ format: z.ZodLiteral<"TENANT_WEB_CONTENT_V1">;
6
+ tenantId: z.ZodString;
7
+ jobRef: z.ZodString;
8
+ planRevision: z.ZodString;
9
+ extractor: z.ZodObject<{
10
+ id: z.ZodLiteral<"native-knowledge.web-content">;
11
+ version: z.ZodLiteral<"1.0.0">;
12
+ }, z.core.$strict>;
13
+ dependencies: z.ZodArray<z.ZodObject<{
14
+ id: z.ZodString;
15
+ version: z.ZodString;
16
+ }, z.core.$strict>>;
17
+ propagation: z.ZodLiteral<"TENANT_ONLY">;
18
+ reviewState: z.ZodLiteral<"UNREVIEWED">;
19
+ parentEvidenceRef: z.ZodString;
20
+ sourceContentHash: z.ZodString;
21
+ sourceByteLength: z.ZodNumber;
22
+ sourceMediaType: z.ZodString;
23
+ sourceUri: z.ZodString;
24
+ observedAt: z.ZodISODateTime;
25
+ extractedAt: z.ZodISODateTime;
26
+ outputs: z.ZodArray<z.ZodObject<{
27
+ name: z.ZodString;
28
+ state: z.ZodEnum<{
29
+ MISSING: "MISSING";
30
+ UNSUPPORTED: "UNSUPPORTED";
31
+ PRESENT: "PRESENT";
32
+ }>;
33
+ value: z.ZodNullable<z.ZodJSONSchema>;
34
+ citations: z.ZodArray<z.ZodObject<{
35
+ evidenceRef: z.ZodString;
36
+ contentHash: z.ZodString;
37
+ locator: z.ZodString;
38
+ excerpt: z.ZodString;
39
+ }, z.core.$strict>>;
40
+ reason: z.ZodNullable<z.ZodString>;
41
+ }, z.core.$strict>>;
42
+ records: z.ZodArray<z.ZodObject<{
43
+ ordinal: z.ZodNumber;
44
+ fields: z.ZodArray<z.ZodObject<{
45
+ name: z.ZodString;
46
+ state: z.ZodEnum<{
47
+ MISSING: "MISSING";
48
+ UNSUPPORTED: "UNSUPPORTED";
49
+ PRESENT: "PRESENT";
50
+ }>;
51
+ value: z.ZodNullable<z.ZodJSONSchema>;
52
+ citations: z.ZodArray<z.ZodObject<{
53
+ evidenceRef: z.ZodString;
54
+ contentHash: z.ZodString;
55
+ locator: z.ZodString;
56
+ excerpt: z.ZodString;
57
+ }, z.core.$strict>>;
58
+ reason: z.ZodNullable<z.ZodString>;
59
+ }, z.core.$strict>>;
60
+ }, z.core.$strict>>;
61
+ gaps: z.ZodArray<z.ZodString>;
62
+ }, z.core.$strict>;
63
+ export type TenantWebContentDocument = z.infer<typeof tenantWebContentDocumentSchema>;
@@ -0,0 +1,15 @@
1
+ import { z } from 'zod';
2
+ import { isoDateTimeSchema, sha256Schema } from './common.js';
3
+ import { materialTenantIdSchema } from './material-context.js';
4
+ import { tenantResourceRefSchema, parseTenantResourceRef, tenantStorageKey } from './resource-scope.js';
5
+ import { tenantWebJobRefSchema, tenantWebUrlSchema } from './tenant-web-collection.js';
6
+ import { tenantWebFieldResultSchema } from './tenant-web-results.js';
7
+ import { TENANT_WEB_CONTENT_EXTRACTOR } from './tenant-web-content-plan.js';
8
+ export const TENANT_WEB_CONTENT_MEDIA_TYPE = 'application/vnd.knowledge-v2.tenant-web-content+json';
9
+ export const tenantWebContentDocumentSchema = z.object({ schemaVersion: z.literal(1), format: z.literal('TENANT_WEB_CONTENT_V1'), tenantId: materialTenantIdSchema, jobRef: tenantWebJobRefSchema, planRevision: sha256Schema, extractor: z.object({ id: z.literal(TENANT_WEB_CONTENT_EXTRACTOR.id), version: z.literal(TENANT_WEB_CONTENT_EXTRACTOR.version) }).strict(), dependencies: z.array(z.object({ id: z.string().min(1).max(128), version: z.string().min(1).max(64) }).strict()).min(1).max(8), propagation: z.literal('TENANT_ONLY'), reviewState: z.literal('UNREVIEWED'), parentEvidenceRef: tenantResourceRefSchema, sourceContentHash: sha256Schema, sourceByteLength: z.number().int().nonnegative(), sourceMediaType: z.string().min(1).max(256), sourceUri: tenantWebUrlSchema, observedAt: isoDateTimeSchema, extractedAt: isoDateTimeSchema, outputs: z.array(tenantWebFieldResultSchema).max(4), records: z.array(z.object({ ordinal: z.number().int().min(0).max(99), fields: z.array(tenantWebFieldResultSchema).max(64) }).strict()).max(100), gaps: z.array(z.string().regex(/^[A-Z][A-Z0-9_]{0,127}$/)).max(32) }).strict().superRefine((v, c) => {
10
+ const key = tenantStorageKey(v.tenantId), parent = parseTenantResourceRef(v.parentEvidenceRef);
11
+ if (parent?.storageKey !== key || parent.resourceType !== 'evidence' || new URL(v.jobRef).hostname !== key || [...v.outputs, ...v.records.flatMap(r => r.fields)].some(f => f.citations.some(cite => cite.evidenceRef !== v.parentEvidenceRef || cite.contentHash !== v.sourceContentHash)))
12
+ c.addIssue({ code: 'custom', message: 'Content must cite its exact Tenant original' });
13
+ if (v.records.some((r, i) => r.ordinal !== i))
14
+ c.addIssue({ code: 'custom', message: 'Record order must be exact' });
15
+ });