@turingpulse/sdk 1.0.1
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/.github/dependabot.yml +38 -0
- package/.github/workflows/ci.yml +246 -0
- package/.github/workflows/framework-compat.yml +169 -0
- package/.github/workflows/security.yml +336 -0
- package/CHANGELOG.md +29 -0
- package/LICENSE +13 -0
- package/MIGRATION.md +30 -0
- package/README.md +221 -0
- package/dist/attachments.d.ts +28 -0
- package/dist/attachments.d.ts.map +1 -0
- package/dist/attachments.js +59 -0
- package/dist/attachments.js.map +1 -0
- package/dist/config.d.ts +72 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +78 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +126 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +163 -0
- package/dist/context.js.map +1 -0
- package/dist/decorators.d.ts +6 -0
- package/dist/decorators.d.ts.map +1 -0
- package/dist/decorators.js +52 -0
- package/dist/decorators.js.map +1 -0
- package/dist/deploy.d.ts +89 -0
- package/dist/deploy.d.ts.map +1 -0
- package/dist/deploy.js +203 -0
- package/dist/deploy.js.map +1 -0
- package/dist/errors.d.ts +18 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +34 -0
- package/dist/errors.js.map +1 -0
- package/dist/eventBuilder.d.ts +21 -0
- package/dist/eventBuilder.d.ts.map +1 -0
- package/dist/eventBuilder.js +127 -0
- package/dist/eventBuilder.js.map +1 -0
- package/dist/fingerprint.d.ts +158 -0
- package/dist/fingerprint.d.ts.map +1 -0
- package/dist/fingerprint.js +339 -0
- package/dist/fingerprint.js.map +1 -0
- package/dist/governance.d.ts +47 -0
- package/dist/governance.d.ts.map +1 -0
- package/dist/governance.js +104 -0
- package/dist/governance.js.map +1 -0
- package/dist/http.d.ts +62 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +181 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/instrumentation.d.ts +40 -0
- package/dist/instrumentation.d.ts.map +1 -0
- package/dist/instrumentation.js +31 -0
- package/dist/instrumentation.js.map +1 -0
- package/dist/integrations/mastra.d.ts +64 -0
- package/dist/integrations/mastra.d.ts.map +1 -0
- package/dist/integrations/mastra.js +256 -0
- package/dist/integrations/mastra.js.map +1 -0
- package/dist/kpi.d.ts +21 -0
- package/dist/kpi.d.ts.map +1 -0
- package/dist/kpi.js +83 -0
- package/dist/kpi.js.map +1 -0
- package/dist/llmDetector.d.ts +22 -0
- package/dist/llmDetector.d.ts.map +1 -0
- package/dist/llmDetector.js +269 -0
- package/dist/llmDetector.js.map +1 -0
- package/dist/plugin.d.ts +33 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +312 -0
- package/dist/plugin.js.map +1 -0
- package/dist/registry.d.ts +13 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +18 -0
- package/dist/registry.js.map +1 -0
- package/dist/tracing.d.ts +10 -0
- package/dist/tracing.d.ts.map +1 -0
- package/dist/tracing.js +30 -0
- package/dist/tracing.js.map +1 -0
- package/dist/triggerState.d.ts +5 -0
- package/dist/triggerState.d.ts.map +1 -0
- package/dist/triggerState.js +19 -0
- package/dist/triggerState.js.map +1 -0
- package/dist/utils.d.ts +27 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +72 -0
- package/dist/utils.js.map +1 -0
- package/package.json +37 -0
- package/packages/anthropic/package.json +16 -0
- package/packages/anthropic/src/index.ts +5 -0
- package/packages/anthropic/src/wrapper.ts +102 -0
- package/packages/anthropic/tsconfig.build.json +20 -0
- package/packages/langchain/package.json +16 -0
- package/packages/langchain/src/index.ts +7 -0
- package/packages/langchain/src/wrapper.ts +51 -0
- package/packages/mastra/package.json +17 -0
- package/packages/mastra/src/index.ts +8 -0
- package/packages/mastra/src/wrapper.ts +301 -0
- package/packages/openai/package.json +16 -0
- package/packages/openai/src/index.ts +8 -0
- package/packages/openai/src/wrapper.ts +103 -0
- package/packages/openai/tsconfig.build.json +20 -0
- package/packages/openclaw/openclaw.plugin.json +100 -0
- package/packages/openclaw/package.json +41 -0
- package/packages/openclaw/src/buffer.ts +99 -0
- package/packages/openclaw/src/config.ts +139 -0
- package/packages/openclaw/src/hooks/governance.ts +267 -0
- package/packages/openclaw/src/hooks/lifecycle.ts +75 -0
- package/packages/openclaw/src/hooks/telemetry.ts +207 -0
- package/packages/openclaw/src/index.ts +91 -0
- package/packages/openclaw/src/mapper.ts +233 -0
- package/packages/openclaw/src/session-tracker.ts +181 -0
- package/packages/openclaw/src/types.ts +220 -0
- package/packages/openclaw/tests/buffer.test.ts +148 -0
- package/packages/openclaw/tests/config.test.ts +122 -0
- package/packages/openclaw/tests/governance.test.ts +232 -0
- package/packages/openclaw/tests/mapper.test.ts +242 -0
- package/packages/openclaw/tests/session-tracker.test.ts +124 -0
- package/packages/openclaw/tsconfig.json +18 -0
- package/packages/openclaw/vitest.config.ts +8 -0
- package/packages/vercel-ai/package.json +16 -0
- package/packages/vercel-ai/src/index.ts +5 -0
- package/packages/vercel-ai/src/wrapper.ts +49 -0
- package/scripts/bump-version.sh +58 -0
- package/scripts/update-readme-compat.mjs +151 -0
- package/src/__tests__/fingerprint.test.ts +328 -0
- package/src/attachments.ts +88 -0
- package/src/config.ts +164 -0
- package/src/context.ts +258 -0
- package/src/decorators.ts +61 -0
- package/src/deploy.ts +260 -0
- package/src/errors.ts +44 -0
- package/src/eventBuilder.ts +153 -0
- package/src/fingerprint.ts +421 -0
- package/src/governance.ts +156 -0
- package/src/http.ts +241 -0
- package/src/index.ts +57 -0
- package/src/instrumentation.ts +68 -0
- package/src/integrations/mastra.ts +335 -0
- package/src/kpi.ts +112 -0
- package/src/llmDetector.ts +330 -0
- package/src/plugin.ts +384 -0
- package/src/registry.ts +27 -0
- package/src/tracing.ts +39 -0
- package/src/triggerState.ts +27 -0
- package/src/utils.ts +78 -0
- package/tests/compat/anthropic.test.ts +61 -0
- package/tests/compat/cohere.test.ts +57 -0
- package/tests/compat/google-genai.test.ts +61 -0
- package/tests/compat/langchain-openai.test.ts +41 -0
- package/tests/compat/langchain.test.ts +64 -0
- package/tests/compat/mistral.test.ts +58 -0
- package/tests/compat/openai.test.ts +71 -0
- package/tests/compat/vercel-ai.test.ts +56 -0
- package/tests/plugins/anthropic-wrapper.test.ts +120 -0
- package/tests/plugins/langchain-wrapper.test.ts +128 -0
- package/tests/plugins/openai-wrapper.test.ts +165 -0
- package/tsconfig.json +21 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "npm"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
day: "monday"
|
|
8
|
+
open-pull-requests-limit: 10
|
|
9
|
+
labels:
|
|
10
|
+
- "dependencies"
|
|
11
|
+
- "security"
|
|
12
|
+
commit-message:
|
|
13
|
+
prefix: "deps"
|
|
14
|
+
groups:
|
|
15
|
+
production-dependencies:
|
|
16
|
+
dependency-type: "production"
|
|
17
|
+
patterns:
|
|
18
|
+
- "*"
|
|
19
|
+
update-types:
|
|
20
|
+
- "patch"
|
|
21
|
+
- "minor"
|
|
22
|
+
|
|
23
|
+
- package-ecosystem: "docker"
|
|
24
|
+
directory: "/"
|
|
25
|
+
schedule:
|
|
26
|
+
interval: "weekly"
|
|
27
|
+
labels:
|
|
28
|
+
- "dependencies"
|
|
29
|
+
- "docker"
|
|
30
|
+
- "security"
|
|
31
|
+
|
|
32
|
+
- package-ecosystem: "github-actions"
|
|
33
|
+
directory: "/"
|
|
34
|
+
schedule:
|
|
35
|
+
interval: "weekly"
|
|
36
|
+
labels:
|
|
37
|
+
- "dependencies"
|
|
38
|
+
- "github-actions"
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# CI + Publish for TypeScript SDK
|
|
2
|
+
name: CI
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
pull_request:
|
|
8
|
+
branches: [main]
|
|
9
|
+
release:
|
|
10
|
+
types: [published]
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
name: Build and Lint
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
matrix:
|
|
18
|
+
node-version: ['18', '20']
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Set up Node.js ${{ matrix.node-version }}
|
|
24
|
+
uses: actions/setup-node@v4
|
|
25
|
+
with:
|
|
26
|
+
node-version: ${{ matrix.node-version }}
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: npm install
|
|
30
|
+
|
|
31
|
+
- name: Type check
|
|
32
|
+
run: npm run lint
|
|
33
|
+
|
|
34
|
+
- name: Build
|
|
35
|
+
run: npm run build
|
|
36
|
+
|
|
37
|
+
pre-publish-scan:
|
|
38
|
+
name: Pre-Publish Security Scan
|
|
39
|
+
runs-on: ubuntu-latest
|
|
40
|
+
if: github.event_name == 'release'
|
|
41
|
+
permissions:
|
|
42
|
+
contents: write
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v4
|
|
45
|
+
with:
|
|
46
|
+
fetch-depth: 0
|
|
47
|
+
|
|
48
|
+
# ── 1. Secret Detection (git history + filesystem) ──────────────
|
|
49
|
+
- name: Run TruffleHog secret scan
|
|
50
|
+
run: |
|
|
51
|
+
echo '.git/' > .trufflehog-exclude
|
|
52
|
+
docker run --rm -v "$PWD:/pwd" trufflesecurity/trufflehog:latest \
|
|
53
|
+
filesystem /pwd --exclude-paths=/pwd/.trufflehog-exclude --json > trufflehog-report.json 2>&1
|
|
54
|
+
SECRETS_FOUND=$(grep -c '"SourceMetadata"' trufflehog-report.json 2>/dev/null || echo "0")
|
|
55
|
+
if [ "$SECRETS_FOUND" -gt 0 ]; then
|
|
56
|
+
echo "::error::TruffleHog found ${SECRETS_FOUND} potential secrets — publish blocked"
|
|
57
|
+
cat trufflehog-report.json
|
|
58
|
+
exit 1
|
|
59
|
+
fi
|
|
60
|
+
echo "TruffleHog: no secrets detected"
|
|
61
|
+
|
|
62
|
+
# ── 2. Sensitive Pattern Scan (source code) ─────────────────────
|
|
63
|
+
- name: Scan source code for hardcoded secrets and sensitive patterns
|
|
64
|
+
run: |
|
|
65
|
+
PATTERNS=(
|
|
66
|
+
'AKIA[0-9A-Z]{16}' # AWS Access Key ID
|
|
67
|
+
'AIza[0-9A-Za-z\-_]{35}' # Google API Key
|
|
68
|
+
'sk-[a-zA-Z0-9]{20,}' # OpenAI / Stripe secret key
|
|
69
|
+
'ghp_[a-zA-Z0-9]{36}' # GitHub PAT
|
|
70
|
+
'glpat-[a-zA-Z0-9\-]{20,}' # GitLab PAT
|
|
71
|
+
'xox[bpors]-[a-zA-Z0-9\-]+' # Slack token
|
|
72
|
+
'eyJ[a-zA-Z0-9_-]*\.eyJ[a-zA-Z0-9_-]*' # JWT token
|
|
73
|
+
'password\s*=\s*["\x27][^"\x27]{8,}' # Hardcoded passwords
|
|
74
|
+
'mongodb(\+srv)?://[^\s]+' # MongoDB URIs
|
|
75
|
+
'redis://[^\s]+' # Redis URIs
|
|
76
|
+
)
|
|
77
|
+
FOUND=0
|
|
78
|
+
for pattern in "${PATTERNS[@]}"; do
|
|
79
|
+
MATCHES=$(grep -rEn "$pattern" src/ packages/ --include="*.ts" --include="*.js" 2>/dev/null || true)
|
|
80
|
+
if [ -n "$MATCHES" ]; then
|
|
81
|
+
echo "::error::Sensitive pattern found: $pattern"
|
|
82
|
+
echo "$MATCHES"
|
|
83
|
+
FOUND=$((FOUND + 1))
|
|
84
|
+
fi
|
|
85
|
+
done
|
|
86
|
+
if [ "$FOUND" -gt 0 ]; then
|
|
87
|
+
echo "::error::Found $FOUND sensitive patterns in source — publish blocked"
|
|
88
|
+
exit 1
|
|
89
|
+
fi
|
|
90
|
+
echo "Source scan: no hardcoded secrets found"
|
|
91
|
+
|
|
92
|
+
- name: Set up Node.js
|
|
93
|
+
uses: actions/setup-node@v4
|
|
94
|
+
with:
|
|
95
|
+
node-version: '20'
|
|
96
|
+
|
|
97
|
+
- name: Set up Python (for Semgrep)
|
|
98
|
+
uses: actions/setup-python@v5
|
|
99
|
+
with:
|
|
100
|
+
python-version: '3.12'
|
|
101
|
+
|
|
102
|
+
- name: Install dependencies
|
|
103
|
+
run: npm install
|
|
104
|
+
|
|
105
|
+
# ── 3. SAST — Semgrep (TypeScript rules) ───────────────────────
|
|
106
|
+
- name: Run Semgrep SAST scan
|
|
107
|
+
run: |
|
|
108
|
+
pip install semgrep
|
|
109
|
+
semgrep --config=auto --config=p/typescript \
|
|
110
|
+
--severity ERROR \
|
|
111
|
+
--json --output=semgrep-report.json \
|
|
112
|
+
src/ packages/ 2>&1 || true
|
|
113
|
+
python3 -c '
|
|
114
|
+
import json, sys
|
|
115
|
+
try:
|
|
116
|
+
data = json.load(open("semgrep-report.json"))
|
|
117
|
+
errors = [r for r in data.get("results", []) if r.get("extra", {}).get("severity") == "ERROR"]
|
|
118
|
+
if errors:
|
|
119
|
+
for e in errors:
|
|
120
|
+
msg = e.get("extra", {}).get("message", "")[:120]
|
|
121
|
+
print(" " + e["path"] + ":" + str(e["start"]["line"]) + " - " + e["check_id"] + ": " + msg)
|
|
122
|
+
sys.exit(1)
|
|
123
|
+
except Exception as e:
|
|
124
|
+
print("Semgrep parse warning: " + str(e))
|
|
125
|
+
' || { echo "::error::Semgrep found ERROR-level issues — publish blocked"; exit 1; }
|
|
126
|
+
echo "Semgrep SAST: no error-level issues"
|
|
127
|
+
|
|
128
|
+
# ── 4. Dependency CVE Audit (HARD GATE) ─────────────────────────
|
|
129
|
+
- name: Run npm audit (hard gate on high/critical)
|
|
130
|
+
run: |
|
|
131
|
+
npm audit --json > npm-audit-report.json 2>&1 || true
|
|
132
|
+
VULNS=$(node -e "
|
|
133
|
+
const r = require('./npm-audit-report.json');
|
|
134
|
+
const meta = r.metadata?.vulnerabilities || {};
|
|
135
|
+
const high = (meta.high || 0) + (meta.critical || 0);
|
|
136
|
+
console.log(high);
|
|
137
|
+
" 2>/dev/null || echo "0")
|
|
138
|
+
if [ "$VULNS" -gt 0 ]; then
|
|
139
|
+
echo "::error::npm audit found ${VULNS} high/critical vulnerabilities — publish blocked"
|
|
140
|
+
npm audit --audit-level=high || true
|
|
141
|
+
exit 1
|
|
142
|
+
fi
|
|
143
|
+
echo "npm audit: no high/critical vulnerabilities"
|
|
144
|
+
|
|
145
|
+
# ── 5. License Compliance ───────────────────────────────────────
|
|
146
|
+
- name: Check dependency licenses
|
|
147
|
+
run: |
|
|
148
|
+
npx license-checker --json --out licenses.json
|
|
149
|
+
npx license-checker --summary
|
|
150
|
+
BLOCKED=$(npx license-checker --failOn \
|
|
151
|
+
'GPL-2.0;GPL-3.0;AGPL-1.0;AGPL-3.0;SSPL-1.0;LGPL-2.0;LGPL-2.1;LGPL-3.0;GPL-2.0-only;GPL-3.0-only;AGPL-3.0-only' \
|
|
152
|
+
2>&1 || true)
|
|
153
|
+
if echo "$BLOCKED" | grep -q "Found restricted license"; then
|
|
154
|
+
echo "::error::Copyleft-licensed dependencies found — publish blocked for enterprise safety"
|
|
155
|
+
echo "$BLOCKED"
|
|
156
|
+
exit 1
|
|
157
|
+
fi
|
|
158
|
+
echo "License check: all dependencies have permissive licenses"
|
|
159
|
+
|
|
160
|
+
# ── 6. Publish Payload Deep Inspection ──────────────────────────
|
|
161
|
+
- name: Inspect npm pack contents for sensitive data
|
|
162
|
+
run: |
|
|
163
|
+
npm pack --dry-run 2>&1 | tee pack-listing.txt
|
|
164
|
+
echo "--- Checking file listing ---"
|
|
165
|
+
SENSITIVE_FILES=$(grep -iE \
|
|
166
|
+
'\.env|\.pem|\.key|\.p12|\.pfx|\.jks|credentials|secret|service.account|\.sqlite|\.db$' \
|
|
167
|
+
pack-listing.txt || true)
|
|
168
|
+
if [ -n "$SENSITIVE_FILES" ]; then
|
|
169
|
+
echo "::error::Sensitive files in publish payload — publish blocked:"
|
|
170
|
+
echo "$SENSITIVE_FILES"
|
|
171
|
+
exit 1
|
|
172
|
+
fi
|
|
173
|
+
echo "--- Packing and scanning content ---"
|
|
174
|
+
TARBALL=$(npm pack 2>/dev/null)
|
|
175
|
+
EXTRACT_DIR=$(mktemp -d)
|
|
176
|
+
tar xzf "$TARBALL" -C "$EXTRACT_DIR"
|
|
177
|
+
CONTENT_SECRETS=$(grep -rEn \
|
|
178
|
+
'AKIA[0-9A-Z]{16}|sk-[a-zA-Z0-9]{20,}|password\s*=\s*["\x27][^"\x27]{8,}|BEGIN (RSA |EC |DSA )?PRIVATE KEY' \
|
|
179
|
+
"$EXTRACT_DIR" --include="*.js" --include="*.ts" --include="*.json" 2>/dev/null || true)
|
|
180
|
+
if [ -n "$CONTENT_SECRETS" ]; then
|
|
181
|
+
echo "::error::Secrets found inside packed artifact content — publish blocked:"
|
|
182
|
+
echo "$CONTENT_SECRETS"
|
|
183
|
+
exit 1
|
|
184
|
+
fi
|
|
185
|
+
rm -rf "$EXTRACT_DIR" "$TARBALL"
|
|
186
|
+
echo "Payload inspection: clean"
|
|
187
|
+
|
|
188
|
+
# ── 7. SBOM Generation ─────────────────────────────────────────
|
|
189
|
+
- name: Generate SBOM (CycloneDX)
|
|
190
|
+
run: npx @cyclonedx/cyclonedx-npm --output-file sbom.json --output-format JSON
|
|
191
|
+
|
|
192
|
+
- name: Upload security reports
|
|
193
|
+
uses: actions/upload-artifact@v4
|
|
194
|
+
if: always()
|
|
195
|
+
with:
|
|
196
|
+
name: security-reports
|
|
197
|
+
path: |
|
|
198
|
+
trufflehog-report.json
|
|
199
|
+
semgrep-report.json
|
|
200
|
+
npm-audit-report.json
|
|
201
|
+
licenses.json
|
|
202
|
+
sbom.json
|
|
203
|
+
retention-days: 90
|
|
204
|
+
|
|
205
|
+
- name: Attach SBOM to release
|
|
206
|
+
if: success()
|
|
207
|
+
run: gh release upload "${{ github.ref_name }}" sbom.json --clobber
|
|
208
|
+
env:
|
|
209
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
210
|
+
|
|
211
|
+
publish:
|
|
212
|
+
name: Publish to npm
|
|
213
|
+
runs-on: ubuntu-latest
|
|
214
|
+
needs: [build, pre-publish-scan]
|
|
215
|
+
if: github.event_name == 'release'
|
|
216
|
+
permissions:
|
|
217
|
+
contents: read
|
|
218
|
+
id-token: write
|
|
219
|
+
steps:
|
|
220
|
+
- uses: actions/checkout@v4
|
|
221
|
+
|
|
222
|
+
- name: Set up Node.js
|
|
223
|
+
uses: actions/setup-node@v4
|
|
224
|
+
with:
|
|
225
|
+
node-version: '20'
|
|
226
|
+
registry-url: 'https://registry.npmjs.org'
|
|
227
|
+
|
|
228
|
+
- name: Install and build
|
|
229
|
+
run: npm install && npm run build
|
|
230
|
+
|
|
231
|
+
- name: Publish core package
|
|
232
|
+
run: npm publish --access public
|
|
233
|
+
env:
|
|
234
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
235
|
+
|
|
236
|
+
- name: Publish satellite packages
|
|
237
|
+
run: |
|
|
238
|
+
for pkg_dir in packages/*/; do
|
|
239
|
+
if [ -f "${pkg_dir}package.json" ]; then
|
|
240
|
+
PKG_NAME=$(node -e "console.log(require('./${pkg_dir}package.json').name)")
|
|
241
|
+
echo "Publishing ${PKG_NAME} from ${pkg_dir}..."
|
|
242
|
+
(cd "$pkg_dir" && npm publish --access public) || echo "WARN: ${PKG_NAME} publish failed"
|
|
243
|
+
fi
|
|
244
|
+
done
|
|
245
|
+
env:
|
|
246
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Framework Compatibility Matrix
|
|
2
|
+
# Tests the SDK against multiple versions of every supported LLM framework.
|
|
3
|
+
# Results are published as workflow summary + auto-update README badges/table.
|
|
4
|
+
name: Framework Compatibility
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
schedule:
|
|
8
|
+
- cron: '0 6 * * *' # Daily 6am UTC
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
push:
|
|
11
|
+
branches: [main]
|
|
12
|
+
paths:
|
|
13
|
+
- 'src/fingerprint.ts'
|
|
14
|
+
- 'src/llmDetector.ts'
|
|
15
|
+
- 'tests/compat/**'
|
|
16
|
+
- '.github/workflows/framework-compat.yml'
|
|
17
|
+
pull_request:
|
|
18
|
+
branches: [main]
|
|
19
|
+
paths:
|
|
20
|
+
- 'src/fingerprint.ts'
|
|
21
|
+
- 'src/llmDetector.ts'
|
|
22
|
+
- 'tests/compat/**'
|
|
23
|
+
|
|
24
|
+
jobs:
|
|
25
|
+
compat-test:
|
|
26
|
+
name: "${{ matrix.framework }} ${{ matrix.version }} (node ${{ matrix.node-version }})"
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
strategy:
|
|
29
|
+
fail-fast: false
|
|
30
|
+
matrix:
|
|
31
|
+
node-version: ['18', '20', '22']
|
|
32
|
+
include:
|
|
33
|
+
# OpenAI
|
|
34
|
+
- { framework: openai, package: openai, version: '4.0.0', test-file: openai, node-version: '18' }
|
|
35
|
+
- { framework: openai, package: openai, version: '4.0.0', test-file: openai, node-version: '20' }
|
|
36
|
+
- { framework: openai, package: openai, version: latest, test-file: openai, node-version: '18' }
|
|
37
|
+
- { framework: openai, package: openai, version: latest, test-file: openai, node-version: '20' }
|
|
38
|
+
- { framework: openai, package: openai, version: latest, test-file: openai, node-version: '22' }
|
|
39
|
+
# Anthropic
|
|
40
|
+
- { framework: anthropic, package: '@anthropic-ai/sdk', version: '0.20.0', test-file: anthropic, node-version: '18' }
|
|
41
|
+
- { framework: anthropic, package: '@anthropic-ai/sdk', version: '0.20.0', test-file: anthropic, node-version: '20' }
|
|
42
|
+
- { framework: anthropic, package: '@anthropic-ai/sdk', version: latest, test-file: anthropic, node-version: '18' }
|
|
43
|
+
- { framework: anthropic, package: '@anthropic-ai/sdk', version: latest, test-file: anthropic, node-version: '20' }
|
|
44
|
+
- { framework: anthropic, package: '@anthropic-ai/sdk', version: latest, test-file: anthropic, node-version: '22' }
|
|
45
|
+
# Google GenAI
|
|
46
|
+
- { framework: google-genai, package: '@google/generative-ai', version: '0.7.0', test-file: google-genai, node-version: '18' }
|
|
47
|
+
- { framework: google-genai, package: '@google/generative-ai', version: '0.7.0', test-file: google-genai, node-version: '20' }
|
|
48
|
+
- { framework: google-genai, package: '@google/generative-ai', version: latest, test-file: google-genai, node-version: '18' }
|
|
49
|
+
- { framework: google-genai, package: '@google/generative-ai', version: latest, test-file: google-genai, node-version: '20' }
|
|
50
|
+
- { framework: google-genai, package: '@google/generative-ai', version: latest, test-file: google-genai, node-version: '22' }
|
|
51
|
+
# LangChain
|
|
52
|
+
- { framework: langchain, package: '@langchain/core', version: '0.1.0', test-file: langchain, node-version: '18' }
|
|
53
|
+
- { framework: langchain, package: '@langchain/core', version: '0.1.0', test-file: langchain, node-version: '20' }
|
|
54
|
+
- { framework: langchain, package: '@langchain/core', version: latest, test-file: langchain, node-version: '18' }
|
|
55
|
+
- { framework: langchain, package: '@langchain/core', version: latest, test-file: langchain, node-version: '20' }
|
|
56
|
+
- { framework: langchain, package: '@langchain/core', version: latest, test-file: langchain, node-version: '22' }
|
|
57
|
+
# LangChain-OpenAI
|
|
58
|
+
- { framework: langchain-openai, package: '@langchain/openai', version: '0.0.14', test-file: langchain-openai, node-version: '18' }
|
|
59
|
+
- { framework: langchain-openai, package: '@langchain/openai', version: '0.0.14', test-file: langchain-openai, node-version: '20' }
|
|
60
|
+
- { framework: langchain-openai, package: '@langchain/openai', version: latest, test-file: langchain-openai, node-version: '18' }
|
|
61
|
+
- { framework: langchain-openai, package: '@langchain/openai', version: latest, test-file: langchain-openai, node-version: '20' }
|
|
62
|
+
- { framework: langchain-openai, package: '@langchain/openai', version: latest, test-file: langchain-openai, node-version: '22' }
|
|
63
|
+
# Vercel AI SDK
|
|
64
|
+
- { framework: vercel-ai, package: ai, version: '3.0.0', test-file: vercel-ai, node-version: '18' }
|
|
65
|
+
- { framework: vercel-ai, package: ai, version: '3.0.0', test-file: vercel-ai, node-version: '20' }
|
|
66
|
+
- { framework: vercel-ai, package: ai, version: latest, test-file: vercel-ai, node-version: '18' }
|
|
67
|
+
- { framework: vercel-ai, package: ai, version: latest, test-file: vercel-ai, node-version: '20' }
|
|
68
|
+
- { framework: vercel-ai, package: ai, version: latest, test-file: vercel-ai, node-version: '22' }
|
|
69
|
+
# Cohere
|
|
70
|
+
- { framework: cohere, package: cohere-ai, version: '7.0.0', test-file: cohere, node-version: '18' }
|
|
71
|
+
- { framework: cohere, package: cohere-ai, version: '7.0.0', test-file: cohere, node-version: '20' }
|
|
72
|
+
- { framework: cohere, package: cohere-ai, version: latest, test-file: cohere, node-version: '18' }
|
|
73
|
+
- { framework: cohere, package: cohere-ai, version: latest, test-file: cohere, node-version: '20' }
|
|
74
|
+
- { framework: cohere, package: cohere-ai, version: latest, test-file: cohere, node-version: '22' }
|
|
75
|
+
# Mistral
|
|
76
|
+
- { framework: mistral, package: '@mistralai/mistralai', version: '0.1.0', test-file: mistral, node-version: '18' }
|
|
77
|
+
- { framework: mistral, package: '@mistralai/mistralai', version: '0.1.0', test-file: mistral, node-version: '20' }
|
|
78
|
+
- { framework: mistral, package: '@mistralai/mistralai', version: latest, test-file: mistral, node-version: '18' }
|
|
79
|
+
- { framework: mistral, package: '@mistralai/mistralai', version: latest, test-file: mistral, node-version: '20' }
|
|
80
|
+
- { framework: mistral, package: '@mistralai/mistralai', version: latest, test-file: mistral, node-version: '22' }
|
|
81
|
+
|
|
82
|
+
steps:
|
|
83
|
+
- uses: actions/checkout@v4
|
|
84
|
+
|
|
85
|
+
- name: Set up Node.js ${{ matrix.node-version }}
|
|
86
|
+
uses: actions/setup-node@v4
|
|
87
|
+
with:
|
|
88
|
+
node-version: ${{ matrix.node-version }}
|
|
89
|
+
|
|
90
|
+
- name: Install SDK
|
|
91
|
+
run: npm install
|
|
92
|
+
|
|
93
|
+
- name: Install framework
|
|
94
|
+
run: |
|
|
95
|
+
if [ "${{ matrix.version }}" = "latest" ]; then
|
|
96
|
+
npm install "${{ matrix.package }}"
|
|
97
|
+
else
|
|
98
|
+
npm install "${{ matrix.package }}@${{ matrix.version }}"
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
- name: Get installed version
|
|
102
|
+
id: fwver
|
|
103
|
+
run: |
|
|
104
|
+
VER=$(npm list "${{ matrix.package }}" --depth=0 --json 2>/dev/null | node -e "const d=require('fs').readFileSync('/dev/stdin','utf8');const j=JSON.parse(d);const deps={...j.dependencies,...j.devDependencies};const pkg='${{ matrix.package }}';console.log(deps[pkg]?.version||'unknown')")
|
|
105
|
+
echo "installed_version=$VER" >> "$GITHUB_OUTPUT"
|
|
106
|
+
|
|
107
|
+
- name: Run compat tests
|
|
108
|
+
id: test
|
|
109
|
+
run: |
|
|
110
|
+
npx vitest run tests/compat/${{ matrix.test-file }}.test.ts --reporter=verbose 2>&1 | tee test-output.txt
|
|
111
|
+
echo "exit_code=${PIPESTATUS[0]}" >> "$GITHUB_OUTPUT"
|
|
112
|
+
|
|
113
|
+
- name: Write result
|
|
114
|
+
if: always()
|
|
115
|
+
run: |
|
|
116
|
+
mkdir -p results
|
|
117
|
+
cat > results/${{ matrix.framework }}-${{ matrix.version }}-node${{ matrix.node-version }}.json <<RESEOF
|
|
118
|
+
{
|
|
119
|
+
"framework": "${{ matrix.framework }}",
|
|
120
|
+
"package": "${{ matrix.package }}",
|
|
121
|
+
"requested_version": "${{ matrix.version }}",
|
|
122
|
+
"installed_version": "${{ steps.fwver.outputs.installed_version }}",
|
|
123
|
+
"node_version": "${{ matrix.node-version }}",
|
|
124
|
+
"passed": ${{ steps.test.outcome == 'success' }}
|
|
125
|
+
}
|
|
126
|
+
RESEOF
|
|
127
|
+
|
|
128
|
+
- name: Upload result
|
|
129
|
+
if: always()
|
|
130
|
+
uses: actions/upload-artifact@v4
|
|
131
|
+
with:
|
|
132
|
+
name: compat-${{ matrix.framework }}-${{ matrix.version }}-node${{ matrix.node-version }}
|
|
133
|
+
path: results/
|
|
134
|
+
retention-days: 7
|
|
135
|
+
|
|
136
|
+
update-readme:
|
|
137
|
+
name: Update README
|
|
138
|
+
needs: [compat-test]
|
|
139
|
+
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
|
|
140
|
+
runs-on: ubuntu-latest
|
|
141
|
+
permissions:
|
|
142
|
+
contents: write
|
|
143
|
+
steps:
|
|
144
|
+
- uses: actions/checkout@v4
|
|
145
|
+
|
|
146
|
+
- name: Download all results
|
|
147
|
+
uses: actions/download-artifact@v4
|
|
148
|
+
with:
|
|
149
|
+
pattern: compat-*
|
|
150
|
+
path: all-results/
|
|
151
|
+
merge-multiple: true
|
|
152
|
+
|
|
153
|
+
- name: Set up Node.js
|
|
154
|
+
uses: actions/setup-node@v4
|
|
155
|
+
with:
|
|
156
|
+
node-version: '20'
|
|
157
|
+
|
|
158
|
+
- name: Generate README sections
|
|
159
|
+
run: node scripts/update-readme-compat.mjs all-results/ README.md
|
|
160
|
+
|
|
161
|
+
- name: Commit if changed
|
|
162
|
+
run: |
|
|
163
|
+
git diff --quiet README.md || {
|
|
164
|
+
git config user.name "github-actions[bot]"
|
|
165
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
166
|
+
git add README.md
|
|
167
|
+
git commit -m "docs: update framework compatibility matrix [skip ci]"
|
|
168
|
+
git push
|
|
169
|
+
}
|