@nudge-ai/core 0.0.1-beta.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,247 @@
1
+
2
+ //#region src/create-step.ts
3
+ /**
4
+ * Creates a step definition that can be used to extend a builder.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * const tone = createStep({
9
+ * name: 'tone',
10
+ * build: (style: string) => ({ type: 'tone', style }),
11
+ * format: (step) => `[Tone] Write in a ${step.style} tone`,
12
+ * });
13
+ * ```
14
+ */
15
+ function createStep(definition) {
16
+ return definition;
17
+ }
18
+
19
+ //#endregion
20
+ //#region src/base-steps.ts
21
+ function formatNudge(nudge$1) {
22
+ if (!nudge$1 || nudge$1 === 3) return "";
23
+ return `\nNudge: ${nudge$1}`;
24
+ }
25
+ const raw = createStep({
26
+ name: "raw",
27
+ build: (value) => ({
28
+ type: "raw",
29
+ value
30
+ }),
31
+ format: (step) => `[Raw Text] (Include this text verbatim in the system prompt.)\nValue: "${step.value}"`
32
+ });
33
+ const persona = createStep({
34
+ name: "persona",
35
+ build: (role) => ({
36
+ type: "persona",
37
+ role
38
+ }),
39
+ format: (step) => `[Persona] (Define the identity and role the AI should assume. Frame this as 'You are...' at the start of the system prompt.)\nValue: "${step.role}"`
40
+ });
41
+ const input = createStep({
42
+ name: "input",
43
+ build: (description) => ({
44
+ type: "input",
45
+ description
46
+ }),
47
+ format: (step) => `[Input] (Describe what input the AI will receive from the user. Help the AI understand the context of what it will be working with.)\nValue: "${step.description}"`
48
+ });
49
+ const output = createStep({
50
+ name: "output",
51
+ build: (description) => ({
52
+ type: "output",
53
+ description
54
+ }),
55
+ format: (step) => `[Output] (Specify what the AI should produce as output. Be clear about the expected format and content.)\nValue: "${step.description}"`
56
+ });
57
+ const context = createStep({
58
+ name: "context",
59
+ build: (information) => ({
60
+ type: "context",
61
+ information
62
+ }),
63
+ format: (step) => `[Context] (Background information or context that helps the AI understand the situation. This is not an instruction, just helpful information.)\nValue: "${step.information}"`
64
+ });
65
+ const doStep = createStep({
66
+ name: "do",
67
+ build: (instruction, options) => ({
68
+ type: "do",
69
+ instruction,
70
+ nudge: options?.nudge
71
+ }),
72
+ format: (step) => `[Do] (A positive instruction the AI must follow.)\nValue: "${step.instruction}"${formatNudge(step.nudge)}`
73
+ });
74
+ const dont = createStep({
75
+ name: "dont",
76
+ build: (instruction, options) => ({
77
+ type: "dont",
78
+ instruction,
79
+ nudge: options?.nudge
80
+ }),
81
+ format: (step) => `[Don't] (A negative instruction - something the AI must avoid.)\nValue: "${step.instruction}"${formatNudge(step.nudge)}`
82
+ });
83
+ const constraint = createStep({
84
+ name: "constraint",
85
+ build: (rule, options) => ({
86
+ type: "constraint",
87
+ rule,
88
+ nudge: options?.nudge
89
+ }),
90
+ format: (step) => `[Constraint] (A rule or limitation the AI must respect.)\nValue: "${step.rule}"${formatNudge(step.nudge)}`
91
+ });
92
+ const example = createStep({
93
+ name: "example",
94
+ build: (inputText, outputText) => ({
95
+ type: "example",
96
+ input: inputText,
97
+ output: outputText
98
+ }),
99
+ format: (step) => `[Example] (An input/output example showing the AI how to respond. Use these to demonstrate the expected behavior.)\nInput: "${step.input}"\nExpected output: "${step.output}"`
100
+ });
101
+ const baseSteps = [
102
+ raw,
103
+ persona,
104
+ input,
105
+ output,
106
+ context,
107
+ doStep,
108
+ dont,
109
+ constraint,
110
+ example
111
+ ];
112
+
113
+ //#endregion
114
+ //#region src/nudge.ts
115
+ let promptCache = {};
116
+ function registerPrompts(prompts) {
117
+ promptCache = {
118
+ ...promptCache,
119
+ ...prompts
120
+ };
121
+ }
122
+ function processTemplate(text, options = {}) {
123
+ const processOptionals = (str) => str.replace(/\{\{#(\w+)\}\}([\s\S]*?)\{\{\/\1\}\}/g, (_, name, content) => options[name] ? processOptionals(content) : "");
124
+ const processVars = (str) => str.replace(/\{\{(?![#\/])(\w+)\}\}/g, (match, name) => {
125
+ const value = options[name];
126
+ return typeof value === "string" ? value : match;
127
+ });
128
+ return processVars(processOptionals(text)).replace(/\n{3,}/g, "\n\n");
129
+ }
130
+ const baseStepDefinitions = /* @__PURE__ */ new Map();
131
+ for (const def of baseSteps) baseStepDefinitions.set(def.name, def);
132
+ /** Format a step for AI consumption using the base step definitions. */
133
+ function formatStepForAI(step) {
134
+ if (step.type === "optional") {
135
+ const opt = step;
136
+ const inner = opt.steps.map(formatStepForAI).join("\n\n");
137
+ return `[Optional Block Start: "${opt.name}"] (The following instructions are OPTIONAL. Wrap the generated content for these in {{#${opt.name}}}...{{/${opt.name}}} markers so it can be toggled at runtime.)\n\n${inner}\n\n[Optional Block End: "${opt.name}"]`;
138
+ }
139
+ const def = baseStepDefinitions.get(step.type);
140
+ if (!def) return `[Unknown Step: ${step.type}]`;
141
+ return def.format(step);
142
+ }
143
+ function createBuilder(customSteps = [], options = {}) {
144
+ const { omitBaseSteps = false } = options;
145
+ const allDefs = omitBaseSteps ? customSteps : [...baseSteps, ...customSteps];
146
+ const definitions = /* @__PURE__ */ new Map();
147
+ for (const def of allDefs) definitions.set(def.name, def);
148
+ function createPromptBuilder(state) {
149
+ const builder = {};
150
+ for (const [name, def] of definitions) builder[name] = (...args) => {
151
+ state.steps.push(def.build(...args));
152
+ return builder;
153
+ };
154
+ builder.use = (source) => {
155
+ state.steps.push(...source._state.steps);
156
+ return builder;
157
+ };
158
+ builder.optional = (name, builderFn) => {
159
+ const innerState = { steps: [] };
160
+ builderFn(createPromptBuilder(innerState));
161
+ state.steps.push({
162
+ type: "optional",
163
+ name,
164
+ steps: innerState.steps
165
+ });
166
+ return builder;
167
+ };
168
+ builder.variant = (name, builderFn) => {
169
+ const innerState = { steps: [] };
170
+ builderFn(createPromptBuilder(innerState));
171
+ if (!state.variants) state.variants = [];
172
+ state.variants.push({
173
+ name,
174
+ steps: innerState.steps
175
+ });
176
+ return builder;
177
+ };
178
+ builder.test = (input$1, assert, description) => {
179
+ if (!state.tests) state.tests = [];
180
+ state.tests.push({
181
+ input: input$1,
182
+ assert,
183
+ description
184
+ });
185
+ return builder;
186
+ };
187
+ return builder;
188
+ }
189
+ function formatStep(step) {
190
+ if (step.type === "optional") {
191
+ const opt = step;
192
+ const inner = opt.steps.map(formatStep).join("\n\n");
193
+ return `[Optional Block Start: "${opt.name}"] (The following instructions are OPTIONAL. Wrap the generated content for these in {{#${opt.name}}}...{{/${opt.name}}} markers so it can be toggled at runtime.)\n\n${inner}\n\n[Optional Block End: "${opt.name}"]`;
194
+ }
195
+ const def = definitions.get(step.type);
196
+ if (!def) return `[Unknown Step: ${step.type}]`;
197
+ return def.format(step);
198
+ }
199
+ return { prompt: (id, builderFn) => {
200
+ const state = { steps: [] };
201
+ builderFn(createPromptBuilder(state));
202
+ return {
203
+ id,
204
+ _state: state,
205
+ variantNames: state.variants?.map((v) => v.name) ?? [],
206
+ toString: ((options$1) => {
207
+ const cached = promptCache[id];
208
+ if (!cached) return "";
209
+ const variantName = options$1?.variant ?? "default";
210
+ return processTemplate(cached.variants[variantName] ?? cached.variants["default"] ?? "", options$1).trim();
211
+ })
212
+ };
213
+ } };
214
+ }
215
+ const nudge = createBuilder(baseSteps, { omitBaseSteps: true });
216
+
217
+ //#endregion
218
+ Object.defineProperty(exports, 'createBuilder', {
219
+ enumerable: true,
220
+ get: function () {
221
+ return createBuilder;
222
+ }
223
+ });
224
+ Object.defineProperty(exports, 'createStep', {
225
+ enumerable: true,
226
+ get: function () {
227
+ return createStep;
228
+ }
229
+ });
230
+ Object.defineProperty(exports, 'formatStepForAI', {
231
+ enumerable: true,
232
+ get: function () {
233
+ return formatStepForAI;
234
+ }
235
+ });
236
+ Object.defineProperty(exports, 'nudge', {
237
+ enumerable: true,
238
+ get: function () {
239
+ return nudge;
240
+ }
241
+ });
242
+ Object.defineProperty(exports, 'registerPrompts', {
243
+ enumerable: true,
244
+ get: function () {
245
+ return registerPrompts;
246
+ }
247
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nudge-ai/core",
3
- "version": "0.0.1-beta.1",
3
+ "version": "0.1.0",
4
4
  "description": "Core library for Nudge - type-safe prompt builder for AI applications",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -38,6 +38,10 @@
38
38
  "require": "./dist/index.cjs",
39
39
  "import": "./dist/index.mjs"
40
40
  },
41
+ "./internal": {
42
+ "require": "./dist/internal.cjs",
43
+ "import": "./dist/internal.mjs"
44
+ },
41
45
  "./package.json": "./package.json"
42
46
  },
43
47
  "publishConfig": {