@lemonppt/agent-prompts 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 +21 -0
- package/dist/fallback.d.ts +13 -0
- package/dist/fallback.d.ts.map +1 -0
- package/dist/fallback.js +183 -0
- package/dist/fallback.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/llm.d.ts +25 -0
- package/dist/llm.d.ts.map +1 -0
- package/dist/llm.js +43 -0
- package/dist/llm.js.map +1 -0
- package/dist/prompt.d.ts +17 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +104 -0
- package/dist/prompt.js.map +1 -0
- package/package.json +42 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 lemonforme
|
|
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,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 当未配置 LLM API Key 时,基于用户输入生成一份 demo 级别的 goal.json。
|
|
3
|
+
* fallback 直接产出完整 Slide(含 role + layout),仍走 recomposeDeck 规范化。
|
|
4
|
+
*/
|
|
5
|
+
import type { DeckGoal } from '@lemonppt/core';
|
|
6
|
+
export interface FallbackOptions {
|
|
7
|
+
input: string;
|
|
8
|
+
pageCount?: number;
|
|
9
|
+
theme?: string;
|
|
10
|
+
language?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function createFallbackGoal(options: FallbackOptions): DeckGoal;
|
|
13
|
+
//# sourceMappingURL=fallback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fallback.d.ts","sourceRoot":"","sources":["../src/fallback.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA2BD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,QAAQ,CAyIrE"}
|
package/dist/fallback.js
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 当未配置 LLM API Key 时,基于用户输入生成一份 demo 级别的 goal.json。
|
|
3
|
+
* fallback 直接产出完整 Slide(含 role + layout),仍走 recomposeDeck 规范化。
|
|
4
|
+
*/
|
|
5
|
+
const layoutToRole = (layout) => {
|
|
6
|
+
if (layout.startsWith('cover'))
|
|
7
|
+
return 'cover';
|
|
8
|
+
if (layout.startsWith('table_of_contents'))
|
|
9
|
+
return 'tableOfContents';
|
|
10
|
+
if (layout.startsWith('metric'))
|
|
11
|
+
return 'metric';
|
|
12
|
+
if (layout.startsWith('stats'))
|
|
13
|
+
return 'stats';
|
|
14
|
+
if (layout.startsWith('chart'))
|
|
15
|
+
return 'chart';
|
|
16
|
+
if (layout.startsWith('comparison'))
|
|
17
|
+
return 'comparison';
|
|
18
|
+
if (layout.startsWith('pricing'))
|
|
19
|
+
return 'pricing';
|
|
20
|
+
if (layout.startsWith('process'))
|
|
21
|
+
return 'process';
|
|
22
|
+
if (layout.startsWith('timeline'))
|
|
23
|
+
return 'timeline';
|
|
24
|
+
if (layout.startsWith('roadmap'))
|
|
25
|
+
return 'roadmap';
|
|
26
|
+
if (layout.startsWith('quote'))
|
|
27
|
+
return 'quote';
|
|
28
|
+
if (layout.startsWith('testimonial'))
|
|
29
|
+
return 'testimonial';
|
|
30
|
+
if (layout.startsWith('faq'))
|
|
31
|
+
return 'faq';
|
|
32
|
+
if (layout.startsWith('feature'))
|
|
33
|
+
return 'feature';
|
|
34
|
+
if (layout.startsWith('team'))
|
|
35
|
+
return 'team';
|
|
36
|
+
if (layout.startsWith('partners'))
|
|
37
|
+
return 'partners';
|
|
38
|
+
if (layout.startsWith('gallery'))
|
|
39
|
+
return 'gallery';
|
|
40
|
+
if (layout.startsWith('image'))
|
|
41
|
+
return 'image';
|
|
42
|
+
if (layout.startsWith('swot'))
|
|
43
|
+
return 'swot';
|
|
44
|
+
if (layout.startsWith('pest'))
|
|
45
|
+
return 'pest';
|
|
46
|
+
if (layout.startsWith('closing'))
|
|
47
|
+
return 'closing';
|
|
48
|
+
return 'content';
|
|
49
|
+
};
|
|
50
|
+
export function createFallbackGoal(options) {
|
|
51
|
+
const { input, pageCount = 5, theme = 'base', language = 'zh' } = options;
|
|
52
|
+
const title = input.split(/[。!?\n]/)[0].slice(0, 30) || '未命名演示';
|
|
53
|
+
const baseSlides = [
|
|
54
|
+
{
|
|
55
|
+
layout: 'cover_v1',
|
|
56
|
+
props: {
|
|
57
|
+
kicker: '自动生成',
|
|
58
|
+
title,
|
|
59
|
+
subtitle: '由 lemonPPT 根据您的描述生成',
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
layout: 'table_of_contents_v1',
|
|
64
|
+
props: {
|
|
65
|
+
kicker: '目录',
|
|
66
|
+
title: '内容概览',
|
|
67
|
+
items: ['核心要点', '关键数据', '实施流程', '展望未来'],
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
layout: 'content_v2',
|
|
72
|
+
props: {
|
|
73
|
+
kicker: '核心要点',
|
|
74
|
+
title: '本次分享的重点',
|
|
75
|
+
leftPoints: [`主题:${title}`, '结构清晰,重点突出'],
|
|
76
|
+
rightPoints: ['支持多主题切换', '导出可编辑 PPTX'],
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
layout: 'metric_v1',
|
|
81
|
+
props: {
|
|
82
|
+
label: '效率提升',
|
|
83
|
+
value: '10',
|
|
84
|
+
unit: '倍',
|
|
85
|
+
description: '使用 lemonPPT 自动生成演示文稿',
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
layout: 'process_v2',
|
|
90
|
+
props: {
|
|
91
|
+
kicker: '流程',
|
|
92
|
+
title: '三步完成',
|
|
93
|
+
steps: [
|
|
94
|
+
{ title: '描述需求', description: '用自然语言输入 PPT 主题与重点' },
|
|
95
|
+
{ title: 'AI 生成内容', description: '自动规划页面并填充文案' },
|
|
96
|
+
{ title: '导出演示文稿', description: '支持 PPTX、PDF 与 HTML' },
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
layout: 'chart_v1',
|
|
102
|
+
props: {
|
|
103
|
+
kicker: '数据洞察',
|
|
104
|
+
title: '增长趋势',
|
|
105
|
+
type: 'bar',
|
|
106
|
+
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
|
|
107
|
+
data: [12, 19, 28, 40],
|
|
108
|
+
unit: '%',
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
layout: 'quote_v2',
|
|
113
|
+
props: {
|
|
114
|
+
quote: '好的演示文稿不是信息的堆砌,而是观点的提炼。',
|
|
115
|
+
author: 'lemonPPT',
|
|
116
|
+
role: '设计原则',
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
layout: 'swot_v1',
|
|
121
|
+
props: {
|
|
122
|
+
title: 'SWOT 简析',
|
|
123
|
+
strength: 'AI 自动化生成,节省时间',
|
|
124
|
+
weakness: '复杂图表仍需手动调整',
|
|
125
|
+
opportunity: '可扩展为企业私有化部署',
|
|
126
|
+
threat: '同类产品竞争激烈',
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
layout: 'closing_v2',
|
|
131
|
+
props: {
|
|
132
|
+
title: '开始创作',
|
|
133
|
+
subtitle: '用 lemonPPT 把你的想法变成演示',
|
|
134
|
+
contact: 'lemonPPT 团队',
|
|
135
|
+
email: 'hello@lemonppt.dev',
|
|
136
|
+
link: 'https://lemonppt.dev',
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
];
|
|
140
|
+
const slides = baseSlides
|
|
141
|
+
.slice(0, pageCount)
|
|
142
|
+
.map((s) => ({ role: layoutToRole(s.layout), layout: s.layout, props: s.props }));
|
|
143
|
+
// 如果页数少于基础版式,确保最后一页是结尾页
|
|
144
|
+
const lastSlide = slides[slides.length - 1];
|
|
145
|
+
if (lastSlide && lastSlide.role !== 'closing') {
|
|
146
|
+
const closing = baseSlides.find((s) => layoutToRole(s.layout) === 'closing');
|
|
147
|
+
if (closing) {
|
|
148
|
+
slides[slides.length - 1] = {
|
|
149
|
+
role: 'closing',
|
|
150
|
+
layout: closing.layout,
|
|
151
|
+
props: closing.props,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// 如果页数多于基础版式,用内容页填充
|
|
156
|
+
while (slides.length < pageCount) {
|
|
157
|
+
slides.splice(slides.length - 1, 0, {
|
|
158
|
+
role: 'content',
|
|
159
|
+
layout: 'content_v3',
|
|
160
|
+
props: {
|
|
161
|
+
kicker: `补充页 ${slides.length}`,
|
|
162
|
+
title: '更多内容',
|
|
163
|
+
points: [
|
|
164
|
+
`围绕“${title}”展开说明`,
|
|
165
|
+
'可替换为 AI 生成的要点',
|
|
166
|
+
'保持整体叙事一致',
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
title,
|
|
173
|
+
goal: input,
|
|
174
|
+
audience: '通用观众',
|
|
175
|
+
owner: 'lemonPPT',
|
|
176
|
+
theme,
|
|
177
|
+
language,
|
|
178
|
+
pageCount,
|
|
179
|
+
randomSeed: `fallback-${Date.now()}`,
|
|
180
|
+
slides,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=fallback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fallback.js","sourceRoot":"","sources":["../src/fallback.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { DeckGoal } from '@lemonppt/core';
|
|
2
|
+
import { createFallbackGoal } from './fallback.js';
|
|
3
|
+
import { callOpenAICompatible, type LlmOptions } from './llm.js';
|
|
4
|
+
import { buildPrompt, type PromptContext } from './prompt.js';
|
|
5
|
+
export interface GenerateGoalOptions extends PromptContext {
|
|
6
|
+
/** LLM 配置;不提供则使用 fallback */
|
|
7
|
+
llm?: LlmOptions;
|
|
8
|
+
}
|
|
9
|
+
export interface GenerateGoalResult {
|
|
10
|
+
goal: DeckGoal;
|
|
11
|
+
source: 'llm' | 'fallback';
|
|
12
|
+
raw?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function generateGoal(options: GenerateGoalOptions): Promise<GenerateGoalResult>;
|
|
15
|
+
export { buildPrompt, createFallbackGoal, callOpenAICompatible };
|
|
16
|
+
export type { PromptContext, LlmOptions };
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAE9D,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,6BAA6B;IAC7B,GAAG,CAAC,EAAE,UAAU,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,KAAK,GAAG,UAAU,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAgBD,wBAAsB,YAAY,CAChC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CA4B7B;AAED,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,CAAC;AACjE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { validateRawGoal } from '@lemonppt/core';
|
|
2
|
+
import { composeDeckFromRaw, recomposeDeck } from '@lemonppt/composer';
|
|
3
|
+
import { createFallbackGoal } from './fallback.js';
|
|
4
|
+
import { callOpenAICompatible } from './llm.js';
|
|
5
|
+
import { buildPrompt } from './prompt.js';
|
|
6
|
+
function extractJson(text) {
|
|
7
|
+
// 尝试去除 markdown 代码块
|
|
8
|
+
const codeBlockMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
9
|
+
if (codeBlockMatch) {
|
|
10
|
+
return codeBlockMatch[1].trim();
|
|
11
|
+
}
|
|
12
|
+
// 尝试提取第一个 { ... }
|
|
13
|
+
const jsonMatch = text.match(/\{[\s\S]*\}/);
|
|
14
|
+
if (jsonMatch) {
|
|
15
|
+
return jsonMatch[0].trim();
|
|
16
|
+
}
|
|
17
|
+
return text.trim();
|
|
18
|
+
}
|
|
19
|
+
export async function generateGoal(options) {
|
|
20
|
+
const { input, pageCount, theme, language, llm } = options;
|
|
21
|
+
// 无 API Key 时直接 fallback
|
|
22
|
+
const apiKey = llm?.apiKey ?? process.env.OPENAI_API_KEY;
|
|
23
|
+
if (!apiKey) {
|
|
24
|
+
const goal = recomposeDeck(createFallbackGoal({ input, pageCount, theme, language }));
|
|
25
|
+
return { goal, source: 'fallback' };
|
|
26
|
+
}
|
|
27
|
+
const prompt = buildPrompt({ input, pageCount, theme, language });
|
|
28
|
+
const response = await callOpenAICompatible(prompt, llm);
|
|
29
|
+
const raw = extractJson(response.content);
|
|
30
|
+
let parsed;
|
|
31
|
+
try {
|
|
32
|
+
parsed = JSON.parse(raw);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
throw new Error(`LLM 返回不是合法 JSON: ${err instanceof Error ? err.message : String(err)}\n\n${raw}`);
|
|
36
|
+
}
|
|
37
|
+
const validation = validateRawGoal(parsed);
|
|
38
|
+
if (!validation.success || !validation.data) {
|
|
39
|
+
throw new Error(`goal.json 校验失败: ${JSON.stringify(validation.errors?.format())}`);
|
|
40
|
+
}
|
|
41
|
+
const goal = recomposeDeck(composeDeckFromRaw(validation.data));
|
|
42
|
+
return { goal, source: 'llm', raw };
|
|
43
|
+
}
|
|
44
|
+
export { buildPrompt, createFallbackGoal, callOpenAICompatible };
|
|
45
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAmB,MAAM,UAAU,CAAC;AACjE,OAAO,EAAE,WAAW,EAAsB,MAAM,aAAa,CAAC;AAa9D,SAAS,WAAW,CAAC,IAAY;IAC/B,oBAAoB;IACpB,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClE,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClC,CAAC;IACD,kBAAkB;IAClB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAC5C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAA4B;IAE5B,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IAE3D,yBAAyB;IACzB,MAAM,MAAM,GAAG,GAAG,EAAE,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACzD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,aAAa,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QACtF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IACtC,CAAC;IAED,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClE,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACzD,MAAM,GAAG,GAAG,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAE1C,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACpG,CAAC;IAED,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,IAAI,GAAG,aAAa,CAAC,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AACtC,CAAC;AAED,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,CAAC"}
|
package/dist/llm.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 基于 fetch 的 OpenAI 兼容 API 调用。
|
|
3
|
+
*/
|
|
4
|
+
export interface LlmOptions {
|
|
5
|
+
/** API Key;留空则使用 fallback */
|
|
6
|
+
apiKey?: string;
|
|
7
|
+
/** 基础 URL,默认 OpenAI */
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
/** 模型名称 */
|
|
10
|
+
model?: string;
|
|
11
|
+
/** 最大 token */
|
|
12
|
+
maxTokens?: number;
|
|
13
|
+
/** 温度 */
|
|
14
|
+
temperature?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface LlmResponse {
|
|
17
|
+
content: string;
|
|
18
|
+
usage?: {
|
|
19
|
+
promptTokens?: number;
|
|
20
|
+
completionTokens?: number;
|
|
21
|
+
totalTokens?: number;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export declare function callOpenAICompatible(prompt: string, options?: LlmOptions): Promise<LlmResponse>;
|
|
25
|
+
//# sourceMappingURL=llm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,UAAU;IACzB,6BAA6B;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS;IACT,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE;QACN,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,UAAe,GACvB,OAAO,CAAC,WAAW,CAAC,CAyDtB"}
|
package/dist/llm.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 基于 fetch 的 OpenAI 兼容 API 调用。
|
|
3
|
+
*/
|
|
4
|
+
export async function callOpenAICompatible(prompt, options = {}) {
|
|
5
|
+
const { apiKey = process.env.OPENAI_API_KEY, baseUrl = process.env.OPENAI_BASE_URL ?? 'https://api.openai.com/v1', model = process.env.OPENAI_MODEL ?? 'gpt-4o-mini', maxTokens = 4096, temperature = 0.7, } = options;
|
|
6
|
+
if (!apiKey) {
|
|
7
|
+
throw new Error('缺少 LLM API Key。请提供 apiKey 参数或设置 OPENAI_API_KEY 环境变量。');
|
|
8
|
+
}
|
|
9
|
+
const response = await fetch(`${baseUrl}/chat/completions`, {
|
|
10
|
+
method: 'POST',
|
|
11
|
+
headers: {
|
|
12
|
+
'Content-Type': 'application/json',
|
|
13
|
+
Authorization: `Bearer ${apiKey}`,
|
|
14
|
+
},
|
|
15
|
+
body: JSON.stringify({
|
|
16
|
+
model,
|
|
17
|
+
messages: [
|
|
18
|
+
{ role: 'system', content: '你是一个专业的演示文稿规划助手。' },
|
|
19
|
+
{ role: 'user', content: prompt },
|
|
20
|
+
],
|
|
21
|
+
max_tokens: maxTokens,
|
|
22
|
+
temperature,
|
|
23
|
+
}),
|
|
24
|
+
});
|
|
25
|
+
if (!response.ok) {
|
|
26
|
+
const text = await response.text().catch(() => 'unknown');
|
|
27
|
+
throw new Error(`LLM 请求失败 (${response.status}): ${text}`);
|
|
28
|
+
}
|
|
29
|
+
const json = (await response.json());
|
|
30
|
+
const content = json.choices?.[0]?.message?.content;
|
|
31
|
+
if (!content) {
|
|
32
|
+
throw new Error('LLM 返回内容为空');
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
content,
|
|
36
|
+
usage: {
|
|
37
|
+
promptTokens: json.usage?.prompt_tokens,
|
|
38
|
+
completionTokens: json.usage?.completion_tokens,
|
|
39
|
+
totalTokens: json.usage?.total_tokens,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=llm.js.map
|
package/dist/llm.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"AAAA;;GAEG;AAwBH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAc,EACd,UAAsB,EAAE;IAExB,MAAM,EACJ,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,EACnC,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,2BAA2B,EACpE,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,aAAa,EACjD,SAAS,GAAG,IAAI,EAChB,WAAW,GAAG,GAAG,GAClB,GAAG,OAAO,CAAC;IAEZ,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,mBAAmB,EAAE;QAC1D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,MAAM,EAAE;SAClC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,KAAK;YACL,QAAQ,EAAE;gBACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,kBAAkB,EAAE;gBAC/C,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE;aAClC;YACD,UAAU,EAAE,SAAS;YACrB,WAAW;SACZ,CAAC;KACH,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,aAAa,QAAQ,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAOlC,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC;IACpD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;IAChC,CAAC;IAED,OAAO;QACL,OAAO;QACP,KAAK,EAAE;YACL,YAAY,EAAE,IAAI,CAAC,KAAK,EAAE,aAAa;YACvC,gBAAgB,EAAE,IAAI,CAAC,KAAK,EAAE,iBAAiB;YAC/C,WAAW,EAAE,IAAI,CAAC,KAAK,EAAE,YAAY;SACtC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/prompt.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 构建用于将自然语言需求转换为 lemonPPT goal.json 的 LLM prompt。
|
|
3
|
+
* 自 0.x 起,Agent 不再直接选择版式,而是输出“页面角色(role) + props”,
|
|
4
|
+
* 由 deckComposer 自动将 role 映射为最合适的版式。
|
|
5
|
+
*/
|
|
6
|
+
export interface PromptContext {
|
|
7
|
+
/** 用户原始输入 */
|
|
8
|
+
input: string;
|
|
9
|
+
/** 可选:期望页数 */
|
|
10
|
+
pageCount?: number;
|
|
11
|
+
/** 可选:指定主题 */
|
|
12
|
+
theme?: string;
|
|
13
|
+
/** 可选:目标语言 */
|
|
14
|
+
language?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function buildPrompt(context: PromptContext): string;
|
|
17
|
+
//# sourceMappingURL=prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,aAAa;IAC5B,aAAa;IACb,KAAK,EAAE,MAAM,CAAC;IACd,cAAc;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAwED,wBAAgB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CA6B1D"}
|
package/dist/prompt.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 构建用于将自然语言需求转换为 lemonPPT goal.json 的 LLM prompt。
|
|
3
|
+
* 自 0.x 起,Agent 不再直接选择版式,而是输出“页面角色(role) + props”,
|
|
4
|
+
* 由 deckComposer 自动将 role 映射为最合适的版式。
|
|
5
|
+
*/
|
|
6
|
+
const ROLE_CATALOG = `
|
|
7
|
+
可用页面角色(按内容类型选择)及其常用 props:
|
|
8
|
+
|
|
9
|
+
1. cover - 封面页
|
|
10
|
+
props: { kicker?: string, title: string, subtitle?: string, date?: string, image?: string }
|
|
11
|
+
|
|
12
|
+
2. tableOfContents - 目录页
|
|
13
|
+
props: { kicker?: string, title: string, items?: string[] }
|
|
14
|
+
|
|
15
|
+
3. metric - 超大数字/核心指标页
|
|
16
|
+
props: { kicker?: string, label?: string, value: string, unit?: string, description?: string }
|
|
17
|
+
|
|
18
|
+
4. stats - 关键指标网格页(多指标 2x2 展示)
|
|
19
|
+
props: { kicker?: string, title: string, stats?: { label?: string, value?: string, unit?: string, change?: string }[] }
|
|
20
|
+
|
|
21
|
+
5. chart - 基础图表页(柱状图/折线图/饼图)
|
|
22
|
+
props: { title: string, kicker?: string, type?: 'bar' | 'line' | 'pie', labels?: string[], data?: number[], unit?: string }
|
|
23
|
+
|
|
24
|
+
6. comparison - 左右对比/优缺点对比页
|
|
25
|
+
props: { kicker?: string, title: string, leftTitle?: string, leftPoints?: string[], rightTitle?: string, rightPoints?: string[] }
|
|
26
|
+
|
|
27
|
+
7. pricing - 价格方案页
|
|
28
|
+
props: { kicker?: string, title: string, tiers?: { name?: string, price?: string, period?: string, features?: string[], cta?: string }[] }
|
|
29
|
+
|
|
30
|
+
8. process - 流程步骤页
|
|
31
|
+
props: { kicker?: string, title: string, steps?: string[] | { title?: string; description?: string }[] }
|
|
32
|
+
|
|
33
|
+
9. timeline - 时间线/里程碑页
|
|
34
|
+
props: { kicker?: string, title: string, milestones?: { date?: string, title?: string, description?: string }[] }
|
|
35
|
+
|
|
36
|
+
10. roadmap - 路线图页(阶段规划)
|
|
37
|
+
props: { kicker?: string, title: string, phases?: { title?: string, description?: string, status?: string }[] }
|
|
38
|
+
|
|
39
|
+
11. quote - 居中文摘/侧栏引用页
|
|
40
|
+
props: { quote: string, author?: string, source?: string, role?: string }
|
|
41
|
+
|
|
42
|
+
12. testimonial - 客户评价页(引用 + 头像/公司)
|
|
43
|
+
props: { quote: string, author?: string, role?: string, avatarUrl?: string, company?: string }
|
|
44
|
+
|
|
45
|
+
13. content - 要点/双列/图文并排内容页
|
|
46
|
+
props: { kicker?: string, title: string, points?: string[], leftPoints?: string[], rightPoints?: string[], imageUrl?: string, imageAlt?: string }
|
|
47
|
+
|
|
48
|
+
14. faq - 问答页
|
|
49
|
+
props: { kicker?: string, title: string, items?: { q?: string, a?: string }[] }
|
|
50
|
+
|
|
51
|
+
15. feature - 产品特性页
|
|
52
|
+
props: { kicker?: string, title: string, features?: { title?: string, description?: string }[] }
|
|
53
|
+
|
|
54
|
+
16. team - 团队介绍页
|
|
55
|
+
props: { kicker?: string, title: string, members?: { name?: string, role?: string, bio?: string, imageUrl?: string }[] }
|
|
56
|
+
|
|
57
|
+
17. partners - 合作伙伴墙页
|
|
58
|
+
props: { kicker?: string, title: string, partners?: { name?: string, logoUrl?: string }[] }
|
|
59
|
+
|
|
60
|
+
18. image - 全屏图片页
|
|
61
|
+
props: { title: string, subtitle?: string, imageUrl?: string, imageAlt?: string }
|
|
62
|
+
|
|
63
|
+
19. gallery - 图片画廊页
|
|
64
|
+
props: { kicker?: string, title: string, images?: { url?: string, caption?: string }[] }
|
|
65
|
+
|
|
66
|
+
20. swot - SWOT 分析页
|
|
67
|
+
props: { title: string, kicker?: string, strength?: string, weakness?: string, opportunity?: string, threat?: string }
|
|
68
|
+
|
|
69
|
+
21. pest - PEST 分析页
|
|
70
|
+
props: { title: string, kicker?: string, political?: string, economic?: string, social?: string, technological?: string }
|
|
71
|
+
|
|
72
|
+
22. closing - 结尾号召/联系信息页
|
|
73
|
+
props: { kicker?: string, title: string, subtitle?: string, cta?: string, contact?: string, email?: string, link?: string }
|
|
74
|
+
`;
|
|
75
|
+
export function buildPrompt(context) {
|
|
76
|
+
const { input, pageCount = 8, theme = 'minimal', language = 'zh' } = context;
|
|
77
|
+
return `你是一个专业的演示文稿规划助手。请根据用户的需求,生成一份符合 lemonPPT 格式的 goal.json。
|
|
78
|
+
|
|
79
|
+
${ROLE_CATALOG}
|
|
80
|
+
|
|
81
|
+
输出要求:
|
|
82
|
+
- 必须是合法 JSON,不要包含 markdown 代码块标记或额外解释。
|
|
83
|
+
- 顶层字段:title, goal, audience, owner, theme, language, pageCount, randomSeed, slides。
|
|
84
|
+
- theme 固定为 "${theme}",language 固定为 "${language}",pageCount 为 ${pageCount}。
|
|
85
|
+
- slides 数组长度必须等于 pageCount。
|
|
86
|
+
- 每个 slide 必须包含 role(从上述角色中选择)和 props(对应角色的字段)。
|
|
87
|
+
- 不要输出 layout 字段;系统会自动根据 role 选择最合适的版式。
|
|
88
|
+
- 如果某些内容特别适合某款具体版式,可以额外提供 layout 字段,否则不要提供。
|
|
89
|
+
- 根据每页内容角色选择角色:封面用 cover,目录用 tableOfContents,数据/大数字用 metric/stats,图表用 chart,对比用 comparison,流程/时间线/路线用 process/timeline/roadmap,团队用 team,价格用 pricing,引用用 quote/testimonial,产品亮点/场景展示用 feature/content,FAQ 用 faq,合作伙伴墙用 partners,图片集用 gallery/image,分析用 swot/pest,结尾用 closing。
|
|
90
|
+
- 尽量多样化使用角色,避免连续多页使用同一个角色。
|
|
91
|
+
- 内容应围绕用户主题,自然、有逻辑,并符合 ${language === 'zh' ? '中文' : language} 表达习惯。
|
|
92
|
+
- 为需要图片的角色(cover、image、gallery、content、feature、team、partners、testimonial 等)提供高质量图片 URL,使用 https://images.unsplash.com/photo-<id>?w=1920&q=80 形式,id 应选用与主题相关、看起来真实存在的 Unsplash 图片编号,并确保图片风格与整体主题一致。
|
|
93
|
+
- chart 请提供真实、合理的 data 数组与 labels,labels 数量与 data 数量一致。
|
|
94
|
+
- 从第 2 页开始展开核心论点,最后一页使用 closing 角色做总结或行动号召。
|
|
95
|
+
- randomSeed 使用一个稳定的字符串,例如 "lemon-<日期>-<序号>"。
|
|
96
|
+
|
|
97
|
+
用户需求:
|
|
98
|
+
"""
|
|
99
|
+
${input}
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
请直接输出 goal.json:`;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoEpB,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,OAAsB;IAChD,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,EAAE,QAAQ,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAE7E,OAAO;;EAEP,YAAY;;;;;eAKC,KAAK,mBAAmB,QAAQ,iBAAiB,SAAS;;;;;;;yBAOhD,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ;;;;;;;;EAQ1D,KAAK;;;iBAGU,CAAC;AAClB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lemonppt/agent-prompts",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/lemonforme/lemonPPT.git",
|
|
22
|
+
"directory": "packages/agent-prompts"
|
|
23
|
+
},
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/lemonforme/lemonPPT/issues"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/lemonforme/lemonPPT#readme",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@lemonppt/core": "0.1.0",
|
|
30
|
+
"@lemonppt/composer": "0.1.0",
|
|
31
|
+
"@lemonppt/view-model": "0.1.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^20.0.0",
|
|
35
|
+
"typescript": "^5.5.0"
|
|
36
|
+
},
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "tsc",
|
|
40
|
+
"typecheck": "tsc --noEmit"
|
|
41
|
+
}
|
|
42
|
+
}
|