forkit-connect 0.1.31 → 0.1.33

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/README.md CHANGED
@@ -123,7 +123,7 @@ Then install the generated tarball into a clean directory:
123
123
  mkdir -p /tmp/forkit-connect-smoke
124
124
  cd /tmp/forkit-connect-smoke
125
125
  npm init -y
126
- npm install /absolute/path/to/forkit-connect-0.1.24.tgz
126
+ npm install /absolute/path/to/forkit-connect-<version>.tgz
127
127
  npx forkit-connect --help
128
128
  npx forkit-connect status
129
129
  npx forkit-connect inbox
@@ -137,9 +137,25 @@ function listBoundBindings(state) {
137
137
  if (!Array.isArray(state.model_bindings)) {
138
138
  return [];
139
139
  }
140
+ const detectedModelKeys = new Set(state.detected_models.map((item) => `${item.model}#${item.digest}`));
141
+ const scoreBinding = (binding) => {
142
+ let score = 0;
143
+ if (detectedModelKeys.has(binding.modelKey))
144
+ score += 4;
145
+ if (binding.runtimeGaid)
146
+ score += 2;
147
+ if (binding.runtimeSignalKeyPresent)
148
+ score += 1;
149
+ return score;
150
+ };
140
151
  return state.model_bindings
141
152
  .filter((item) => item.status === 'bound' && typeof item.gaid === 'string' && item.gaid.trim())
142
- .sort((left, right) => String(right.updatedAt || '').localeCompare(String(left.updatedAt || '')))
153
+ .sort((left, right) => {
154
+ const scoreDelta = scoreBinding(right) - scoreBinding(left);
155
+ if (scoreDelta !== 0)
156
+ return scoreDelta;
157
+ return String(right.updatedAt || '').localeCompare(String(left.updatedAt || ''));
158
+ })
143
159
  .map((binding) => ({
144
160
  binding,
145
161
  detectedModel: state.detected_models.find((item) => `${item.model}#${item.digest}` === binding.modelKey),
@@ -309,7 +309,8 @@ function canonicalJson(value) {
309
309
  return JSON.stringify(canonicalize(value));
310
310
  }
311
311
  function modelNameFromKey(modelKeyValue) {
312
- return String(modelKeyValue || '').split('#')[0]?.trim() || 'unknown';
312
+ const rawName = String(modelKeyValue || '').split('#')[0]?.trim() || 'unknown';
313
+ return rawName.startsWith('model:') ? rawName.slice('model:'.length) : rawName;
313
314
  }
314
315
  function modelDigestFromKey(modelKeyValue) {
315
316
  const digest = String(modelKeyValue || '').split('#')[1]?.trim() || '';
@@ -2832,7 +2833,26 @@ class ConnectV1Service {
2832
2833
  };
2833
2834
  }
2834
2835
  getPrimaryBoundBinding(state) {
2835
- return state.model_bindings.find((binding) => binding.status === 'bound' && typeof binding.gaid === 'string' && binding.gaid.trim());
2836
+ const detectedModelKeys = new Set(state.detected_models.map((item) => `${item.model}#${item.digest}`));
2837
+ const scoreBinding = (binding) => {
2838
+ let score = 0;
2839
+ if (detectedModelKeys.has(binding.modelKey))
2840
+ score += 4;
2841
+ if (binding.runtimeGaid)
2842
+ score += 2;
2843
+ if (binding.runtimeSignalKeyPresent)
2844
+ score += 1;
2845
+ return score;
2846
+ };
2847
+ return state.model_bindings
2848
+ .filter((binding) => binding.status === 'bound' && typeof binding.gaid === 'string' && binding.gaid.trim())
2849
+ .sort((left, right) => {
2850
+ const scoreDelta = scoreBinding(right) - scoreBinding(left);
2851
+ if (scoreDelta !== 0)
2852
+ return scoreDelta;
2853
+ return String(right.updatedAt || '').localeCompare(String(left.updatedAt || ''));
2854
+ })
2855
+ .at(0);
2836
2856
  }
2837
2857
  setRuntimeSignalApiKeyForGaid(gaid, apiKey) {
2838
2858
  if (!gaid || !apiKey)
@@ -3240,7 +3260,8 @@ class ConnectV1Service {
3240
3260
  const { workspaceId, projectId } = this.resolveRuntimeRunScope(state, gaid);
3241
3261
  const runtimeMetadata = isRecord(input.metadata) ? input.metadata : {};
3242
3262
  const steps = Array.isArray(input.steps) ? input.steps.filter((step) => isRecord(step)) : [];
3243
- return this.getApiClient(state).pushRuntimeRunLog({
3263
+ const client = this.getApiClientWithSessionToken(apiKey);
3264
+ return client.pushRuntimeRunLog({
3244
3265
  gaid,
3245
3266
  apiKey,
3246
3267
  schemaVersion: 'runtime.run.v1',
@@ -7080,6 +7101,7 @@ class ConnectV1Service {
7080
7101
  // Don't consume a retry_count increment here — this is a throttle, not a real failure.
7081
7102
  return;
7082
7103
  }
7104
+ attempted += 1;
7083
7105
  if (!event.passport_gaid) {
7084
7106
  if (event.event_type === 'connect_runtime_unavailable') {
7085
7107
  this.stateStore.discardC2Event(event.event_id, 'c2_local_only_runtime_unavailable');
@@ -7169,14 +7191,39 @@ class ConnectV1Service {
7169
7191
  }
7170
7192
  }
7171
7193
  const queuedEvents = dedupedEvents.slice(0, C2_SYNC_BATCH_SIZE);
7172
- attempted = queuedEvents.length;
7173
- for (let i = 0; i < queuedEvents.length; i += C2_FLUSH_CONCURRENCY) {
7174
- // Stop sending once rate-limited for this cycle.
7194
+ const eventsByPassport = new Map();
7195
+ for (const event of queuedEvents) {
7196
+ const groupKey = event.passport_gaid
7197
+ ? `passport:${event.passport_gaid}`
7198
+ : `event:${event.event_id}`;
7199
+ const group = eventsByPassport.get(groupKey) ?? [];
7200
+ group.push(event);
7201
+ eventsByPassport.set(groupKey, group);
7202
+ }
7203
+ // Keep throughput across independent passports, but process each passport
7204
+ // sequentially so a credential/governor halt leaves later events untouched.
7205
+ while (eventsByPassport.size > 0) {
7175
7206
  if (rateLimitedUntilMs !== null && Date.now() < rateLimitedUntilMs) {
7176
7207
  break;
7177
7208
  }
7178
- const chunk = queuedEvents.slice(i, i + C2_FLUSH_CONCURRENCY);
7179
- await Promise.all(chunk.map(processSingleEvent));
7209
+ const round = [];
7210
+ for (const key of [...eventsByPassport.keys()]) {
7211
+ const group = eventsByPassport.get(key);
7212
+ const event = group?.shift();
7213
+ if (event) {
7214
+ round.push(event);
7215
+ }
7216
+ if (!group || group.length === 0) {
7217
+ eventsByPassport.delete(key);
7218
+ }
7219
+ }
7220
+ for (let i = 0; i < round.length; i += C2_FLUSH_CONCURRENCY) {
7221
+ if (rateLimitedUntilMs !== null && Date.now() < rateLimitedUntilMs) {
7222
+ break;
7223
+ }
7224
+ const chunk = round.slice(i, i + C2_FLUSH_CONCURRENCY);
7225
+ await Promise.all(chunk.map(processSingleEvent));
7226
+ }
7180
7227
  }
7181
7228
  const lastSyncAt = attempted > 0 ? nowIso() : state.last_c2_sync_at;
7182
7229
  const lastSyncError = firstError;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forkit-connect",
3
- "version": "0.1.31",
3
+ "version": "0.1.33",
4
4
  "description": "Forkit Connect Local Engine - The Global AI Governance Fabric",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -34,7 +34,6 @@
34
34
  "cors": "^2.8.6",
35
35
  "express": "^4.19.2",
36
36
  "ps-list": "^8.1.1",
37
- "uuid": "^10.0.0",
38
37
  "ws": "^8.16.0",
39
38
  "zod": "^3.22.0"
40
39
  },
@@ -43,7 +42,6 @@
43
42
  "@types/cors": "^2.8.19",
44
43
  "@types/express": "^4.17.21",
45
44
  "@types/node": "^20.0.0",
46
- "@types/uuid": "^10.0.0",
47
45
  "@types/ws": "^8.5.10",
48
46
  "typescript": "^5.0.0"
49
47
  },