Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9afa980
adding basic tests
pelikhan Jun 24, 2025
66911bb
split runtime file
pelikhan Jun 24, 2025
7d98bce
split helpers in files
pelikhan Jun 24, 2025
5f91514
refactor: remove deprecated fs property and enhance NodeHost installa…
pelikhan Jun 24, 2025
2e0bb6e
refactor: update .gitignore to include package.json files and clean u…
pelikhan Jun 24, 2025
519db99
refactor: reorder globalPromptContext declaration and installGlobals …
pelikhan Jun 24, 2025
3bb508a
resolve context
pelikhan Jun 24, 2025
53257ba
refactor: integrate resolveRuntime function and update parser usage a…
pelikhan Jun 24, 2025
102e738
more tests
pelikhan Jun 24, 2025
fd944ae
refactor: simplify parser creation and remove unused parameters in pr…
pelikhan Jun 24, 2025
257c5e9
refactor: update type definitions and improve global declarations for…
pelikhan Jun 24, 2025
b805713
refactor: streamline imports from runtime and add run:node script
pelikhan Jun 24, 2025
2f718fa
refactor: update trace handling in context creation and expand functions
pelikhan Jun 24, 2025
820d144
✨ refactor: enhance trace handling robustness
pelikhan Jun 25, 2025
061278a
✨ Enable quiet mode during runtime configuration
pelikhan Jun 25, 2025
9feb262
🛠️ chore: migrate tsx to "catalog" dependency
pelikhan Jun 25, 2025
8eb05fb
✨ feat: enhance poem functionality with config and options
pelikhan Jun 25, 2025
47f9c7a
✨ chore: Integrate catalog references for dependencies
pelikhan Jun 25, 2025
bff9bce
🛠️ chore: remove redundant tokens test from parsers
pelikhan Jun 25, 2025
0fecb4c
✨ feat: add utility functions and export enhancements
pelikhan Jun 25, 2025
2c1105e
✨ refactor(runtime): enhance initialization and token handling
pelikhan Jun 25, 2025
604f954
✨ Enhance type safety and improve React component handling
pelikhan Jun 25, 2025
4e5453e
fixing tests
pelikhan Jun 25, 2025
3c3de89
✨ feat: add runtime tests to build workflow and update test script in…
pelikhan Jun 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: compile tests
run: pnpm run test:compile
continue-on-error: true
- name: runtime tests
run: pnpm run test:runtime
- name: unit tests
run: pnpm run test:samples
env:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,5 @@ genaiscript*.tgz
# START Ruler Generated Files
.github/copilot-instructions.md
# END Ruler Generated Files

