Skip to content

Commit b98d36d

Browse files
authored
0.7.1 - allow undefined parameters (#32)
1 parent c0c0be8 commit b98d36d

File tree

6 files changed

+47
-106
lines changed

6 files changed

+47
-106
lines changed

src/compiler/base/nodes/for.test.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import CompileError from '$promptl/error/error'
2-
import { getExpectedError } from '$promptl/test/helpers'
31
import { Message, MessageContent, TextContent } from '$promptl/types'
42
import { describe, expect, it } from 'vitest'
53

@@ -71,12 +69,11 @@ describe('each loops', async () => {
7169
const prompt1 = `{{ for elemenet in ['a', 'b', 'c'] }} {{foo = 5}} {{ endfor }} {{foo}}`
7270
const prompt2 = `{{foo = 5}} {{ for element in ['a', 'b', 'c'] }} {{foo = 7}} {{ endfor }} {{foo}}`
7371
const prompt3 = `{{foo = 5}} {{ for element in [1, 2, 3] }} {{foo += element}} {{ endfor }} {{foo}}`
74-
const action1 = () => render({ prompt: prompt1, parameters: {} })
75-
const error1 = await getExpectedError(action1, CompileError)
72+
const result1 = await getCompiledText(prompt1)
7673
const result2 = await getCompiledText(prompt2)
7774
const result3 = await getCompiledText(prompt3)
7875

79-
expect(error1.code).toBe('variable-not-declared')
76+
expect(result1).toBe('')
8077
expect(result2).toBe('7')
8178
expect(result3).toBe('11')
8279
})

src/compiler/base/nodes/tags/ref.test.ts

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ describe('ref tags', async () => {
5656
child: 'child message',
5757
}
5858

59-
const action = () => render({ prompt: prompts['parent'], adapter: Adapters.default })
59+
const action = () =>
60+
render({ prompt: prompts['parent'], adapter: Adapters.default })
6061
const error = await getExpectedError(action, CompileError)
6162
expect(error.code).toBe('missing-reference-function')
6263
})
@@ -83,16 +84,19 @@ describe('ref tags', async () => {
8384
parent: '<prompt path="child" />',
8485
}
8586

86-
const action = () =>
87-
render({
88-
prompt: prompts['parent'],
89-
parameters: { foo: 'bar' },
90-
referenceFn: buildReferenceFn(prompts),
91-
adapter: Adapters.default,
92-
})
93-
94-
const error = await getExpectedError(action, CompileError)
95-
expect(error.code).toBe('variable-not-declared')
87+
const result = await render({
88+
prompt: prompts['parent'],
89+
referenceFn: buildReferenceFn(prompts),
90+
adapter: Adapters.default,
91+
})
92+
expect(result.messages.length).toBe(1)
93+
const message = result.messages[0]! as SystemMessage
94+
expect(message.content).toEqual([
95+
{
96+
type: 'text',
97+
text: 'Child message:',
98+
},
99+
])
96100
})
97101

98102
it('referenced prompts can receive parameters as tag attributes', async () => {
@@ -336,12 +340,12 @@ describe('ref tags', async () => {
336340
{{ bar }}
337341
</content-text>
338342
{{ endfor }}
339-
`)
343+
`),
340344
}
341345

342346
const metadata = await scan({
343347
prompt: prompts['parent'],
344-
referenceFn: buildReferenceFn(prompts)
348+
referenceFn: buildReferenceFn(prompts),
345349
})
346350

347351
const result = await render({
@@ -351,18 +355,19 @@ describe('ref tags', async () => {
351355
})
352356

353357
expect(result.messages.length).toBe(2)
354-
const [ firstMessage, secondMessage ] = result.messages as [UserMessage, SystemMessage]
358+
const [firstMessage, secondMessage] = result.messages as [
359+
UserMessage,
360+
SystemMessage,
361+
]
355362
expect(firstMessage.role).toBe(MessageRole.user)
356363
expect(firstMessage.content.length).toBe(3)
357364
expect(firstMessage.content).toEqual([
358-
{ type: 'text', text: '11'},
359-
{ type: 'text', text: '12'},
360-
{ type: 'text', text: '13'},
365+
{ type: 'text', text: '11' },
366+
{ type: 'text', text: '12' },
367+
{ type: 'text', text: '13' },
361368
])
362369
expect(secondMessage.role).toBe(MessageRole.system)
363370
expect(secondMessage.content.length).toBe(1)
364-
expect(secondMessage.content).toEqual([
365-
{ type: 'text', text: '10' }
366-
])
371+
expect(secondMessage.content).toEqual([{ type: 'text', text: '10' }])
367372
})
368373
})

src/compiler/base/nodes/tags/scope.test.ts

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
import { Adapters, Chain, render } from '$promptl/index'
22
import { complete } from '$promptl/compiler/test/helpers'
33
import { removeCommonIndent } from '$promptl/compiler/utils'
4-
import CompileError from '$promptl/error/error'
5-
import { getExpectedError } from '$promptl/test/helpers'
6-
import {
7-
MessageRole,
8-
SystemMessage,
9-
UserMessage,
10-
} from '$promptl/types'
4+
import { MessageRole, SystemMessage, UserMessage } from '$promptl/types'
115
import { describe, expect, it, vi } from 'vitest'
126

