@southwind-ai/server-sdk 0.1.1 → 0.1.3

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/index.ts CHANGED
@@ -1,5 +1,58 @@
1
+ export type { ModuleActor } from "./src/actor.js";
1
2
  export type {
3
+ ModuleAuditEmitter,
4
+ ModuleAuditEmitInput,
5
+ ModuleAuditTarget,
6
+ } from "./src/audit-port.js";
7
+ export type {
8
+ ModuleJobSubmitter,
9
+ ModuleJobSubmitInput,
10
+ ModuleJobSubmitResult,
11
+ } from "./src/jobs-port.js";
12
+ export type {
13
+ InstallableServerModule,
2
14
  ModuleHost,
3
15
  ModuleInitializer,
4
16
  ModuleUploadPolicy,
5
17
  } from "./src/module-host.js";
18
+ export { requireModuleNamespace } from "./src/namespace.js";
19
+ export type { ModuleRequestContext } from "./src/request-context.js";
20
+ export type { ModuleRolePreset } from "./src/role-preset.js";
21
+ export type {
22
+ ModuleRouteDefinition,
23
+ ModuleRouteHandler,
24
+ ModuleRouteMethod,
25
+ } from "./src/route-definition.js";
26
+ export type {
27
+ ModuleSearchContext,
28
+ ModuleSearchHealth,
29
+ ModuleSearchHit,
30
+ ModuleSearchPage,
31
+ ModuleSearchProvider,
32
+ ModuleSearchQuery,
33
+ } from "./src/search-provider-port.js";
34
+ export type {
35
+ ModuleStoragePort,
36
+ ModuleUploadSessionInput,
37
+ } from "./src/storage-port.js";
38
+ export type {
39
+ ModuleTaskHandler,
40
+ ModuleTaskHandlerRegistration,
41
+ ModuleTaskResult,
42
+ } from "./src/task-registration.js";
43
+ export type {
44
+ ModuleAgentToolHostPort,
45
+ ModuleAgentToolInvocation,
46
+ ModuleAgentToolResult,
47
+ } from "./src/tool-host-port.js";
48
+ export type {
49
+ ModuleToolContext,
50
+ ModuleToolHandlerRegistration,
51
+ ModuleToolResult,
52
+ } from "./src/tool-registration.js";
53
+ export type {
54
+ ModuleAiJsonValue,
55
+ ModuleAiOperationContext,
56
+ ModuleAiOperationHandlerRegistration,
57
+ ModuleAiOperationPlan,
58
+ } from "./src/ai-operation-registration.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@southwind-ai/server-sdk",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "license": "UNLICENSED",
5
5
  "type": "module",
6
6
  "engines": {
@@ -8,13 +8,28 @@
8
8
  },
9
9
  "files": [
10
10
  "index.ts",
11
- "src/module-host.ts"
11
+ "src/actor.ts",
12
+ "src/ai-operation-registration.ts",
13
+ "src/audit-port.ts",
14
+ "src/jobs-port.ts",
15
+ "src/module-host.ts",
16
+ "src/namespace.ts",
17
+ "src/request-context.ts",
18
+ "src/role-preset.ts",
19
+ "src/route-definition.ts",
20
+ "src/search-provider-port.ts",
21
+ "src/storage-port.ts",
22
+ "src/task-registration.ts",
23
+ "src/tool-registration.ts",
24
+ "src/tool-host-port.ts"
12
25
  ],
13
26
  "scripts": {
27
+ "test": "bun test",
14
28
  "typecheck": "tsc --noEmit --project tsconfig.json"
15
29
  },
16
30
  "dependencies": {
17
- "@southwind-ai/jobs": "0.1.1"
31
+ "@southwind-ai/jobs": "0.1.2",
32
+ "@southwind-ai/storage": "0.1.1"
18
33
  },