packages/*/src/package.json
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"chattypes",
"Chunker",
"chunkers",
"clihelp",
"cmds",
"cmsg",
"codelion",
Expand Down Expand Up @@ -95,6 +96,7 @@
"fallbacktools",
"fetchtext",
"ffprobe",
"filetree",
"firstsecond",
"Fmepg",
"frontmatter",
Expand Down Expand Up @@ -160,6 +162,7 @@
"makeitbetter",
"managedidentity",
"markdownify",
"markdownifypdf",
"markitdown",
"mcpclient",
"mcpresource",
Expand Down
23 changes: 23 additions & 0 deletions docs/src/content/docs/reference/runtime.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
title: Runtime
sidebar:
order: 1.2
description: Learn how to run GenAIScript scripts in a Node.JS environment, including configuration
---

Scripts using the `.genai.mts` (or any `.genai.*` extension) are meant to be run through the [command line interfanece](/genaiscript/reference/cli).

This page describes how to use the runtime in a Node.JS script without using the CLI.

## Import and configuration

```js
import { initialize } from "@genaiscript/runtime";

// runs this before using any global ty\pes
await initialize();
```

## globals

The runtime installs global parsers and inline prompt types. However, the global `$`, `def`, etc... is not available, online inline prompts.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@
"test:scripts": "cd packages/sample/ && pnpm test:scripts",
"test:scripts:view": "cd packages/sample/ && pnpm test:scripts:view",
"test:system": "cd packages/core && node ../cli/dist/src/index.js scripts compile",
"test:runtime": "cd packages/runtime && pnpm run test",
"tsx": "tsx",
"typecheck": "echo skipped",
"typecheck:web": "pnpm --filter=@genaiscript/web run typecheck",
"whisper": "pnpm whisper:stop && pnpm whisper:start",
Expand All @@ -108,7 +110,7 @@
}
},
"devDependencies": {
"@inquirer/prompts": "^7.5.3",
"@inquirer/prompts": "catalog:",
"@intellectronica/ruler": "^0.2.3",
"@modelcontextprotocol/inspector": "^0.14.3",
"npm-check-updates": "^18.0.1",
Expand All @@ -117,6 +119,7 @@
"prettier": "catalog:",
"prettier-plugin-curly": "^0.3.2",
"tailwindcss": "^4.1.10",
"tsx": "catalog:",
"turbo": "^2.5.4",
"zx": "catalog:"
}
Expand Down
2 changes: 1 addition & 1 deletion packages/api/src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ export async function runScriptInternal(
topLogprobs,
fenceFormat,
runDir,
applyGitIgnore,
applyGitIgnore,
cliInfo: options.cli
? {
files,
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"@genaiscript/api": "workspace:*",
"@genaiscript/core": "workspace:*",
"@genaiscript/runtime": "workspace:*",
"@inquirer/prompts": "^7.5.3",
"@inquirer/prompts": "catalog:",
"@modelcontextprotocol/sdk": "^1.13.1",
"chokidar": "^4.0.3",
"commander": "^12.1.0",
Expand Down
7 changes: 6 additions & 1 deletion packages/cli/src/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,12 @@ export async function actionConfigure(
].filter(Boolean);

const actionYmlFilename = resolve(out, "action.yml");
const action = YAMLTryParse(await tryReadText(actionYmlFilename));
const action = YAMLTryParse(await tryReadText(actionYmlFilename)) as {
description?: string;
inputs?: Record<string, GitHubActionFieldType>;
outputs?: Record<string, GitHubActionFieldType>;
branding?: Record<string, unknown>;
};
if (action && !force) {
logVerbose(`updating action.yml`);
action.description = script.description || pkg?.description;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
"toml": "^3.0.0",
"ts-dedent": "^2.2.0",
"tslib": "catalog:",
"tsx": "^4.19.4",
"tsx": "catalog:",
"turndown": "^7.2.0",
"turndown-plugin-gfm": "^1.0.2",
"undici": "^7.10.0",
Expand Down
9 changes: 5 additions & 4 deletions packages/core/src/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export async function agentAddMemory(
};
dbg(`add ${agent}: ${ellipse(query, 80)} -> ${ellipse(text, 128)}`);
await cache.set(cacheKey, cachedValue);
trace.detailsFenced(
trace?.detailsFenced(
`🧠 agent memory: ${HTMLEscape(query)}`,
HTMLEscape(prettifyMarkdown(cachedValue.answer)),
"markdown",
Expand Down Expand Up @@ -139,25 +139,26 @@ export async function traceAgentMemory(
options: Pick<GenerationOptions, "userState"> & Required<TraceOptions>,
) {
const { trace } = options || {};
if (!trace) return;
const cache = agentCreateCache({
userState: options.userState,
lookupOnly: true,
});
const memories = await loadMemories(cache);
if (memories?.length) {
try {
trace.startDetails("🧠 agent memory");
trace?.startDetails("🧠 agent memory");
memories
.reverse()
.forEach(({ agent, query, answer }) =>
trace.detailsFenced(
trace?.detailsFenced(
`👤 ${agent}: ${HTMLEscape(query)}`,
HTMLEscape(prettifyMarkdown(answer)),
"markdown",
),
);
} finally {
trace.endDetails();
trace?.endDetails();
}
}
}
Expand Down
29 changes: 16 additions & 13 deletions packages/core/src/anthropic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ const convertAssistantMessage = (
signature: msg.signature,
} satisfies Anthropic.ThinkingBlockParam)
: undefined,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...((convertStandardMessage(msg)?.content || []) as any),
...(msg.tool_calls || []).map(
(tool) =>
Expand Down Expand Up @@ -305,7 +306,7 @@ const completerFactory = (
const httpAgent = await resolveHttpProxyAgent();
const messagesApi = await resolver(trace, cfg, httpAgent, fetch);
dbg("caching", caching);
trace.itemValue(`caching`, caching);
trace?.itemValue(`caching`, caching);

let numTokens = 0;
let chatResp = "";
Expand Down Expand Up @@ -363,8 +364,8 @@ const completerFactory = (
}

dbgMessages(`messages: %O`, messages);
trace.detailsFenced("✉️ body", mreq, "json");
trace.appendContent("\n");
trace?.detailsFenced("✉️ body", mreq, "json");
trace?.appendContent("\n");

try {
const stream = messagesApi.stream({ ...mreq, ...headers });
Expand Down Expand Up @@ -399,17 +400,17 @@ const completerFactory = (
break;
case "thinking_delta":
reasoningContent = chunk.delta.thinking;
trace.appendToken(reasoningContent);
trace?.appendToken(reasoningContent);
reasoningChatResp += reasoningContent;
trace.appendToken(chunkContent);
trace?.appendToken(chunkContent);
break;
case "text_delta":
if (!chunk.delta.text) dbg(`empty text_delta`, chunk);
else {
chunkContent = chunk.delta.text;
numTokens += approximateTokens(chunkContent, { encoder });
chatResp += chunkContent;
trace.appendToken(chunkContent);
trace?.appendToken(chunkContent);
}
break;

Expand Down Expand Up @@ -448,13 +449,13 @@ const completerFactory = (
} catch (e) {
finishReason = "fail";
logError(e);
trace.error("error while processing event", serializeError(e));
trace?.error("error while processing event", serializeError(e));
}

trace.appendContent("\n\n");
trace.itemValue(`🏁 finish reason`, finishReason);
trace?.appendContent("\n\n");
trace?.itemValue(`🏁 finish reason`, finishReason);
if (usage?.total_tokens) {
trace.itemValue(
trace?.itemValue(
`🪙 tokens`,
`${usage.total_tokens} total, ${usage.prompt_tokens} prompt, ${usage.completion_tokens} completion`,
);
Expand All @@ -472,7 +473,7 @@ const completerFactory = (
return completion;
};

const listModels: ListModelsFunction = async (cfg, options) => {
const listModels: ListModelsFunction = async (cfg) => {
try {
const anthropic = new Anthropic({
baseURL: cfg.base,
Expand Down Expand Up @@ -507,9 +508,10 @@ export const AnthropicModel = Object.freeze<LanguageModel>({
fetch,
fetchOptions: {
dispatcher: httpAgent,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as RequestInit as any,
});
if (anthropic.baseURL) trace.itemValue(`url`, `[${anthropic.baseURL}](${anthropic.baseURL})`);
if (anthropic.baseURL) trace?.itemValue(`url`, `[${anthropic.baseURL}](${anthropic.baseURL})`);
const messagesApi = anthropic.beta.messages;
return messagesApi;
}),
Expand All @@ -524,9 +526,10 @@ export const AnthropicBedrockModel = Object.freeze<LanguageModel>({
fetch,
fetchOptions: {
dispatcher: httpAgent,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as RequestInit as any,
});
if (anthropic.baseURL) trace.itemValue(`url`, `[${anthropic.baseURL}](${anthropic.baseURL})`);
if (anthropic.baseURL) trace?.itemValue(`url`, `[${anthropic.baseURL}](${anthropic.baseURL})`);
return anthropic.beta.messages;
}),
id: MODEL_PROVIDER_ANTHROPIC_BEDROCK,
Expand Down
Loading
Loading