Skip to content

Commit 8667fdf

Browse files
authored
support package:module (#1372)
1 parent d1f5460 commit 8667fdf

8 files changed

Lines changed: 47 additions & 4 deletions

File tree

.github/workflows/build.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,5 @@ jobs:
3636
run: yarn test:core
3737
- name: unit tests
3838
run: yarn test:samples
39+
- name: unit tests (2)
40+
run: yarn test:modulesamples

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"debug:mcp": "npx --yes @modelcontextprotocol/inspector node packages/cli/built/genaiscript.cjs mcp --groups mcp --cwd packages/sample",
4242
"test:core": "cd packages/core && yarn test",
4343
"test:samples": "cd packages/sample && yarn test",
44+
"test:modulesamples": "cd packages/modulesample && yarn test",
4445
"test:cli": "node packages/cli/built/genaiscript.cjs run code-annotator packages/sample/src/counting.py -l Test -o .genaiscript/tmp/tests/cli -ot .genaiscript/tmp/tests/cli/outtrace.md -oa .genaiscript/tmp/tests/cli/diags.sarif",
4546
"test:live": "node packages/cli/built/genaiscript.cjs run code-annotator packages/sample/src/counting.py -l Test -o .genaiscript/tmp/tests/cli --retry 1 --temperature 0.5 ",
4647
"test:front-matter": "node packages/cli/built/genaiscript.cjs run front-matter SUPPORT.md ",
@@ -56,6 +57,7 @@
5657
"test:fix": "node packages/cli/built/genaiscript.cjs scripts fix",
5758
"test:infomodel": "node packages/cli/built/genaiscript.cjs scripts model",
5859
"test:phi3": "node packages/cli/built/genaiscript.cjs run summarize-ollama-phi3 packages/sample/src/rag/markdown.md",
60+
"genai:module": "cd packages/modulesample && node ../cli/built/genaiscript.cjs run",
5961
"run:script": "cd packages/sample/ && yarn run:script",
6062
"run:script:debug": "yarn compile-debug && cd packages/sample/ && yarn run:script",
6163
"cache:clear": "cd packages/sample/ && yarn cache:clear",

packages/core/src/evalprompt.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import debug from "debug"
2+
const dbg = debug("genaiscript:evalprompt")
3+
14
import { host } from "./host"
25
import MagicString from "magic-string"
36

@@ -21,9 +24,11 @@ export async function evalPrompt(
2124
let src: string = [prefix, jsSource, suffix].join("")
2225
// source map
2326
if (r.filename && sourceMaps) {
27+
dbg("creating source map")
2428
const s = new MagicString(jsSource)
2529
s.prepend(prefix)
2630
s.append(suffix)
31+
dbg(`resolving path for ${r.filename}`)
2732
const source = host.path.resolve(r.filename)
2833
const map = s.generateMap({
2934
source,
@@ -33,11 +38,13 @@ export async function evalPrompt(
3338
const mapURL: string = map.toUrl()
3439
// split keywords as so that JS engine does not try to load "mapUrl"
3540
src += "\n//# source" + "MappingURL=" + mapURL
41+
dbg("appending sourceURL to source")
3642
src += "\n//# source" + "URL=" + source
3743
}
3844

3945
// in principle we could cache this function (but would have to do that based on hashed body or sth)
4046
// but probably little point
4147
const fn = (0, eval)(src)
48+
dbg(`eval ${r.filename}`)
4249
return await fn(...Object.values(ctx))
4350
}

packages/core/src/expander.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { normalizeFloat, normalizeInt } from "./cleaners"
2929
import { mergeEnvVarsWithSystem } from "./vars"
3030
import { installGlobalPromptContext } from "./globals"
3131
import { mark } from "./performance"
32+
import { tryReadJSON } from "./fs"
3233

3334
export async function callExpander(
3435
prj: Project,
@@ -62,10 +63,14 @@ export async function callExpander(
6263
logs += msg + "\n"
6364
}
6465

66+
// package.json { type: "module" }
67+
const pkg = await tryReadJSON("package.json")
68+
const isModule = pkg?.type === "module"
69+
dbg(`package.json type: ${pkg?.type || ""}`)
6570
try {
6671
if (
6772
r.filename &&
68-
!JS_REGEX.test(r.filename) &&
73+
(isModule || !JS_REGEX.test(r.filename)) &&
6974
!PROMPTY_REGEX.test(r.filename)
7075
)
7176
await importPrompt(ctx, r, { logCb, trace })

packages/core/src/importprompt.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import debug from "debug"
2+
const dbg = debug("genaiscript:importprompt")
3+
14
import { host } from "./host"
25
import { logError } from "./util"
36
import { TraceOptions } from "./trace"
@@ -12,10 +15,13 @@ export async function importFile<T = void>(
1215
} & TraceOptions
1316
): Promise<T> {
1417
const { trace, onImported } = options || {}
15-
if (!filename) throw new Error("filename is required")
18+
if (!filename) {
19+
throw new Error("filename is required")
20+
}
1621

1722
let unregister: () => void = undefined
1823
try {
24+
dbg(`resolving module path for filename: ${filename}`)
1925
const modulePath = pathToFileURL(
2026
host.path.isAbsolute(filename)
2127
? filename
@@ -25,6 +31,7 @@ export async function importFile<T = void>(
2531
import.meta.url ??
2632
pathToFileURL(__filename ?? host.projectFolder()).toString()
2733

34+
dbg(`importing module from path: ${modulePath}`)
2835
const onImport = (file: string) => {
2936
// trace?.itemValue("📦 import", fileURLToPath(file))
3037
}
@@ -41,6 +48,7 @@ export async function importFile<T = void>(
4148

4249
return result
4350
} catch (err) {
51+
dbg("module imported failed")
4452
unregister?.()
4553
logError(err)
4654
trace?.error(err)
@@ -57,15 +65,19 @@ export async function importPrompt(
5765
) {
5866
mark("prompt.import")
5967
const { filename } = r
68+
dbg(`importing file: ${filename}`)
6069
return await importFile(filename, {
6170
...(options || {}),
6271
onImported: async (module) => {
6372
const main = module.default
64-
if (typeof main === "function") await main(ctx0)
65-
else if (r.isSystem)
73+
if (typeof main === "function") {
74+
dbg(`found default export as function, calling`)
75+
await main(ctx0)
76+
} else if (r.isSystem) {
6677
throw new Error(
6778
"system prompt using esm JavaScript (mjs, mts) must have a default function."
6879
)
80+
}
6981
},
7082
})
7183
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
genaiscript.d.ts
2+
tsconfig.json
3+
jsconfig.json
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { parse } from "ini"
2+
script({ model: "echo" })
3+
const v = parse(`A = B`)
4+
$`write a short poem about ${v}`

packages/modulesample/package.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "genaiscript-modulesample",
3+
"type": "module",
4+
"scripts": {
5+
"genai": "node ../cli/built/genaiscript.cjs run",
6+
"test": "yarn genai poem-js-module"
7+
}
8+
}

0 commit comments

Comments
 (0)