@anythingai/teleprompt 0.2.0 → 0.3.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/dist/index.cjs +132 -169
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -66
- package/dist/index.d.ts +9 -66
- package/dist/index.js +132 -169
- package/dist/index.js.map +1 -1
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +4 -23
- package/dist/testing.d.ts +4 -23
- package/dist/testing.js.map +1 -1
- package/dist/types-ow-XbrO7.d.cts +12 -0
- package/dist/types-ow-XbrO7.d.ts +12 -0
- package/llms.txt +183 -0
- package/package.json +19 -19
- package/dist/types--sRnfw6Q.d.cts +0 -34
- package/dist/types--sRnfw6Q.d.ts +0 -34
package/dist/testing.d.ts
CHANGED
|
@@ -1,26 +1,7 @@
|
|
|
1
|
-
import { P as PromptContext, a as PromptSection } from './types
|
|
1
|
+
import { P as PromptContext, a as PromptSection } from './types-ow-XbrO7.js';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```ts
|
|
9
|
-
* const ctx = mockContext({ flags: { myFlag: true } });
|
|
10
|
-
* const output = mySection.render(ctx);
|
|
11
|
-
* ```
|
|
12
|
-
*/
|
|
13
|
-
declare function mockContext<TFlags extends Record<string, boolean> = Record<string, boolean>, TVars extends Record<string, unknown> = Record<string, unknown>>(overrides?: Partial<PromptContext<TFlags, TVars>>): PromptContext<TFlags, TVars>;
|
|
14
|
-
/**
|
|
15
|
-
* Render a single section in isolation with a mock context.
|
|
16
|
-
* Respects the section's `when` guard — returns `null` if excluded.
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```ts
|
|
20
|
-
* const output = renderSection(mySection, { flags: { enabled: true } });
|
|
21
|
-
* expect(output).toContain('expected text');
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
declare function renderSection<TCtx extends PromptContext<Record<string, boolean>, Record<string, unknown>>>(section: PromptSection<TCtx>, contextOverrides?: Partial<TCtx>): string | null;
|
|
3
|
+
declare function mockContext<TFlags extends Record<string, boolean> = Record<string, boolean>, TVars extends object = Record<string, unknown>>(overrides?: Partial<PromptContext<TFlags, TVars>>): PromptContext<TFlags, TVars>;
|
|
4
|
+
/** Renders a section in isolation. Returns `null` if excluded by `when` guard. */
|
|
5
|
+
declare function renderSection<TCtx extends PromptContext>(section: PromptSection<TCtx>, contextOverrides?: Partial<TCtx>): string | null;
|
|
25
6
|
|
|
26
7
|
export { mockContext, renderSection };
|
package/dist/testing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/testing.ts"],"sourcesContent":["import type { PromptContext, PromptSection } from './types';\n\
|
|
1
|
+
{"version":3,"sources":["../src/testing.ts"],"sourcesContent":["import type { PromptContext, PromptSection } from './types';\n\nexport function mockContext<\n TFlags extends Record<string, boolean> = Record<string, boolean>,\n TVars extends object = Record<string, unknown>,\n>(overrides?: Partial<PromptContext<TFlags, TVars>>): PromptContext<TFlags, TVars> {\n return {\n flags: {} as TFlags,\n vars: {} as TVars,\n ...overrides,\n };\n}\n\n/** Renders a section in isolation. Returns `null` if excluded by `when` guard. */\nexport function renderSection<TCtx extends PromptContext>(\n section: PromptSection<TCtx>,\n contextOverrides?: Partial<TCtx>,\n): string | null {\n const ctx = mockContext(contextOverrides) as TCtx;\n if (section.when && !section.when(ctx)) {\n return null;\n }\n return section.render(ctx);\n}\n"],"mappings":";AAEO,SAAS,YAGd,WAAiF;AACjF,SAAO;AAAA,IACL,OAAO,CAAC;AAAA,IACR,MAAM,CAAC;AAAA,IACP,GAAG;AAAA,EACL;AACF;AAGO,SAAS,cACd,SACA,kBACe;AACf,QAAM,MAAM,YAAY,gBAAgB;AACxC,MAAI,QAAQ,QAAQ,CAAC,QAAQ,KAAK,GAAG,GAAG;AACtC,WAAO;AAAA,EACT;AACA,SAAO,QAAQ,OAAO,GAAG;AAC3B;","names":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface PromptContext<TFlags extends Record<string, boolean> = Record<string, boolean>, TVars extends object = Record<string, unknown>> {
|
|
2
|
+
flags: TFlags;
|
|
3
|
+
vars: TVars;
|
|
4
|
+
}
|
|
5
|
+
interface PromptSection<TCtx extends PromptContext = PromptContext> {
|
|
6
|
+
id: string;
|
|
7
|
+
/** Return `false` to exclude this section from the output. */
|
|
8
|
+
when?: (ctx: TCtx) => boolean;
|
|
9
|
+
render: (ctx: TCtx) => string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type { PromptContext as P, PromptSection as a };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface PromptContext<TFlags extends Record<string, boolean> = Record<string, boolean>, TVars extends object = Record<string, unknown>> {
|
|
2
|
+
flags: TFlags;
|
|
3
|
+
vars: TVars;
|
|
4
|
+
}
|
|
5
|
+
interface PromptSection<TCtx extends PromptContext = PromptContext> {
|
|
6
|
+
id: string;
|
|
7
|
+
/** Return `false` to exclude this section from the output. */
|
|
8
|
+
when?: (ctx: TCtx) => boolean;
|
|
9
|
+
render: (ctx: TCtx) => string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type { PromptContext as P, PromptSection as a };
|
package/llms.txt
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# teleprompt
|
|
2
|
+
|
|
3
|
+
Composable, section-based LLM system prompts. Published as `@anythingai/teleprompt`.
|
|
4
|
+
|
|
5
|
+
## Core Concepts
|
|
6
|
+
|
|
7
|
+
**Section** — a named unit of prompt content with an id and a render function. Return a string to include, `null` to exclude.
|
|
8
|
+
|
|
9
|
+
**PromptBuilder** — composes sections in order. Supports groups, mutual exclusion, forking, and removal.
|
|
10
|
+
|
|
11
|
+
**PromptContext** — typed object with `flags` (booleans) and `vars` (arbitrary data) passed to every section's render function.
|
|
12
|
+
|
|
13
|
+
## Idiomatic Usage
|
|
14
|
+
|
|
15
|
+
### Define a context type for your application
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { type PromptContext } from "@anythingai/teleprompt";
|
|
19
|
+
|
|
20
|
+
type Flags = { webSearchEnabled: boolean; verbose: boolean };
|
|
21
|
+
type Vars = { userName: string; tasks: Task[] };
|
|
22
|
+
type Ctx = PromptContext<Flags, Vars>;
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Create sections with the `section()` helper
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { section } from "@anythingai/teleprompt";
|
|
29
|
+
|
|
30
|
+
// Static — no context needed, works in any builder
|
|
31
|
+
const guidelines = section("guidelines", () => `Be concise and direct.`);
|
|
32
|
+
|
|
33
|
+
// Dynamic — reads from context
|
|
34
|
+
const identity = section("identity", (ctx: Ctx) =>
|
|
35
|
+
`You are ${ctx.vars.userName}'s assistant.`
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
// Conditional — return null to exclude
|
|
39
|
+
const webSearch = section("web-search", (ctx: Ctx) => {
|
|
40
|
+
if (!ctx.flags.webSearchEnabled) return null;
|
|
41
|
+
return "You have access to web search.";
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Compose with PromptBuilder
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { PromptBuilder } from "@anythingai/teleprompt";
|
|
49
|
+
|
|
50
|
+
const builder = new PromptBuilder<Ctx>()
|
|
51
|
+
.use(identity)
|
|
52
|
+
.use(guidelines)
|
|
53
|
+
.use(webSearch)
|
|
54
|
+
.group("tools", (b) => b.use(bashTool).use(gitTool))
|
|
55
|
+
.useOneOf(hasTasks, noTasks);
|
|
56
|
+
|
|
57
|
+
const prompt = builder.build(ctx);
|
|
58
|
+
const xmlPrompt = builder.build(ctx, { format: "xml" });
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Fork for variants
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
const base = new PromptBuilder<Ctx>().use(identity).use(guidelines).use(tone);
|
|
65
|
+
|
|
66
|
+
const supportAgent = base.fork().use(escalationPolicy);
|
|
67
|
+
const codeAgent = base.fork().without(tone).use(codingRules);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Patterns and Rationale
|
|
71
|
+
|
|
72
|
+
### Use null returns for conditional sections, not the `when` guard
|
|
73
|
+
|
|
74
|
+
The `section()` helper colocates the condition with the content it guards, making sections self-contained and easier to reason about. The `when` field exists on the raw PromptSection interface for programmatic use cases, but `section()` with null returns is the standard path because it keeps each section's logic in one place.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
// Preferred — condition and content together
|
|
78
|
+
const verbose = section("verbose", (ctx: Ctx) => {
|
|
79
|
+
if (!ctx.flags.verbose) return null;
|
|
80
|
+
return "Show detailed explanations.";
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Avoid — splits the condition from the content it controls
|
|
84
|
+
const verbose: PromptSection<Ctx> = {
|
|
85
|
+
id: "verbose",
|
|
86
|
+
when: (ctx) => ctx.flags.verbose,
|
|
87
|
+
render: () => "Show detailed explanations.",
|
|
88
|
+
};
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Keep sections small and focused
|
|
92
|
+
|
|
93
|
+
Each section should own one concern. This makes sections independently reusable across builder variants (via `fork`, `without`, `use`) and gives `buildWithMeta` meaningful granularity — you can see exactly which capabilities were included or excluded. A monolithic section that concatenates everything defeats both of these.
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
// Preferred — each concern is a composable unit
|
|
97
|
+
const identity = section("identity", (ctx: Ctx) => `You are ${ctx.vars.userName}'s assistant.`);
|
|
98
|
+
const guidelines = section("guidelines", () => "# Guidelines\n- Be concise.");
|
|
99
|
+
const webSearch = section("web-search", (ctx: Ctx) => {
|
|
100
|
+
if (!ctx.flags.webSearchEnabled) return null;
|
|
101
|
+
return "You can search the web.";
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Return null rather than empty string for absent content
|
|
106
|
+
|
|
107
|
+
Returning `null` from `section()` signals intentional exclusion — the section is tracked as "excluded" in `buildWithMeta`, which is useful for debugging and observability. An empty string is ambiguous (is it a bug or intentional?) and still occupies a slot in the output.
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
// Preferred — null signals intentional absence, tracked in metadata
|
|
111
|
+
const tools = section("tools", (ctx: Ctx) => {
|
|
112
|
+
if (!ctx.flags.webSearchEnabled) return null;
|
|
113
|
+
return "You can search the web.";
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// Avoid — empty string is ambiguous and not tracked as excluded
|
|
117
|
+
const tools = section("tools", (ctx: Ctx) =>
|
|
118
|
+
ctx.flags.webSearchEnabled ? "You can search the web." : ""
|
|
119
|
+
);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Let the builder handle composition
|
|
123
|
+
|
|
124
|
+
The builder manages section ordering, format wrapping (text vs XML), joining, and metadata tracking. Calling `render` directly on sections bypasses all of this — you lose format support, metadata, and the ability to fork or modify the composition.
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
// Preferred — builder handles joining, format, and metadata
|
|
128
|
+
const prompt = new PromptBuilder<Ctx>().use(identity).use(guidelines).build(ctx);
|
|
129
|
+
|
|
130
|
+
// Avoid — bypasses composition, forking, and metadata tracking
|
|
131
|
+
const prompt = identity.render(ctx) + "\n\n" + guidelines.render(ctx);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## API Reference
|
|
135
|
+
|
|
136
|
+
### `section(id, render)`
|
|
137
|
+
|
|
138
|
+
Creates a PromptSection. `render` receives context, returns `string | null`.
|
|
139
|
+
|
|
140
|
+
### `PromptBuilder<TCtx>`
|
|
141
|
+
|
|
142
|
+
- `.use(section)` — append or replace by id
|
|
143
|
+
- `.useOneOf(...sections)` — first non-empty render wins
|
|
144
|
+
- `.group(id, configure)` — named group (XML wrapper in xml format, transparent in text)
|
|
145
|
+
- `.without(id | section)` — remove by id, searches recursively
|
|
146
|
+
- `.has(id | section)` — check existence
|
|
147
|
+
- `.ids()` — list all section ids
|
|
148
|
+
- `.fork()` — independent deep copy
|
|
149
|
+
- `.build(ctx)` — render to string (text format)
|
|
150
|
+
- `.build(ctx, { format: "xml" })` — render with XML tags
|
|
151
|
+
- `.buildWithMeta(ctx)` — returns `{ prompt, included, excluded }`
|
|
152
|
+
|
|
153
|
+
### `PromptContext<TFlags, TVars>`
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
interface PromptContext<
|
|
157
|
+
TFlags extends Record<string, boolean>,
|
|
158
|
+
TVars extends object,
|
|
159
|
+
> {
|
|
160
|
+
flags: TFlags;
|
|
161
|
+
vars: TVars;
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Both type parameters default to open records, so `new PromptBuilder()` works without a type argument for simple cases.
|
|
166
|
+
|
|
167
|
+
## Testing
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
import { mockContext, renderSection } from "@anythingai/teleprompt/testing";
|
|
171
|
+
|
|
172
|
+
// Render a single section in isolation
|
|
173
|
+
const output = renderSection(webSearch, { flags: { webSearchEnabled: true } });
|
|
174
|
+
|
|
175
|
+
// Assert on builder metadata
|
|
176
|
+
const { included, excluded } = builder.buildWithMeta(ctx);
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Output Formats
|
|
180
|
+
|
|
181
|
+
**text** (default) — sections joined with `\n\n`, groups are transparent.
|
|
182
|
+
|
|
183
|
+
**xml** — each section wrapped in `<id>...</id>`, groups wrap children in `<id>...</id>`. Recommended for Claude and Gemini which handle XML-structured prompts well.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anythingai/teleprompt",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Composable, declarative prompt builder for LLM system prompts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -29,19 +29,12 @@
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
|
-
"files": [
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
"typecheck": "tsc --noEmit",
|
|
39
|
-
"test": "vitest run",
|
|
40
|
-
"test:watch": "vitest",
|
|
41
|
-
"publint": "publint",
|
|
42
|
-
"attw": "attw --pack . --profile node16",
|
|
43
|
-
"prepublishOnly": "pnpm check && pnpm build"
|
|
44
|
-
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE",
|
|
36
|
+
"llms.txt"
|
|
37
|
+
],
|
|
45
38
|
"keywords": [
|
|
46
39
|
"prompt",
|
|
47
40
|
"llm",
|
|
@@ -56,13 +49,9 @@
|
|
|
56
49
|
"type": "git",
|
|
57
50
|
"url": "https://github.com/Create-Inc/teleprompt.git"
|
|
58
51
|
},
|
|
59
|
-
"packageManager": "pnpm@10.30.0+sha512.2b5753de015d480eeb88f5b5b61e0051f05b4301808a82ec8b840c9d2adf7748eb352c83f5c1593ca703ff1017295bc3fdd3119abb9686efc96b9fcb18200937",
|
|
60
52
|
"engines": {
|
|
61
53
|
"node": ">=20"
|
|
62
54
|
},
|
|
63
|
-
"pnpm": {
|
|
64
|
-
"onlyBuiltDependencies": ["@biomejs/biome", "esbuild"]
|
|
65
|
-
},
|
|
66
55
|
"devDependencies": {
|
|
67
56
|
"@arethetypeswrong/cli": "^0.17.0",
|
|
68
57
|
"@biomejs/biome": "^1.9.0",
|
|
@@ -71,5 +60,16 @@
|
|
|
71
60
|
"tsx": "^4.21.0",
|
|
72
61
|
"typescript": "^5.7.0",
|
|
73
62
|
"vitest": "^3.0.0"
|
|
63
|
+
},
|
|
64
|
+
"scripts": {
|
|
65
|
+
"build": "tsup",
|
|
66
|
+
"check": "pnpm lint && pnpm typecheck && pnpm test && pnpm publint && pnpm attw",
|
|
67
|
+
"lint": "biome check .",
|
|
68
|
+
"lint:fix": "biome check --write .",
|
|
69
|
+
"typecheck": "tsc --noEmit",
|
|
70
|
+
"test": "vitest run",
|
|
71
|
+
"test:watch": "vitest",
|
|
72
|
+
"publint": "publint",
|
|
73
|
+
"attw": "attw --pack . --profile node16"
|
|
74
74
|
}
|
|
75
|
-
}
|
|
75
|
+
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The context passed to every section's `when` and `render` functions.
|
|
3
|
-
*
|
|
4
|
-
* @typeParam TFlags - Shape of the boolean flags object
|
|
5
|
-
* @typeParam TVars - Shape of the runtime variables object
|
|
6
|
-
*/
|
|
7
|
-
interface PromptContext<TFlags extends Record<string, boolean> = Record<string, boolean>, TVars extends Record<string, unknown> = Record<string, unknown>> {
|
|
8
|
-
/** Boolean flags that control which sections are included and how they render */
|
|
9
|
-
flags: TFlags;
|
|
10
|
-
/** Runtime data sections can read from (model, mode, integrations, etc.) */
|
|
11
|
-
vars: TVars;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* A single composable unit of prompt content.
|
|
15
|
-
*
|
|
16
|
-
* @typeParam TCtx - The prompt context type this section operates on
|
|
17
|
-
*/
|
|
18
|
-
interface PromptSection<TCtx extends PromptContext = PromptContext> {
|
|
19
|
-
/** Unique identifier. Used by `use()`, `without()`, and `buildWithMeta()`. */
|
|
20
|
-
id: string;
|
|
21
|
-
/**
|
|
22
|
-
* Guard function. Return `false` to exclude this section from the output.
|
|
23
|
-
* If omitted, the section is always included.
|
|
24
|
-
*/
|
|
25
|
-
when?: (ctx: TCtx) => boolean;
|
|
26
|
-
/**
|
|
27
|
-
* Render the section content. Receives the full prompt context.
|
|
28
|
-
* Return an empty string to include nothing (different from `when: false`
|
|
29
|
-
* which removes the section entirely including any separator).
|
|
30
|
-
*/
|
|
31
|
-
render: (ctx: TCtx) => string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export type { PromptContext as P, PromptSection as a };
|
package/dist/types--sRnfw6Q.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The context passed to every section's `when` and `render` functions.
|
|
3
|
-
*
|
|
4
|
-
* @typeParam TFlags - Shape of the boolean flags object
|
|
5
|
-
* @typeParam TVars - Shape of the runtime variables object
|
|
6
|
-
*/
|
|
7
|
-
interface PromptContext<TFlags extends Record<string, boolean> = Record<string, boolean>, TVars extends Record<string, unknown> = Record<string, unknown>> {
|
|
8
|
-
/** Boolean flags that control which sections are included and how they render */
|
|
9
|
-
flags: TFlags;
|
|
10
|
-
/** Runtime data sections can read from (model, mode, integrations, etc.) */
|
|
11
|
-
vars: TVars;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* A single composable unit of prompt content.
|
|
15
|
-
*
|
|
16
|
-
* @typeParam TCtx - The prompt context type this section operates on
|
|
17
|
-
*/
|
|
18
|
-
interface PromptSection<TCtx extends PromptContext = PromptContext> {
|
|
19
|
-
/** Unique identifier. Used by `use()`, `without()`, and `buildWithMeta()`. */
|
|
20
|
-
id: string;
|
|
21
|
-
/**
|
|
22
|
-
* Guard function. Return `false` to exclude this section from the output.
|
|
23
|
-
* If omitted, the section is always included.
|
|
24
|
-
*/
|
|
25
|
-
when?: (ctx: TCtx) => boolean;
|
|
26
|
-
/**
|
|
27
|
-
* Render the section content. Receives the full prompt context.
|
|
28
|
-
* Return an empty string to include nothing (different from `when: false`
|
|
29
|
-
* which removes the section entirely including any separator).
|
|
30
|
-
*/
|
|
31
|
-
render: (ctx: TCtx) => string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export type { PromptContext as P, PromptSection as a };
|