19
34
  "exports": {
20
35
  ".": "./index.ts"
package/src/actor.ts ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * 当前操作者的只读视图,与 Server 现有 Actor 模型对齐。
3
+ *
4
+ * 视图只暴露身份、角色与权限;凭据状态、数据范围令牌等宿主内部字段不下发。
5
+ * 运行时对象由宿主颁发,模块不得自行构造或修改。
6
+ */
7
+ export interface ModuleActor {
8
+ readonly id: string;
9
+ readonly type: "anonymous" | "user" | "service";
10
+ readonly name: string;
11
+ readonly username?: string;
12
+ readonly displayName?: string;
13
+ readonly roleCodes: readonly string[];
14
+ readonly permissionKeys: readonly string[];
15
+ }
@@ -0,0 +1,31 @@
1
+ import type { ModuleActor } from "./actor.js";
2
+
3
+ export type ModuleAiJsonValue =
4
+ | string
5
+ | number
6
+ | boolean
7
+ | null
8
+ | ModuleAiJsonValue[]
9
+ | { [key: string]: ModuleAiJsonValue };
10
+
11
+ export interface ModuleAiOperationContext {
12
+ readonly actor: ModuleActor;
13
+ readonly requestId: string;
14
+ }
15
+
16
+ /**
17
+ * 业务模块只负责把类型化输入收敛为模型无关的指令和用户消息。
18
+ * Provider、Deployment、Secret、Execution Grant 与 Tool 授权均由宿主持有。
19
+ */
20
+ export interface ModuleAiOperationPlan {
21
+ readonly instructions: string;
22
+ readonly userPrompt: string;
23
+ }
24
+
25
+ export interface ModuleAiOperationHandlerRegistration {
26
+ readonly operationKey: string;
27
+ prepare(
28
+ input: ModuleAiJsonValue,
29
+ context: ModuleAiOperationContext,
30
+ ): Promise<ModuleAiOperationPlan> | ModuleAiOperationPlan;
31
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * 模块审计事件的受控写入入口。
3
+ *
4
+ * 只允许 emit 本模块 Manifest `auditActions` 已注册的动作;越权动作在调用时抛错。
5
+ * 事件由宿主补齐 Actor、RequestId 与时间戳并写入统一 Audit Sink。
6
+ */
7
+ export interface ModuleAuditTarget {
8
+ readonly type: string;
9
+ readonly id?: string;
10
+ readonly label?: string;
11
+ }
12
+
13
+ export interface ModuleAuditEmitInput {
14
+ readonly target?: ModuleAuditTarget;
15
+ readonly metadata?: Record<string, unknown>;
16
+ /** 关键事件走宿主 Critical 写入策略(写入失败会抛出)。 */
17
+ readonly critical?: boolean;
18
+ }
19
+
20
+ export interface ModuleAuditEmitter {
21
+ emit(action: string, input?: ModuleAuditEmitInput): Promise<void>;
22
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * 模块提交 Durable Job 的窄接口。
3
+ *
4
+ * 只能提交到本模块命名空间的 Handler;Queue 由宿主强制为模块命名空间,
5
+ * 提交人由宿主以当前 Actor 身份补齐,模块无法伪造。
6
+ */
7
+ export interface ModuleJobSubmitInput {
8
+ readonly handlerKey: string;
9
+ readonly idempotencyKey: string;
10
+ readonly payload: Record<string, unknown>;
11
+ readonly priority?: number;
12
+ readonly maxAttempts?: number;
13
+ readonly timeoutSeconds?: number;
14
+ readonly availableAt?: Date;
15
+ }
16
+
17
+ export interface ModuleJobSubmitResult {
18
+ readonly jobId: string;
19
+ readonly created: boolean;
20
+ }
21
+
22
+ export interface ModuleJobSubmitter {
23
+ submit(input: ModuleJobSubmitInput): Promise<ModuleJobSubmitResult>;
24
+ }
@@ -1,4 +1,10 @@
1
1
  import type { DurableHandlerDefinition } from "@southwind-ai/jobs";
2
+ import type { ModuleAiOperationHandlerRegistration } from "./ai-operation-registration.js";
3
+ import type { ModuleRolePreset } from "./role-preset.js";
4
+ import type { ModuleRouteDefinition } from "./route-definition.js";
5
+ import type { ModuleSearchProvider } from "./search-provider-port.js";
6
+ import type { ModuleTaskHandlerRegistration } from "./task-registration.js";
7
+ import type { ModuleToolHandlerRegistration } from "./tool-registration.js";
2
8
 
3
9
  export interface ModuleUploadPolicy {
4
10
  purpose: string;
@@ -10,20 +16,54 @@ export interface ModuleUploadPolicy {
10
16
  }
11
17
 
12
18
  /**
13
- * 模块作用域 Host。注册的任务 Key 与上传用途必须使用初始化器模块名作为命名空间。
19
+ * 模块作用域 Host。注册的所有 Key(上传用途、任务、工具、角色预设、Provider)
20
+ * 必须使用初始化器模块名作为命名空间,越界或重复注册在 Server 监听前抛错。
21
+ *
22
+ * 模块只获得受限 Port(Guarded Route、Actor 视图、Audit、Durable Submit、
23
+ * 受限 Upload/BlobRead);Worker 与 Repository 始终由宿主持有。
14
24
  */
15
25
  export interface ModuleHost {
16
26
  readonly moduleName: string;
17
27
  registerUploadPolicy(policy: ModuleUploadPolicy): void;
18
28
  registerDurableHandler<T>(definition: DurableHandlerDefinition<T>): void;
29
+ /** 注册 Guarded API 路由;须与 Manifest `apiPermissions` 声明一致。 */
30
+ registerRoutes(routes: readonly ModuleRouteDefinition[]): void;
31
+ /** 注册 Manifest `tasks` 已声明定时任务的执行体。 */
32
+ registerTaskHandlers(
33
+ registrations: readonly ModuleTaskHandlerRegistration[],
34
+ ): void;
35
+ /** 注册 Manifest `tools` 已声明 Agent Tool 的执行体。 */
36
+ registerToolHandlers(
37
+ registrations: readonly ModuleToolHandlerRegistration[],
38
+ ): void;
39
+ /** 注册 Manifest `aiOperations` 已声明的模型无关 Operation 执行计划。 */
40
+ registerAiOperationHandlers(
41
+ registrations: readonly ModuleAiOperationHandlerRegistration[],
42
+ ): void;
43
+ /** 注册角色预设;permissionKeys 须属于本模块 Manifest 权限声明。 */
44
+ registerRolePresets(presets: readonly ModuleRolePreset[]): void;
45
+ /** 注册 Manifest `providers` 已声明的搜索 Provider。 */
46
+ registerSearchProviders(providers: readonly ModuleSearchProvider[]): void;
19
47
  }
20
48
 
21
49
  /**
22
50
  * 已安装模块的 Server 初始化入口。
23
51
  *
24
52
  * 初始化器在 Storage 与 Durable Job 运行时创建前顺序执行;这里只注册定义,不启动 Worker。
53
+ * 路由、任务、工具与 Provider 的实现体可延迟绑定宿主运行时创建的服务。
25
54
  */
26
55
  export interface ModuleInitializer {
27
56
  readonly moduleName: string;
28
57
  initialize(host: ModuleHost): Promise<void> | void;
29
58
  }
59
+
60
+ /**
61
+ * 可安装业务模块的完整 Server 契约。
62
+ *
63
+ * Manifest 与 setup 必须由同一安装单元贡献,避免宿主分别维护声明工厂和初始化器。
64
+ * TManifest 由能力目录包提供,SDK 因而不依赖具体 Manifest 实现。
65
+ */
66
+ export interface InstallableServerModule<TManifest> {
67
+ readonly manifest: TManifest;
68
+ setup(host: ModuleHost): Promise<void> | void;
69
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 模块命名空间约束:注册的 Key 必须等于模块名,或以 `<moduleName>.` 开头。
3
+ * 宿主在所有注册入口统一调用,越界注册在 Server 监听前抛错。
4
+ */
5
+ export function requireModuleNamespace(
6
+ kind: string,
7
+ value: string,
8
+ moduleName: string,
9
+ ): void {
10
+ if (value !== moduleName && !value.startsWith(`${moduleName}.`)) {
11
+ throw new Error(`${kind}不属于模块 ${moduleName}:${value}`);
12
+ }
13
+ }
@@ -0,0 +1,21 @@
1
+ import type { ModuleActor } from "./actor.js";
2
+ import type { ModuleAuditEmitter } from "./audit-port.js";
3
+ import type { ModuleJobSubmitter } from "./jobs-port.js";
4
+ import type { ModuleStoragePort } from "./storage-port.js";
5
+
6
+ /**
7
+ * 模块路由 Handler 的受限请求上下文。
8
+ *
9
+ * 不暴露 Elysia 内部对象、数据库连接或任何 Repository;
10
+ * 模块只能经由 Actor 视图与受限 Port(Audit / Jobs / Storage)与平台交互。
11
+ */
12
+ export interface ModuleRequestContext {
13
+ readonly requestId: string;
14
+ readonly actor: ModuleActor;
15
+ readonly params: Record<string, string | undefined>;
16
+ readonly query: Record<string, string | undefined>;
17
+ readonly body?: unknown;
18
+ readonly audit: ModuleAuditEmitter;
19
+ readonly jobs: ModuleJobSubmitter;
20
+ readonly storage: ModuleStoragePort;
21
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * 模块贡献的角色预设。
3
+ *
4
+ * `key` 作为角色 Code,必须使用模块命名空间;`permissionKeys` 必须全部属于
5
+ * 本模块 Manifest `permissions` 声明(宿主在启动时校验)。预设随内置角色一起
6
+ * 同步入库:不存在则创建,权限或菜单漂移则收敛,不改变 4 个内置角色语义。
7
+ */
8
+ export interface ModuleRolePreset {
9
+ readonly key: string;
10
+ readonly label: string;
11
+ readonly description?: string;
12
+ readonly dataScope?:
13
+ | "all"
14
+ | "department"
15
+ | "department-and-children"
16
+ | "self";
17
+ readonly permissionKeys: readonly string[];
18
+ }
@@ -0,0 +1,26 @@
1
+ import type { ModuleRequestContext } from "./request-context.js";
2
+
3
+ export type ModuleRouteMethod = "GET" | "POST" | "PUT" | "DELETE";
4
+
5
+ export type ModuleRouteHandler = (
6
+ context: ModuleRequestContext,
7
+ ) => Promise<unknown> | unknown;
8
+
9
+ /**
10
+ * 模块贡献的 API 路由定义。
11
+ *
12
+ * `method` + `path` 必须与本模块 Manifest `apiPermissions` 中的声明一致
13
+ * (path 含 `/api` 前缀);宿主据此绑定 Guard(权限 / Feature / License),
14
+ * 无需模块手工接线。`permissionKey` 必须与 Manifest 绑定一致并属于本模块命名空间。
15
+ *
16
+ * 声明 `auditAction` 时,宿主在 Handler 成功返回后自动写入一条该动作的审计事件;
17
+ * 动作必须是本模块 Manifest `auditActions` 已注册的动作。
18
+ */
19
+ export interface ModuleRouteDefinition {
20
+ readonly method: ModuleRouteMethod;
21
+ readonly path: string;
22
+ readonly permissionKey: string;
23
+ readonly featureKey?: string;
24
+ readonly auditAction?: string;
25
+ readonly handler: ModuleRouteHandler;
26
+ }
@@ -0,0 +1,48 @@
1
+ import type { ModuleActor } from "./actor.js";
2
+
3
+ export interface ModuleSearchQuery {
4
+ readonly text: string;
5
+ readonly limit: number;
6
+ readonly cursor?: string;
7
+ readonly signal: AbortSignal;
8
+ }
9
+
10
+ export interface ModuleSearchContext {
11
+ readonly actor: ModuleActor;
12
+ readonly requestId: string;
13
+ }
14
+
15
+ export interface ModuleSearchHit {
16
+ readonly id: string;
17
+ readonly resourceType: string;
18
+ readonly maskedTitle: string;
19
+ readonly maskedExcerpt?: string;
20
+ readonly score?: number;
21
+ }
22
+
23
+ export interface ModuleSearchPage {
24
+ readonly hits: ModuleSearchHit[];
25
+ readonly nextCursor?: string;
26
+ }
27
+
28
+ export interface ModuleSearchHealth {
29
+ readonly status: "healthy" | "degraded" | "unavailable";
30
+ readonly checkedAt: string;
31
+ readonly message?: string;
32
+ }
33
+
34
+ /**
35
+ * 模块搜索 Provider。
36
+ *
37
+ * `key` 必须在本模块 Manifest `providers` 中声明;返回的标题与摘要必须是
38
+ * 已脱敏文本,明文访问与导出由目标资源与治理导出走各自 Guard。
39
+ */
40
+ export interface ModuleSearchProvider {
41
+ readonly key: string;
42
+ readonly providerVersion: string;
43
+ search(
44
+ query: ModuleSearchQuery,
45
+ context: ModuleSearchContext,
46
+ ): Promise<ModuleSearchPage>;
47
+ health(signal: AbortSignal): Promise<ModuleSearchHealth>;
48
+ }
@@ -0,0 +1,25 @@
1
+ import type { OpenedFile, UploadSession } from "@southwind-ai/storage";
2
+
3
+ export interface ModuleUploadSessionInput {
4
+ readonly purpose: string;
5
+ readonly filename: string;
6
+ readonly mimeType: string;
7
+ readonly expectedByteSize: number;
8
+ readonly expectedSha256?: string;
9
+ readonly fileExpiresAt?: Date;
10
+ }
11
+
12
+ /**
13
+ * 模块受限 Upload / BlobRead Port。
14
+ *
15
+ * - `createUploadSession` 的 purpose 必须是本模块经 Host 注册的 Upload Policy,
16
+ * 跨模块或平台用途一律拒绝;Owner 由宿主以当前 Actor 身份补齐。
17
+ * - `openFile` 走 FileService 的 Owner 约束,且文件用途必须属于本模块。
18
+ * - `openPublicFile` 走 FileService 的 Purpose 约束,用途同样必须属于本模块。
19
+ * - 模块不允许直接接触 BlobStore 或 Upload Repository。
20
+ */
21
+ export interface ModuleStoragePort {
22
+ createUploadSession(input: ModuleUploadSessionInput): Promise<UploadSession>;
23
+ openFile(fileId: string): Promise<OpenedFile>;
24
+ openPublicFile(fileId: string, purpose: string): Promise<OpenedFile>;
25
+ }
@@ -0,0 +1,18 @@
1
+ export type ModuleTaskResult = Record<string, unknown> | void;
2
+
3
+ export type ModuleTaskHandler = () =>
4
+ | Promise<ModuleTaskResult>
5
+ | ModuleTaskResult;
6
+
7
+ /**
8
+ * 模块定时任务的 Handler 注册。
9
+ *
10
+ * `taskKey` 必须在本模块 Manifest `tasks` 中声明;调度元数据(间隔、重试、
11
+ * Feature、权限)一律以 Manifest 为准,这里只提供执行体。
12
+ */
13
+ export interface ModuleTaskHandlerRegistration {
14
+ readonly taskKey: string;
15
+ readonly handler: ModuleTaskHandler;
16
+ /** 判断执行结果是否为空转(用于调度指标统计),与平台任务语义一致。 */
17
+ readonly isIdleResult?: (value: ModuleTaskResult) => boolean;
18
+ }
@@ -0,0 +1,22 @@
1
+ import type { ModuleAiJsonValue } from "./ai-operation-registration.js";
2
+
3
+ export interface ModuleAgentToolInvocation {
4
+ readonly runId: string;
5
+ readonly toolCallId: string;
6
+ readonly toolKey: string;
7
+ readonly arguments: Readonly<Record<string, ModuleAiJsonValue>>;
8
+ }
9
+
10
+ export interface ModuleAgentToolResult {
11
+ readonly value: ModuleAiJsonValue;
12
+ }
13
+
14
+ /**
15
+ * 宿主创建并绑定 Operation、Actor 与 Scope 的受限 Tool Host Port。
16
+ * 调用方不能传 Permission、Feature、License 或数据范围作为授权事实。
17
+ */
18
+ export interface ModuleAgentToolHostPort {
19
+ execute(
20
+ invocation: ModuleAgentToolInvocation,
21
+ ): Promise<ModuleAgentToolResult>;
22
+ }
@@ -0,0 +1,29 @@
1
+ import type { ModuleActor } from "./actor.js";
2
+
3
+ export interface ModuleToolContext {
4
+ readonly actor: ModuleActor;
5
+ readonly requestId: string;
6
+ }
7
+
8
+ export interface ModuleToolResult {
9
+ readonly items: unknown[];
10
+ readonly total: number;
11
+ readonly page: number;
12
+ readonly pageSize: number;
13
+ }
14
+
15
+ /**
16
+ * 模块 Agent Tool 的 Handler 注册。
17
+ *
18
+ * `toolKey` 必须在本模块 Manifest `tools` 中声明;Guard(权限 / Feature /
19
+ * 数据范围)由宿主在 Agent 路由层统一执行。`scopeMode: "request"` 的 Handler
20
+ * 只会在持有服务端数据范围上下文的 Actor 下执行。
21
+ */
22
+ export interface ModuleToolHandlerRegistration {
23
+ readonly toolKey: string;
24
+ readonly scopeMode: "platform" | "request";
25
+ execute(
26
+ query: Record<string, string | undefined>,
27
+ context: ModuleToolContext,
28
+ ): Promise<ModuleToolResult> | ModuleToolResult;
29
+ }