@far-world-labs/verblets 0.1.3 → 0.1.7

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.
@@ -85,11 +85,13 @@ jobs:
85
85
  echo "✅ Linting: Passed"
86
86
  echo "✅ Tests: Passed on all LTS Node versions"
87
87
  echo "✅ Build: Successful"
88
+ echo "ℹ️ Version: Will be checked on merge (publish only if bumped)"
88
89
  echo ""
89
90
  echo "This PR is now ready for squash and merge."
90
91
 
92
+ # Publish to NPM and create git tag - only if version was bumped
91
93
  release:
92
- name: 🚀 Release
94
+ name: 🚀 Publish to NPM
93
95
  runs-on: ubuntu-latest
94
96
  needs: build
95
97
  if: github.ref == 'refs/heads/main' && github.event_name == 'push'
@@ -108,13 +110,56 @@ jobs:
108
110
  cache: 'npm'
109
111
  - run: npm ci
110
112
 
111
- - name: Configure Git
113
+ - name: Check if version was bumped
114
+ id: version-check
112
115
  run: |
116
+ CURRENT_VERSION=$(node -p "require('./package.json').version")
117
+ PUBLISHED_VERSION=$(npm view @far-world-labs/verblets version 2>/dev/null || echo "0.0.0")
118
+
119
+ echo "📦 Current version in package.json: $CURRENT_VERSION"
120
+ echo "📦 Published version on npm: $PUBLISHED_VERSION"
121
+
122
+ if [ "$CURRENT_VERSION" = "$PUBLISHED_VERSION" ]; then
123
+ echo "should-publish=false" >> $GITHUB_OUTPUT
124
+ echo "ℹ️ No version bump detected - skipping publish"
125
+ else
126
+ echo "should-publish=true" >> $GITHUB_OUTPUT
127
+ echo "✅ Version bump detected: $PUBLISHED_VERSION → $CURRENT_VERSION - will publish"
128
+ fi
129
+
130
+ - name: Create Git Tag
131
+ if: steps.version-check.outputs.should-publish == 'true'
132
+ run: |
133
+ VERSION=$(node -p "require('./package.json').version")
113
134
  git config --global user.name "github-actions[bot]"
114
135
  git config --global user.email "github-actions[bot]@users.noreply.github.com"
136
+ git tag -a "v$VERSION" -m "Release v$VERSION"
137
+ git push origin "v$VERSION"
115
138
 
116
- - name: Release
139
+ - name: Publish to NPM
140
+ if: steps.version-check.outputs.should-publish == 'true'
117
141
  env:
118
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
119
142
  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