137
describe('scope tags', async () => {
@@ -48,7 +42,7 @@ describe('scope tags', async () => {
4842
`)
4943

5044
const result = await render({ prompt, adapter: Adapters.default })
51-
45+
5246
expect(result.messages.length).toBe(1)
5347
const message = result.messages[0]! as SystemMessage
5448
expect(message.content).toEqual([
@@ -67,18 +61,19 @@ describe('scope tags', async () => {
6761
const prompt = removeCommonIndent(`
6862
{{ foo = 'bar' }}
6963
<scope>
70-
{{ foo }}
64+
{{ foo == 'bar' }}
7165
</scope>
7266
`)
7367

74-
const action = () => render({
75-
prompt,
76-
parameters: { foo: 'baz' },
77-
adapter: Adapters.default
78-
})
79-
80-
const error = await getExpectedError(action, CompileError)
81-
expect(error.code).toBe('variable-not-declared')
68+
const result = await render({ prompt, adapter: Adapters.default })
69+
expect(result.messages.length).toBe(1)
70+
const message = result.messages[0]! as SystemMessage
71+
expect(message.content).toEqual([
72+
{
73+
type: 'text',
74+
text: 'false',
75+
},
76+
])
8277
})
8378

8479
it('can inherit parameters from parents if explicitly passed', async () => {
@@ -91,7 +86,7 @@ describe('scope tags', async () => {
9186
const result = await render({
9287
prompt,
9388
parameters: { foo: 'bar' },
94-
adapter: Adapters.default
89+
adapter: Adapters.default,
9590
})
9691

9792
expect(result.messages.length).toBe(1)

src/compiler/chain.test.ts

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -343,19 +343,6 @@ describe('chain', async () => {
343343
{{foo}}
344344
`)
345345

346-
const incorrectPrompt = removeCommonIndent(`
347-
{{foo = 5}}
348-
349-
{{if true}}
350-
{{bar = 1}}
351-
<step>
352-
{{ bar++}}
353-
</step>
354-
{{endif}}
355-
356-
{{bar}}
357-
`)
358-
359346
const correctChain = new Chain({
360347
prompt: correctPrompt,
361348
adapter: Adapters.default,
@@ -371,16 +358,6 @@ describe('chain', async () => {
371358
},
372359
],
373360
})
374-
375-
const incorrectChain = new Chain({
376-
prompt: incorrectPrompt,
377-
parameters: {},
378-
adapter: Adapters.default,
379-
})
380-
381-
const action = () => complete({ chain: incorrectChain })
382-
const error = await getExpectedError(action, CompileError)
383-
expect(error.code).toBe('variable-not-declared')
384361
})
385362

386363
it('maintains the scope in for loops', async () => {
@@ -419,23 +396,6 @@ describe('chain', async () => {
419396
})
420397
})
421398

422-
it('cannot access variables created in a loop outside its scope', async () => {
423-
const prompt = removeCommonIndent(`
424-
{{for i in [1, 2, 3]}}
425-
{{foo = i}}
426-
<step />
427-
{{endfor}}
428-
429-
{{foo}}
430-
`)
431-
432-
const chain = new Chain({ prompt, adapter: Adapters.default })
433-
434-
const action = () => complete({ chain })
435-
const error = await getExpectedError(action, CompileError)
436-
expect(error.code).toBe('variable-not-declared')
437-
})
438-
439399
it('maintains the scope in nested loops', async () => {
440400
const prompt = removeCommonIndent(`
441401
{{ foo = 0 }}

src/compiler/compile.test.ts

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -173,18 +173,12 @@ describe('variable assignment', async () => {
173173
expect(result).toBe('5')
174174
})
175175

176-
it('cannot reference undefined variables', async () => {
176+
it('undefined variables do not cause an error', async () => {
177177
const prompt = `
178178
{{ foo }}
179179
`
180-
const action = () =>
181-
render({
182-
prompt: removeCommonIndent(prompt),
183-
parameters: {},
184-
adapter: Adapters.default,
185-
})
186-
const error = await getExpectedError(action, CompileError)
187-
expect(error.code).toBe('variable-not-declared')
180+
const result = await getCompiledText(prompt)
181+
expect(result).toBe('')
188182
})
189183

190184
it('parameters are available as variables in the prompt', async () => {
@@ -227,14 +221,8 @@ describe('variable assignment', async () => {
227221
{{ endif }}
228222
{{ foo }}
229223
`
230-
const action = () =>
231-
render({
232-
prompt: removeCommonIndent(prompt),
233-
parameters: {},
234-
adapter: Adapters.default,
235-
})
236-
const error = await getExpectedError(action, CompileError)
237-
expect(error.code).toBe('variable-not-declared')
224+
const result = await getCompiledText(prompt)
225+
expect(result).toBe('')
238226
})
239227

240228
it('variables can be modified from an inner scope', async () => {

src/compiler/logic/nodes/identifier.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,9 @@ import type { Identifier } from 'estree'
99
* ### Identifier
1010
* Represents a variable from the scope.
1111
*/
12-
export async function resolve({
13-
node,
14-
scope,
15-
raiseError,
16-
}: ResolveNodeProps<Identifier>) {
12+
export async function resolve({ node, scope }: ResolveNodeProps<Identifier>) {
1713
if (!scope.exists(node.name)) {
18-
raiseError(errors.variableNotDeclared(node.name), node)
14+
return undefined
1915
}
2016
return scope.get(node.name)
2117
}

0 commit comments

Comments
 (0)