@prodivix/shared 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Minsecrus 2025
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ export * from './types/PdxComponent';
2
+ export * from './llm';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,OAAO,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from './types/PdxComponent';
2
+ export * from './llm';
@@ -0,0 +1,9 @@
1
+ import type { LlmContextBundle, LlmContextEntry } from './types';
2
+ export declare class LlmContextBuilder {
3
+ private readonly entries;
4
+ private readonly omittedContext;
5
+ add<TValue>(entry: LlmContextEntry<TValue>): this;
6
+ omit(reason: string): this;
7
+ build(tokenBudget?: number): LlmContextBundle;
8
+ }
9
+ //# sourceMappingURL=contextBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contextBuilder.d.ts","sourceRoot":"","sources":["../../src/llm/contextBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEjE,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAE/C,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC,GAAG,IAAI;IASjD,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK1B,KAAK,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,gBAAgB;CAO9C"}
@@ -0,0 +1,22 @@
1
+ export class LlmContextBuilder {
2
+ entries = [];
3
+ omittedContext = [];
4
+ add(entry) {
5
+ if (this.entries.some((current) => current.id === entry.id)) {
6
+ throw new Error(`LLM context entry already exists: ${entry.id}`);
7
+ }
8
+ this.entries.push(entry);
9
+ return this;
10
+ }
11
+ omit(reason) {
12
+ this.omittedContext.push(reason);
13
+ return this;
14
+ }
15
+ build(tokenBudget) {
16
+ return {
17
+ entries: [...this.entries],
18
+ omittedContext: [...this.omittedContext],
19
+ tokenBudget,
20
+ };
21
+ }
22
+ }
@@ -0,0 +1,28 @@
1
+ import type { LlmProvider, LlmTaskRequest, LlmTaskResult } from './types';
2
+ import type { LlmTraceStore } from './traceStore';
3
+ import { LlmToolRegistry } from './toolRegistry';
4
+ export interface LlmGatewayOptions {
5
+ provider: LlmProvider;
6
+ tools: LlmToolRegistry;
7
+ traceStore?: LlmTraceStore;
8
+ createId?: () => string;
9
+ now?: () => string;
10
+ }
11
+ /**
12
+ * LLM Gateway 是 MFE 内部 AI 调用链路的统一入口:先按任务挑选允许的工具,
13
+ * 再调用 provider,随后校验输出通道并写入 trace,最后返回可 dry-run 或可计划化的结果。
14
+ *
15
+ * LlmGateway is the unified MFE AI execution entrypoint: it picks task-allowed
16
+ * tools, calls the provider, validates the output channel, records trace data,
17
+ * and returns a result ready for planning or dry-run handling.
18
+ */
19
+ export declare class LlmGateway {
20
+ private readonly provider;
21
+ private readonly tools;
22
+ private readonly traceStore?;
23
+ private readonly createId;
24
+ private readonly now;
25
+ constructor(options: LlmGatewayOptions);
26
+ run(task: LlmTaskRequest): Promise<LlmTaskResult>;
27
+ }
28
+ //# sourceMappingURL=gateway.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../src/llm/gateway.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,WAAW,EAGX,cAAc,EACd,aAAa,EACd,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,WAAW,CAAC;IACtB,KAAK,EAAE,eAAe,CAAC;IACvB,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAkDD;;;;;;;GAOG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAc;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAgB;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,OAAO,EAAE,iBAAiB;IAQhC,GAAG,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CA6ExD"}
@@ -0,0 +1,118 @@
1
+ import { LlmProviderError } from './types';
2
+ import { LlmToolRegistry } from './toolRegistry';
3
+ const defaultCreateId = () => `llm_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`;
4
+ const defaultNow = () => new Date().toISOString();
5
+ const getOutputChannel = (output) => {
6
+ if ('channel' in output) {
7
+ return output.channel;
8
+ }
9
+ return 'plan';
10
+ };
11
+ const unwrapProviderResult = (result) => {
12
+ if (isProviderResultEnvelope(result)) {
13
+ return result;
14
+ }
15
+ return { output: result };
16
+ };
17
+ const isProviderResultEnvelope = (result) => typeof result === 'object' &&
18
+ result !== null &&
19
+ 'output' in result &&
20
+ isStructuredOutput(result.output);
21
+ const isStructuredOutput = (value) => {
22
+ if (typeof value !== 'object' || value === null) {
23
+ return false;
24
+ }
25
+ const candidate = value;
26
+ return (('goal' in candidate && typeof candidate.goal === 'string') ||
27
+ ('channel' in candidate &&
28
+ (candidate.channel === 'pir-command' ||
29
+ candidate.channel === 'node-graph-operation' ||
30
+ candidate.channel === 'code-artifact')));
31
+ };
32
+ /**
33
+ * LLM Gateway 是 MFE 内部 AI 调用链路的统一入口:先按任务挑选允许的工具,
34
+ * 再调用 provider,随后校验输出通道并写入 trace,最后返回可 dry-run 或可计划化的结果。
35
+ *
36
+ * LlmGateway is the unified MFE AI execution entrypoint: it picks task-allowed
37
+ * tools, calls the provider, validates the output channel, records trace data,
38
+ * and returns a result ready for planning or dry-run handling.
39
+ */
40
+ export class LlmGateway {
41
+ provider;
42
+ tools;
43
+ traceStore;
44
+ createId;
45
+ now;
46
+ constructor(options) {
47
+ this.provider = options.provider;
48
+ this.tools = options.tools;
49
+ this.traceStore = options.traceStore;
50
+ this.createId = options.createId ?? defaultCreateId;
51
+ this.now = options.now ?? defaultNow;
52
+ }
53
+ async run(task) {
54
+ const startedAt = this.now();
55
+ const traceId = this.createId();
56
+ const allowedTools = this.tools.pick(task.allowedTools);
57
+ try {
58
+ const providerResult = await this.provider.generate({
59
+ task,
60
+ tools: allowedTools,
61
+ });
62
+ const { output, rawResponse } = unwrapProviderResult(providerResult);
63
+ const outputChannel = getOutputChannel(output);
64
+ if (outputChannel !== 'plan' &&
65
+ !task.outputChannels.includes(outputChannel)) {
66
+ throw new Error(`Provider returned disallowed LLM output channel: ${outputChannel}`);
67
+ }
68
+ const completedAt = this.now();
69
+ await this.traceStore?.append({
70
+ id: traceId,
71
+ taskId: task.id,
72
+ userIntent: task.intent,
73
+ modelProviderId: this.provider.id,
74
+ context: task.context,
75
+ toolNames: allowedTools.map((tool) => tool.name),
76
+ toolCalls: [],
77
+ diagnostics: [],
78
+ startedAt,
79
+ completedAt,
80
+ });
81
+ return {
82
+ taskId: task.id,
83
+ status: task.requiresPlan ? 'planned' : 'dry-run',
84
+ output,
85
+ rawResponse,
86
+ diagnostics: [],
87
+ traceId,
88
+ };
89
+ }
90
+ catch (error) {
91
+ const rawResponse = error instanceof LlmProviderError ? error.rawResponse : undefined;
92
+ const diagnostic = {
93
+ code: 'LLM_PROVIDER_FAILED',
94
+ severity: 'error',
95
+ message: error instanceof Error ? error.message : 'LLM provider failed.',
96
+ };
97
+ await this.traceStore?.append({
98
+ id: traceId,
99
+ taskId: task.id,
100
+ userIntent: task.intent,
101
+ modelProviderId: this.provider.id,
102
+ context: task.context,
103
+ toolNames: allowedTools.map((tool) => tool.name),
104
+ toolCalls: [],
105
+ diagnostics: [diagnostic],
106
+ startedAt,
107
+ completedAt: this.now(),
108
+ });
109
+ return {
110
+ taskId: task.id,
111
+ status: 'failed',
112
+ rawResponse,
113
+ diagnostics: [diagnostic],
114
+ traceId,
115
+ };
116
+ }
117
+ }
118
+ }
@@ -0,0 +1,7 @@
1
+ export * from './contextBuilder';
2
+ export * from './gateway';
3
+ export * from './mockProvider';
4
+ export * from './toolRegistry';
5
+ export * from './traceStore';
6
+ export * from './types';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/llm/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC"}
@@ -0,0 +1,6 @@
1
+ export * from './contextBuilder';
2
+ export * from './gateway';
3
+ export * from './mockProvider';
4
+ export * from './toolRegistry';
5
+ export * from './traceStore';
6
+ export * from './types';
@@ -0,0 +1,8 @@
1
+ import type { LlmProvider, LlmProviderGenerateResult, LlmProviderRequest, LlmStructuredOutput } from './types';
2
+ export declare class MockLlmProvider implements LlmProvider {
3
+ private readonly output;
4
+ readonly id = "mock";
5
+ constructor(output: LlmStructuredOutput);
6
+ generate(_request: LlmProviderRequest): Promise<LlmProviderGenerateResult>;
7
+ }
8
+ //# sourceMappingURL=mockProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mockProvider.d.ts","sourceRoot":"","sources":["../../src/llm/mockProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAEjB,qBAAa,eAAgB,YAAW,WAAW;IAGrC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,QAAQ,CAAC,EAAE,UAAU;gBAEQ,MAAM,EAAE,mBAAmB;IAExD,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAAC,yBAAyB,CAAC;CAG3E"}
@@ -0,0 +1,10 @@
1
+ export class MockLlmProvider {
2
+ output;
3
+ id = 'mock';
4
+ constructor(output) {
5
+ this.output = output;
6
+ }
7
+ generate(_request) {
8
+ return Promise.resolve(this.output);
9
+ }
10
+ }
@@ -0,0 +1,9 @@
1
+ import type { LlmToolDefinition } from './types';
2
+ export declare class LlmToolRegistry {
3
+ private readonly tools;
4
+ register(tool: LlmToolDefinition): void;
5
+ get(name: string): LlmToolDefinition | undefined;
6
+ list(): readonly LlmToolDefinition[];
7
+ pick(names: readonly string[]): readonly LlmToolDefinition[];
8
+ }
9
+ //# sourceMappingURL=toolRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolRegistry.d.ts","sourceRoot":"","sources":["../../src/llm/toolRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwC;IAE9D,QAAQ,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI;IAQvC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAIhD,IAAI,IAAI,SAAS,iBAAiB,EAAE;IAIpC,IAAI,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,iBAAiB,EAAE;CAW7D"}
@@ -0,0 +1,24 @@
1
+ export class LlmToolRegistry {
2
+ tools = new Map();
3
+ register(tool) {
4
+ if (this.tools.has(tool.name)) {
5
+ throw new Error(`LLM tool already registered: ${tool.name}`);
6
+ }
7
+ this.tools.set(tool.name, tool);
8
+ }
9
+ get(name) {
10
+ return this.tools.get(name);
11
+ }
12
+ list() {
13
+ return Array.from(this.tools.values());
14
+ }
15
+ pick(names) {
16
+ return names.map((name) => {
17
+ const tool = this.tools.get(name);
18
+ if (!tool) {
19
+ throw new Error(`Unknown LLM tool: ${name}`);
20
+ }
21
+ return tool;
22
+ });
23
+ }
24
+ }
@@ -0,0 +1,10 @@
1
+ import type { LlmGatewayTrace } from './types';
2
+ export interface LlmTraceStore {
3
+ append(trace: LlmGatewayTrace): void | Promise<void>;
4
+ }
5
+ export declare class InMemoryLlmTraceStore implements LlmTraceStore {
6
+ private readonly traces;
7
+ append(trace: LlmGatewayTrace): void;
8
+ list(): readonly LlmGatewayTrace[];
9
+ }
10
+ //# sourceMappingURL=traceStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceStore.d.ts","sourceRoot":"","sources":["../../src/llm/traceStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD;AAED,qBAAa,qBAAsB,YAAW,aAAa;IACzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAEhD,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAIpC,IAAI,IAAI,SAAS,eAAe,EAAE;CAGnC"}
@@ -0,0 +1,9 @@
1
+ export class InMemoryLlmTraceStore {
2
+ traces = [];
3
+ append(trace) {
4
+ this.traces.push(trace);
5
+ }
6
+ list() {
7
+ return [...this.traces];
8
+ }
9
+ }
@@ -0,0 +1,173 @@
1
+ export type LlmOutputChannel = 'pir-command' | 'node-graph-operation' | 'code-artifact';
2
+ export type LlmRiskLevel = 'low' | 'medium' | 'high';
3
+ export type LlmTaskStatus = 'planned' | 'dry-run' | 'applied' | 'failed';
4
+ export type LlmContextAuthority = 'authoritative' | 'summary';
5
+ export type LlmCodeArtifactKind = 'node-code' | 'external-runtime-code' | 'adapter-code' | 'test-code' | 'shader-code' | 'worker-code' | 'utility-code';
6
+ export type LlmDiagnosticSeverity = 'info' | 'warning' | 'error';
7
+ export type LlmToolSideEffect = 'read' | 'dry-run' | 'write' | 'verify';
8
+ export type LlmResponseMode = 'json' | 'tool-calls' | 'text-with-json';
9
+ export type LlmToolSchemaFormat = 'json-schema' | 'openai-compatible' | 'anthropic-compatible' | 'gemini-compatible';
10
+ export interface LlmModelPreferences {
11
+ jsonMode?: boolean;
12
+ toolCalling?: boolean;
13
+ vision?: boolean;
14
+ longContext?: boolean;
15
+ }
16
+ export interface LlmExecutionBudget {
17
+ maxOutputTokens?: number;
18
+ temperature?: number;
19
+ timeoutMs?: number;
20
+ }
21
+ export interface LlmProviderCapabilities {
22
+ responseModes: readonly LlmResponseMode[];
23
+ toolSchemaFormats: readonly LlmToolSchemaFormat[];
24
+ supportsStreaming: boolean;
25
+ supportsJsonMode: boolean;
26
+ supportsToolCalling: boolean;
27
+ supportsVision: boolean;
28
+ supportsLongContext: boolean;
29
+ }
30
+ export interface LlmDiagnostic {
31
+ code: string;
32
+ message: string;
33
+ severity: LlmDiagnosticSeverity;
34
+ path?: string;
35
+ allowedValues?: readonly string[];
36
+ repairHint?: string;
37
+ }
38
+ export interface LlmContextEntry<TValue = unknown> {
39
+ id: string;
40
+ title: string;
41
+ authority: LlmContextAuthority;
42
+ value: TValue;
43
+ description?: string;
44
+ }
45
+ export interface LlmContextBundle {
46
+ entries: readonly LlmContextEntry[];
47
+ tokenBudget?: number;
48
+ omittedContext?: readonly string[];
49
+ }
50
+ export interface LlmPlanMilestone {
51
+ id: string;
52
+ title: string;
53
+ description?: string;
54
+ }
55
+ export interface LlmPlanArtifact {
56
+ goal: string;
57
+ assumptions: readonly string[];
58
+ milestones: readonly LlmPlanMilestone[];
59
+ }
60
+ export interface LlmPirCommandBatch {
61
+ channel: 'pir-command';
62
+ commands: readonly unknown[];
63
+ riskLevel: LlmRiskLevel;
64
+ }
65
+ export interface LlmNodeGraphOperationBatch {
66
+ channel: 'node-graph-operation';
67
+ operations: readonly unknown[];
68
+ riskLevel: LlmRiskLevel;
69
+ }
70
+ export interface LlmCodeArtifact {
71
+ channel: 'code-artifact';
72
+ id: string;
73
+ kind: LlmCodeArtifactKind;
74
+ language: string;
75
+ content: string;
76
+ ownerId?: string;
77
+ bindTargetId?: string;
78
+ riskLevel: LlmRiskLevel;
79
+ }
80
+ export type LlmStructuredOutput = LlmPlanArtifact | LlmPirCommandBatch | LlmNodeGraphOperationBatch | LlmCodeArtifact;
81
+ export type LlmProviderGenerateResult<TOutput extends LlmStructuredOutput = LlmStructuredOutput> = TOutput | {
82
+ output: TOutput;
83
+ rawResponse?: string;
84
+ };
85
+ export interface LlmProviderErrorOptions {
86
+ rawResponse?: string;
87
+ }
88
+ export declare class LlmProviderError extends Error {
89
+ readonly rawResponse?: string;
90
+ constructor(message: string, options?: LlmProviderErrorOptions);
91
+ }
92
+ export interface LlmTaskRequest {
93
+ id: string;
94
+ intent: string;
95
+ context: LlmContextBundle;
96
+ allowedTools: readonly string[];
97
+ outputChannels: readonly LlmOutputChannel[];
98
+ modelPreferences?: LlmModelPreferences;
99
+ responseMode?: LlmResponseMode;
100
+ streaming?: boolean;
101
+ toolSchemaFormat?: LlmToolSchemaFormat;
102
+ providerMetadata?: Record<string, unknown>;
103
+ budget?: LlmExecutionBudget;
104
+ requiresPlan?: boolean;
105
+ }
106
+ export interface LlmTaskResult<TOutput extends LlmStructuredOutput = LlmStructuredOutput> {
107
+ taskId: string;
108
+ status: LlmTaskStatus;
109
+ output?: TOutput;
110
+ rawResponse?: string;
111
+ diagnostics: readonly LlmDiagnostic[];
112
+ traceId?: string;
113
+ }
114
+ export type LlmStreamEvent = {
115
+ type: 'started';
116
+ taskId: string;
117
+ traceId: string;
118
+ providerId: string;
119
+ } | {
120
+ type: 'raw-delta';
121
+ delta: string;
122
+ } | {
123
+ type: 'raw-snapshot';
124
+ rawResponse: string;
125
+ } | {
126
+ type: 'diagnostic';
127
+ diagnostic: LlmDiagnostic;
128
+ } | {
129
+ type: 'validated-output';
130
+ output: LlmStructuredOutput;
131
+ rawResponse: string;
132
+ } | {
133
+ type: 'completed';
134
+ result: LlmTaskResult;
135
+ };
136
+ export interface LlmToolDefinition<TInput = unknown, TOutput = unknown> {
137
+ name: string;
138
+ description: string;
139
+ sideEffect: LlmToolSideEffect;
140
+ requiresDryRun?: boolean;
141
+ riskLevel?: LlmRiskLevel;
142
+ execute(input: TInput): Promise<TOutput> | TOutput;
143
+ }
144
+ export interface LlmToolCallRecord {
145
+ name: string;
146
+ sideEffect: LlmToolSideEffect;
147
+ startedAt: string;
148
+ completedAt?: string;
149
+ diagnostics?: readonly LlmDiagnostic[];
150
+ }
151
+ export interface LlmProviderRequest {
152
+ task: LlmTaskRequest;
153
+ tools: readonly LlmToolDefinition[];
154
+ }
155
+ export interface LlmProvider {
156
+ id: string;
157
+ capabilities?: LlmProviderCapabilities;
158
+ generate(request: LlmProviderRequest): Promise<LlmProviderGenerateResult>;
159
+ stream?(request: LlmProviderRequest): AsyncIterable<LlmStreamEvent>;
160
+ }
161
+ export interface LlmGatewayTrace {
162
+ id: string;
163
+ taskId: string;
164
+ userIntent: string;
165
+ modelProviderId: string;
166
+ context: LlmContextBundle;
167
+ toolNames: readonly string[];
168
+ toolCalls: readonly LlmToolCallRecord[];
169
+ diagnostics: readonly LlmDiagnostic[];
170
+ startedAt: string;
171
+ completedAt?: string;
172
+ }
173
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/llm/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export class LlmProviderError extends Error {
2
+ rawResponse;
3
+ constructor(message, options) {
4
+ super(message);
5
+ this.name = 'LlmProviderError';
6
+ this.rawResponse = options?.rawResponse;
7
+ }
8
+ }
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ export interface PdxComponent {
3
+ className?: string;
4
+ style?: React.CSSProperties;
5
+ id?: string;
6
+ dataAttributes?: Record<string, string>;
7
+ onClick?: React.MouseEventHandler;
8
+ as?: React.ElementType;
9
+ }
10
+ //# sourceMappingURL=PdxComponent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PdxComponent.d.ts","sourceRoot":"","sources":["../../src/types/PdxComponent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC;IAClC,EAAE,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC;CACxB"}
@@ -0,0 +1 @@
1
+ import React from 'react';
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Generated from PIR Schema v1.0
3
+ * DO NOT EDIT - Run `pnpm run generate-types` to regenerate
4
+ */
5
+ export interface PIRDocumentV10 {
6
+ version: string;
7
+ metadata?: {
8
+ name?: string;
9
+ description?: string;
10
+ tags?: string[];
11
+ [k: string]: unknown;
12
+ };
13
+ ui: {
14
+ root: ComponentNode;
15
+ };
16
+ logic?: {
17
+ graphs?: {
18
+ [k: string]: NodeGraph;
19
+ };
20
+ state?: {
21
+ [k: string]: StateDef;
22
+ };
23
+ };
24
+ }
25
+ export interface ComponentNode {
26
+ id?: string;
27
+ type: string;
28
+ text?: string;
29
+ style?: {
30
+ [k: string]: unknown;
31
+ };
32
+ props?: {
33
+ [k: string]: unknown;
34
+ };
35
+ children?: ComponentNode[];
36
+ events?: {
37
+ [k: string]: EventBinding;
38
+ };
39
+ binding?: DataBinding;
40
+ resources?: {
41
+ [k: string]: Resource;
42
+ };
43
+ _comment?: string;
44
+ }
45
+ export interface EventBinding {
46
+ target: string;
47
+ payload?: {
48
+ [k: string]: unknown;
49
+ };
50
+ debounce?: number;
51
+ preventDefault?: boolean;
52
+ }
53
+ export interface DataBinding {
54
+ path: string;
55
+ type: 'string' | 'number' | 'boolean' | 'object' | 'array';
56
+ }
57
+ export interface Resource {
58
+ type: 'file' | 'url' | 'inline';
59
+ value: string;
60
+ mimeType?: string;
61
+ }
62
+ export interface NodeGraph {
63
+ id: string;
64
+ name?: string;
65
+ nodes: GraphNode[];
66
+ edges: GraphEdge[];
67
+ }
68
+ export interface GraphNode {
69
+ id: string;
70
+ type: string;
71
+ inputs?: {
72
+ [k: string]: unknown;
73
+ }[];
74
+ outputs?: {
75
+ [k: string]: unknown;
76
+ }[];
77
+ config?: {
78
+ [k: string]: unknown;
79
+ };
80
+ }
81
+ export interface GraphEdge {
82
+ id: string;
83
+ source: {
84
+ nodeId: string;
85
+ port: string;
86
+ [k: string]: unknown;
87
+ };
88
+ target: {
89
+ nodeId: string;
90
+ port: string;
91
+ [k: string]: unknown;
92
+ };
93
+ }
94
+ export interface StateDef {
95
+ type: 'local' | 'global' | 'derived';
96
+ initial?: unknown;
97
+ schema?: {
98
+ [k: string]: unknown;
99
+ };
100
+ }
101
+ //# sourceMappingURL=pir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pir.d.ts","sourceRoot":"","sources":["../../src/types/pir.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;KACtB,CAAC;IACF,EAAE,EAAE;QACF,IAAI,EAAE,aAAa,CAAC;KACrB,CAAC;IACF,KAAK,CAAC,EAAE;QACN,MAAM,CAAC,EAAE;YACP,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;SACxB,CAAC;QACF,KAAK,CAAC,EAAE;YACN,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;SACvB,CAAC;KACH,CAAC;CACH;AACD,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QACN,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;KACtB,CAAC;IACF,KAAK,CAAC,EAAE;QACN,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;KACtB,CAAC;IACF,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE;QACP,CAAC,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;KAC3B,CAAC;IACF,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,SAAS,CAAC,EAAE;QACV,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;KACvB,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE;QACR,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;KACtB,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AACD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;CAC5D;AACD,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AACD,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE;QACP,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;KACtB,EAAE,CAAC;IACJ,OAAO,CAAC,EAAE;QACR,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;KACtB,EAAE,CAAC;IACJ,MAAM,CAAC,EAAE;QACP,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;KACtB,CAAC;CACH;AACD,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;KACtB,CAAC;IACF,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;KACtB,CAAC;CACH;AACD,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE;QACP,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;KACtB,CAAC;CACH"}
@@ -0,0 +1,6 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * Generated from PIR Schema v1.0
4
+ * DO NOT EDIT - Run `pnpm run generate-types` to regenerate
5
+ */
6
+ export {};
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@prodivix/shared",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ },
12
+ "./types/*": {
13
+ "types": "./dist/types/*.d.ts",
14
+ "import": "./dist/types/*.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "scripts"
20
+ ],
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "devDependencies": {
25
+ "@types/react": "^19.2.2",
26
+ "json-schema-to-typescript": "^15.0.4",
27
+ "typescript": "~5.9.3"
28
+ },
29
+ "peerDependencies": {
30
+ "react": "^19.1.1"
31
+ },
32
+ "dependencies": {
33
+ "ajv": "^8.17.1",
34
+ "ajv-formats": "^3.0.1",
35
+ "chalk": "^5.6.2"
36
+ },
37
+ "scripts": {
38
+ "build": "pnpm run clean && tsc -p tsconfig.json",
39
+ "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
40
+ "generate-types": "node scripts/generate-types.js"
41
+ }
42
+ }
@@ -0,0 +1,39 @@
1
+ import { compileFromFile } from 'json-schema-to-typescript';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+
9
+ const SCHEMA_PATH = path.join(__dirname, '../../../specs/pir/PIR-v1.0.json');
10
+ const OUTPUT_PATH = path.join(__dirname, '../src/types/pir.ts');
11
+
12
+ console.log('📄 从Schema生成TS类型...');
13
+ console.log(` Schema: ${SCHEMA_PATH}`);
14
+ console.log(` 输出: ${OUTPUT_PATH}`);
15
+
16
+ compileFromFile(SCHEMA_PATH, {
17
+ bannerComment:
18
+ '/* eslint-disable */\n/**\n * Generated from PIR Schema v1.0\n * DO NOT EDIT - Run `pnpm run generate-types` to regenerate\n */',
19
+ format: true,
20
+ style: {
21
+ singleQuote: true,
22
+ semi: true,
23
+ tabWidth: 2,
24
+ },
25
+ })
26
+ .then((ts) => {
27
+ // 确保目录存在
28
+ fs.mkdirSync(path.dirname(OUTPUT_PATH), { recursive: true });
29
+
30
+ // 写入文件
31
+ fs.writeFileSync(OUTPUT_PATH, ts);
32
+
33
+ console.log('✅ 类型生成成功!');
34
+ console.log(` 共生成 ${ts.split('\n').length} 行类型定义`);
35
+ })
36
+ .catch((err) => {
37
+ console.error('❌ 生成失败:', err.message);
38
+ process.exit(1);
39
+ });
@@ -0,0 +1,52 @@
1
+ import { readFileSync } from 'fs';
2
+ import { resolve, dirname } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import Ajv from 'ajv';
5
+ import addFormats from 'ajv-formats';
6
+ import chalk from 'chalk';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+
11
+ const SCHEMA_PATH = resolve(__dirname, '../../../specs/pir/PIR-v1.0.json');
12
+
13
+ // 创建AJV实例
14
+ const ajv = new Ajv({ allErrors: true, verbose: true });
15
+ addFormats(ajv);
16
+
17
+ // 编译Schema
18
+ const schema = JSON.parse(readFileSync(SCHEMA_PATH, 'utf-8'));
19
+ const validate = ajv.compile(schema);
20
+
21
+ // CLI参数
22
+ const pirPath = resolve(process.argv[2] || './project.pir.json');
23
+
24
+ console.log('🔍 校验PIR文件...');
25
+ console.log(` Schema: ${SCHEMA_PATH}`);
26
+ console.log(` 文件: ${pirPath}`);
27
+
28
+ try {
29
+ const pir = JSON.parse(readFileSync(pirPath, 'utf-8'));
30
+ const valid = validate(pir);
31
+
32
+ if (valid) {
33
+ console.log(chalk.green('\n✅ PIR格式正确!'));
34
+ process.exit(0);
35
+ } else {
36
+ console.error(chalk.red('\n❌ 校验失败:'));
37
+ validate.errors?.forEach((error, i) => {
38
+ console.error(
39
+ chalk.red(`\n ${i + 1}. ${error.instancePath || 'root'}`) +
40
+ chalk.gray(`\n ${error.message}`) +
41
+ chalk.yellow(`\n 参数: ${JSON.stringify(error.params)}`)
42
+ );
43
+ if (error.schemaPath) {
44
+ console.error(chalk.gray(` Schema路径: ${error.schemaPath}`));
45
+ }
46
+ });
47
+ process.exit(1);
48
+ }
49
+ } catch (error) {
50
+ console.error(chalk.red(`\n💥 致命错误: ${error.message}`));
51
+ process.exit(1);
52
+ }