120
- run: npx release-it --ci
143
+ run: |
144
+ # Version was manually bumped and validated in PR
145
+ npm publish --access public
146
+
147
+ - name: Create GitHub Release
148
+ if: steps.version-check.outputs.should-publish == 'true'
149
+ env:
150
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
151
+ run: |
152
+ # Get version from package.json
153
+ VERSION=$(node -p "require('./package.json').version")
154
+
155
+ # Create GitHub release
156
+ gh release create "v$VERSION" \
157
+ --title "Release v$VERSION" \
158
+ --notes "Automated release of version $VERSION" \
159
+ --latest
160
+
161
+ - name: Skip publish
162
+ if: steps.version-check.outputs.should-publish == 'false'
163
+ run: |
164
+ echo "ℹ️ No version bump detected - publish skipped"
165
+ echo "This merge completed without triggering a release"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@far-world-labs/verblets",
3
- "version": "0.1.3",
4
- "description": "OpenAI Client",
3
+ "version": "0.1.7",
4
+ "description": "Verblets is a collection of tools for building LLM-powered applications.",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
7
7
  "repository": {
@@ -11,7 +11,7 @@ export default async function themes(text, config = {}) {
11
11
  const { chunkSize = 5, topN, llm, ...options } = config;
12
12
  const pieces = splitText(text);
13
13
  const reducePrompt =
14
- 'Update the accumulator with short themes from this text. Avoid duplicates. Return a comma-separated list of themes.';
14
+ 'Update the accumulator with short themes from this text. Avoid duplicates. Return ONLY a comma-separated list of themes with no explanation or additional text.';
15
15
  const firstPass = await bulkReduce(shuffle(pieces), reducePrompt, { chunkSize, llm, ...options });
16
16
  const rawThemes = firstPass
17
17
  .split(',')
@@ -19,7 +19,7 @@ export default async function themes(text, config = {}) {
19
19
  .filter(Boolean);
20
20
 
21
21
  const limitText = topN ? `Limit to the top ${topN} themes.` : 'Return all meaningful themes.';
22
- const refinePrompt = `Refine the accumulator by merging similar themes. ${limitText} Return a comma-separated list.`;
22
+ const refinePrompt = `Refine the accumulator by merging similar themes. ${limitText} Return ONLY a comma-separated list with no explanation or additional text.`;
23
23
  const final = await bulkReduce(rawThemes, refinePrompt, { chunkSize, llm, ...options });
24
24
  return final
25
25
  .split(',')
@@ -1,9 +1,10 @@
1
- // Importing dotenv config to load environment variables from .env file
2
- // eslint-disable-next-line no-unused-vars
3
- import dotenv from 'dotenv/config';
1
+ // Environment variables loaded in index.js
4
2
 
5
3
  const _models = {};
6
4
 
5
+ // Function to get API key at runtime
6
+ const getOpenAIKey = () => process.env.OPENAI_API_KEY;
7
+
7
8
  const systemPrompt = `You are a superintelligent processing unit, answering prompts with precise instructions.
8
9
  You are a small but critical component in a complex system, so your role in giving quality outputs to your given inputs and instructions is critical.
9
10
  You must obey those instructions to the letter at all costs--do not deviate or add your own interpretation or flair. Stick to the instructions.
@@ -45,7 +46,9 @@ _models.fastCheapMulti = {
45
46
  maxContextWindow: 128_000,
46
47
  maxOutputTokens: 16_384,
47
48
  requestTimeout: 20_000,
48
- apiKey: process.env.OPENAI_API_KEY ?? 'undefined',
49
+ get apiKey() {
50
+ return getOpenAIKey();
51
+ },
49
52
  apiUrl: 'https://api.openai.com/',
50
53
  systemPrompt,
51
54
  };
@@ -59,7 +62,9 @@ _models.goodMulti = {
59
62
  maxContextWindow: 128_000,
60
63
  maxOutputTokens: 16_384,
61
64
  requestTimeout: 20_000,
62
- apiKey: process.env.OPENAI_API_KEY ?? 'undefined',
65
+ get apiKey() {
66
+ return getOpenAIKey();
67
+ },
63
68
  apiUrl: 'https://api.openai.com/',
64
69
  systemPrompt,
65
70
  };
@@ -73,7 +78,9 @@ _models.fastCheapReasoningMulti = {
73
78
  maxContextWindow: 128_000,
74
79
  maxOutputTokens: 16_384,
75
80
  requestTimeout: 40_000,
76
- apiKey: process.env.OPENAI_API_KEY ?? 'undefined',
81
+ get apiKey() {
82
+ return getOpenAIKey();
83
+ },
77
84
  apiUrl: 'https://api.openai.com/',
78
85
  systemPrompt,
79
86
  };
@@ -87,7 +94,9 @@ _models.reasoningNoImage = {
87
94
  maxContextWindow: 200_000,
88
95
  maxOutputTokens: 100_000,
89
96
  requestTimeout: 120_000,
90
- apiKey: process.env.OPENAI_API_KEY ?? 'undefined',
97
+ get apiKey() {
98
+ return getOpenAIKey();
99
+ },
91
100
  apiUrl: 'https://api.openai.com/',
92
101
  systemPrompt,
93
102
  };
@@ -132,7 +141,9 @@ _models.privacy = {
132
141
  apiUrl: (process.env.OPENWEBUI_API_URL ?? '').endsWith('/')
133
142
  ? process.env.OPENWEBUI_API_URL
134
143
  : `${process.env.OPENWEBUI_API_URL}/`,
135
- apiKey: process.env.OPENWEBUI_API_KEY ?? 'undefined',
144
+ get apiKey() {
145
+ return process.env.OPENWEBUI_API_KEY;
146
+ },
136
147
  systemPrompt,
137
148
  modelOptions: {
138
149
  stop: ['</s>'],
package/src/index.js CHANGED
@@ -1,6 +1,6 @@
1
- // Importing dotenv config to load environment variables from .env file
2
- // eslint-disable-next-line no-unused-vars
3
- import dotenv from 'dotenv/config';
1
+ // Load environment variables from .env file FIRST
2
+ import dotenv from 'dotenv';
3
+ dotenv.config();
4
4
 
5
5
  import chatGPT from './lib/chatgpt/index.js';
6
6