all-the-public-replicate-models 1.347.0 → 1.349.0

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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "all-the-public-replicate-models",
3
3
  "description": "Metadata for all the public models on Replicate, bundled up into an npm package",
4
4
  "repository": "https://github.com/replicate/all-the-public-replicate-models",
5
- "version": "1.347.0",
5
+ "version": "1.349.0",
6
6
  "devDependencies": {
7
7
  "chai": "^4.3.10",
8
8
  "lodash-es": "^4.17.21",
@@ -13,10 +13,11 @@
13
13
  "main": "index.mjs",
14
14
  "exports": {
15
15
  ".": "./index.mjs",
16
- "./lite": "./lite.mjs"
16
+ "./lite": "./lite.mjs",
17
+ "./stats": "./stats.mjs"
17
18
  },
18
19
  "scripts": {
19
- "build": "node script/build.js",
20
+ "build": "node script/build.js && node script/stats.js",
20
21
  "test": "mocha test.js"
21
22
  },
22
23
  "engines": {
package/script/stats.js CHANGED
@@ -1,119 +1,96 @@
1
- import { promises as fs } from 'fs';
2
- import oldModels from '../models.old.json' assert { type: "json" };
3
- import newModels from '../models.json' assert { type: "json" };
4
-
5
- async function compareAndGenerateMD() {
6
- const newModelUrls = newModels.map(model => model.url);
7
- const oldModelUrls = oldModels.map(model => model.url);
8
-
9
- const addedModels = newModels.filter(model => !oldModelUrls.includes(model.url));
10
- const removedModels = oldModels.filter(model => !newModelUrls.includes(model.url));
11
-
12
- const activeModels = newModels.map(newModel => {
13
- const oldModel = oldModels.find(m => m.url === newModel.url);
14
- const runCountDiff = oldModel ? newModel.run_count - oldModel.run_count : newModel.run_count;
15
- return { ...newModel, runCountDiff };
16
- })
17
- .filter(model => model.runCountDiff > 100)
18
- .sort((a, b) => b.runCountDiff - a.runCountDiff);
19
-
20
- const risingStars = newModels.map(model => {
21
- const oldModel = oldModels.find(m => m.url === model.url);
22
- const runCountDiff = oldModel ? model.run_count - oldModel.run_count : model.run_count;
23
- const percentageIncrease = runCountDiff / model.run_count * 100;
24
- return { ...model, runCountDiff, percentageIncrease };
25
- })
26
- .sort((a, b) => b.percentageIncrease - a.percentageIncrease)
27
- .slice(0, 50);
28
-
29
- let markdownContent = '# Model Stats\n';
30
-
31
- // New Models
32
- markdownContent += '## New Models\n';
33
- if (addedModels.length > 0) {
34
- for (let model of addedModels) {
35
- markdownContent += `- ${model.url}\n`;
36
- }
37
- } else {
38
- markdownContent += 'No new models today.\n';
39
- }
40
-
41
- // Removed Models
42
- markdownContent += '\n## Removed Models\n';
43
- if (removedModels.length > 0) {
44
- for (let model of removedModels) {
45
- markdownContent += `- ${model.url}\n`;
46
- }
47
- } else {
48
- markdownContent += 'No models were removed today.\n';
49
- }
50
-
51
- // Rising Stars
52
- markdownContent += '\n## Rising Stars\n';
53
- if (risingStars.length > 0) {
54
- markdownContent += '| Model | Description | Runs Today | Runs Total | % of Total |\n|-------|-------------|------------|------------|------------|\n';
55
- for (let model of risingStars) {
56
- const linkText = `${model.owner}/${model.name}`;
57
- const percentageDisplay = `${model.percentageIncrease.toFixed(2)}%`;
58
- markdownContent += `| [${linkText}](${model.url}) | ${model.description} | ${model.runCountDiff} | ${model.run_count} | ${percentageDisplay} |\n`;
59
- }
60
- } else {
61
- markdownContent += 'No rising stars today.\n';
62
- }
63
-
64
- // Active Models
65
- markdownContent += '\n## Active Models\n';
66
- if (activeModels.length > 0) {
67
- markdownContent += '| Model | Description | Runs in the last day |\n|-------|-------------|---------------------|\n';
68
- for (let model of activeModels) {
69
- const linkText = `${model.owner}/${model.name}`;
70
- markdownContent += `| [${linkText}](${model.url}) | ${model.description} | ${model.runCountDiff} |\n`;
71
- }
72
- } else {
73
- markdownContent += 'No active models today.\n';
74
- }
75
-
76
- // Top Model Authors
77
- markdownContent += '\n## Top Model Authors by Run Count\n';
78
- const modelsByOwner = newModels.reduce((acc, model) => {
79
- if (!acc[model.owner]) {
80
- acc[model.owner] = [];
81
- }
82
- acc[model.owner].push(model);
83
- return acc;
84
- }, {});
85
-
86
- const topAuthors = Object.entries(modelsByOwner).map(([owner, models]) => ({
87
- owner,
88
- modelCount: models.length,
89
- totalRuns: models.reduce((sum, model) => sum + model.run_count, 0),
90
- })).sort((a, b) => b.totalRuns - a.totalRuns).slice(0, 30);
91
-
92
-
93
- markdownContent += '| Author | Models | Total Runs |\n|--------|--------|------------|\n';
94
- for (const author of topAuthors) {
95
- const ownerUrl = `https://replicate.com/${author.owner}`;
96
- markdownContent += `| [${author.owner}](${ownerUrl}) | ${author.modelCount} | ${author.totalRuns} |\n`;
97
- }
98
-
99
-
100
- // Top Model Authors by Model Count
101
- markdownContent += '\n## Top Model Authors by Model Count\n';
102
- const authorsByModelCount = Object.entries(modelsByOwner).map(([owner, models]) => ({
103
- owner,
104
- modelCount: models.length,
105
- })).sort((a, b) => b.modelCount - a.modelCount).slice(0, 30);
1
+ #!/usr/bin/env node
2
+
3
+ import { exec } from 'node:child_process';
4
+ import { promisify } from 'node:util';
5
+ import fs from 'node:fs/promises';
6
+
7
+ const execAsync = promisify(exec);
8
+ const stats = {};
9
+
10
+ // Get the date 31 days ago in ISO format
11
+ const thirtyOneDaysAgo = new Date();
12
+ thirtyOneDaysAgo.setDate(thirtyOneDaysAgo.getDate() - 31);
13
+ const thirtyOneDaysAgoISO = thirtyOneDaysAgo.toISOString().split('T')[0];
14
+
15
+ // Get all commit SHAs using async exec
16
+ const { stdout: commitsOutput } = await execAsync(
17
+ `git log --reverse --since="${thirtyOneDaysAgoISO}" --format="%H"`
18
+ );
19
+ const commits = commitsOutput.trim().split('\n');
20
+
21
+ // Skip if no commits found
22
+ if (!commits[0]) {
23
+ console.log('No commits found in the last 31 days');
24
+ process.exit(0);
25
+ }
106
26
 
107
- markdownContent += '| Author | Model Count |\n|--------|-------------|\n';
108
- for (const author of authorsByModelCount) {
109
- const ownerUrl = `https://replicate.com/${author.owner}`;
110
- markdownContent += `| [${author.owner}](${ownerUrl}) | ${author.modelCount} |\n`;
27
+ // Loop through each commit, starting from the second commit (index 1)
28
+ for (const commitSha of commits) {
29
+ try {
30
+ // Get the commit message
31
+ const { stdout: commitMessage } = await execAsync(
32
+ `git log --format=%B -n 1 ${commitSha}`
33
+ );
34
+
35
+ // Bail if it's not a build artifacts commit
36
+ if (commitMessage.trim() !== 'Build artifacts') continue;
37
+
38
+ // Get the commit date
39
+ const { stdout: commitDate } = await execAsync(
40
+ `git log -n 1 --format=%ad --date=iso ${commitSha}`
41
+ );
42
+ const formattedDate = commitDate.trim().split(' ')[0];
43
+
44
+ // Instead of using git show, we'll create a temporary file
45
+ await execAsync(
46
+ `git show ${commitSha}:models-lite.json > temp-models-${commitSha}.json`
47
+ );
48
+
49
+ // Read the temporary file
50
+ const modelsJson = await fs.readFile(
51
+ `temp-models-${commitSha}.json`,
52
+ 'utf-8'
53
+ );
54
+
55
+ // Clean up temporary file
56
+ await fs.unlink(`temp-models-${commitSha}.json`);
57
+
58
+ // console.log({ commitSha, date: formattedDate });
59
+
60
+ const models = JSON.parse(modelsJson);
61
+
62
+ // Process models data
63
+ for (const model of models) {
64
+ const nwo = `${model.owner}/${model.name}`;
65
+
66
+ if (!stats[nwo]) {
67
+ stats[nwo] = [];
68
+ }
69
+
70
+ const totalRuns = model.run_count;
71
+ const dailyRuns = stats[nwo].length > 0
72
+ ? totalRuns - stats[nwo][stats[nwo].length - 1].totalRuns
73
+ : totalRuns;
74
+
75
+ const dailyStats = {
76
+ date: formattedDate,
77
+ totalRuns,
78
+ dailyRuns,
79
+ };
80
+ stats[nwo].push(dailyStats);
111
81
  }
82
+
83
+ } catch (error) {
84
+ console.error(`Error processing commit ${commitSha}:`, error.message);
85
+ }
86
+ }
112
87
 
113
- // Write to stats.md
114
- await fs.writeFile('stats.md', markdownContent);
88
+ // Remove the first element from each model's stats array,
89
+ // because the dailyRuns is not accurate for the first day
90
+ for (const nwo in stats) {
91
+ stats[nwo] = stats[nwo].slice(1);
115
92
  }
116
93
 
117
- compareAndGenerateMD().catch(error => {
118
- console.error('Error generating stats:', error);
119
- });
94
+ // Write stats to disk
95
+ await fs.writeFile('stats.json', JSON.stringify(stats, null, 2));
96
+
package/stats.json ADDED
@@ -0,0 +1 @@
1
+ {}
package/stats.mjs ADDED
@@ -0,0 +1,7 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ const __dirname = dirname(fileURLToPath(import.meta.url));
5
+ const stats = JSON.parse(await readFile(join(__dirname, 'stats.json'), 'utf8'));
6
+
7
+ export default stats;