forkit-connect 0.1.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.
Files changed (51) hide show
  1. package/QUICKSTART.md +55 -0
  2. package/README.md +96 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.js +4724 -0
  5. package/dist/index.d.ts +7 -0
  6. package/dist/index.js +21 -0
  7. package/dist/launcher.d.ts +33 -0
  8. package/dist/launcher.js +9344 -0
  9. package/dist/ps-list-loader.d.ts +5 -0
  10. package/dist/ps-list-loader.js +20 -0
  11. package/dist/v1/agent-observation.d.ts +42 -0
  12. package/dist/v1/agent-observation.js +499 -0
  13. package/dist/v1/api.d.ts +276 -0
  14. package/dist/v1/api.js +390 -0
  15. package/dist/v1/credential-store.d.ts +92 -0
  16. package/dist/v1/credential-store.js +797 -0
  17. package/dist/v1/currency.d.ts +41 -0
  18. package/dist/v1/currency.js +127 -0
  19. package/dist/v1/daemon.d.ts +50 -0
  20. package/dist/v1/daemon.js +265 -0
  21. package/dist/v1/discovery.d.ts +61 -0
  22. package/dist/v1/discovery.js +168 -0
  23. package/dist/v1/filesystem-models.d.ts +11 -0
  24. package/dist/v1/filesystem-models.js +261 -0
  25. package/dist/v1/heartbeat.d.ts +45 -0
  26. package/dist/v1/heartbeat.js +463 -0
  27. package/dist/v1/lifecycle-monitor.d.ts +78 -0
  28. package/dist/v1/lifecycle-monitor.js +512 -0
  29. package/dist/v1/lmstudio.d.ts +11 -0
  30. package/dist/v1/lmstudio.js +148 -0
  31. package/dist/v1/ollama.d.ts +19 -0
  32. package/dist/v1/ollama.js +164 -0
  33. package/dist/v1/openai-compatible.d.ts +12 -0
  34. package/dist/v1/openai-compatible.js +124 -0
  35. package/dist/v1/process-scout.d.ts +50 -0
  36. package/dist/v1/process-scout.js +715 -0
  37. package/dist/v1/providers.d.ts +50 -0
  38. package/dist/v1/providers.js +106 -0
  39. package/dist/v1/service.d.ts +680 -0
  40. package/dist/v1/service.js +8286 -0
  41. package/dist/v1/state.d.ts +87 -0
  42. package/dist/v1/state.js +1318 -0
  43. package/dist/v1/test-credential-backend.d.ts +19 -0
  44. package/dist/v1/test-credential-backend.js +49 -0
  45. package/dist/v1/types.d.ts +873 -0
  46. package/dist/v1/types.js +3 -0
  47. package/dist/v1/update.d.ts +38 -0
  48. package/dist/v1/update.js +184 -0
  49. package/dist/v1/vitality-pulse.d.ts +36 -0
  50. package/dist/v1/vitality-pulse.js +512 -0
  51. package/package.json +53 -0
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readEndpointPort = readEndpointPort;
4
+ exports.buildEndpointHash = buildEndpointHash;
5
+ exports.buildSourceEndpointLabel = buildSourceEndpointLabel;
6
+ exports.buildRuntimePassportGaid = buildRuntimePassportGaid;
7
+ exports.buildRuntimeDiscoveryHash = buildRuntimeDiscoveryHash;
8
+ exports.buildModelDiscoveryHash = buildModelDiscoveryHash;
9
+ exports.buildModelRegistrationKey = buildModelRegistrationKey;
10
+ exports.buildAgentDiscoveryHash = buildAgentDiscoveryHash;
11
+ exports.buildRuntimeAttestationFingerprint = buildRuntimeAttestationFingerprint;
12
+ exports.buildModelObservationFingerprint = buildModelObservationFingerprint;
13
+ exports.applyRuntimeDiscovery = applyRuntimeDiscovery;
14
+ exports.applyModelDiscovery = applyModelDiscovery;
15
+ const node_crypto_1 = require("node:crypto");
16
+ function stableObjectStringify(value) {
17
+ if (Array.isArray(value)) {
18
+ return `[${value.map((item) => stableObjectStringify(item)).join(',')}]`;
19
+ }
20
+ if (value && typeof value === 'object') {
21
+ const entries = Object.entries(value).sort(([left], [right]) => left.localeCompare(right));
22
+ return `{${entries.map(([key, entryValue]) => `${JSON.stringify(key)}:${stableObjectStringify(entryValue)}`).join(',')}}`;
23
+ }
24
+ return JSON.stringify(value ?? null);
25
+ }
26
+ function normalizeEndpointForIdentity(sourceEndpoint) {
27
+ try {
28
+ const url = new URL(sourceEndpoint);
29
+ const port = url.port || (url.protocol === 'https:' ? '443' : '80');
30
+ const pathname = url.pathname && url.pathname !== '/' ? url.pathname : '';
31
+ return `${url.protocol}//${url.hostname}:${port}${pathname}`;
32
+ }
33
+ catch {
34
+ return String(sourceEndpoint || '').trim();
35
+ }
36
+ }
37
+ function readEndpointPort(sourceEndpoint) {
38
+ try {
39
+ const url = new URL(sourceEndpoint);
40
+ const port = url.port || (url.protocol === 'https:' ? '443' : '80');
41
+ const parsed = Number.parseInt(port, 10);
42
+ return Number.isFinite(parsed) ? parsed : null;
43
+ }
44
+ catch {
45
+ return null;
46
+ }
47
+ }
48
+ function buildEndpointHash(sourceEndpoint) {
49
+ const normalized = normalizeEndpointForIdentity(sourceEndpoint);
50
+ return (0, node_crypto_1.createHash)('sha256').update(normalized, 'utf8').digest('hex');
51
+ }
52
+ function buildSourceEndpointLabel(sourceEndpoint) {
53
+ if (sourceEndpoint.startsWith('local://filesystem')) {
54
+ return 'local-model-files';
55
+ }
56
+ try {
57
+ const url = new URL(sourceEndpoint);
58
+ const port = url.port || (url.protocol === 'https:' ? '443' : '80');
59
+ return `${url.hostname}:${port}`;
60
+ }
61
+ catch {
62
+ return 'local-runtime-endpoint';
63
+ }
64
+ }
65
+ function buildRuntimePassportGaid(input) {
66
+ const stablePayload = stableObjectStringify({
67
+ connect_device_id: input.connectDeviceId,
68
+ runtime_name: input.runtimeName,
69
+ runtime_type: input.runtimeType,
70
+ provider: input.provider,
71
+ endpoint_hash: input.endpointHash,
72
+ });
73
+ return `runtime:${(0, node_crypto_1.createHash)('sha256').update(stablePayload, 'utf8').digest('hex').slice(0, 32)}`;
74
+ }
75
+ function buildRuntimeDiscoveryHash(input) {
76
+ const stablePayload = stableObjectStringify({
77
+ runtime_name: input.runtimeName,
78
+ runtime_type: input.runtimeType,
79
+ source_endpoint: input.sourceEndpoint,
80
+ runtime_identity: input.runtimeIdentity,
81
+ });
82
+ return (0, node_crypto_1.createHash)('sha256').update(stablePayload, 'utf8').digest('hex');
83
+ }
84
+ function buildModelDiscoveryHash(input) {
85
+ const stablePayload = stableObjectStringify({
86
+ runtime_name: input.runtimeName,
87
+ runtime_type: input.runtimeType,
88
+ model_name: input.modelName,
89
+ model_id: input.modelId,
90
+ source_endpoint: input.sourceEndpoint,
91
+ runtime_identity: input.runtimeIdentity,
92
+ });
93
+ return (0, node_crypto_1.createHash)('sha256').update(stablePayload, 'utf8').digest('hex');
94
+ }
95
+ function buildModelRegistrationKey(model, runtimeIdentity) {
96
+ const stablePayload = stableObjectStringify({
97
+ model_name: model.model,
98
+ model_id: model.modelId ?? null,
99
+ runtime_identity: runtimeIdentity,
100
+ });
101
+ return (0, node_crypto_1.createHash)('sha256').update(stablePayload, 'utf8').digest('hex');
102
+ }
103
+ function buildAgentDiscoveryHash(input) {
104
+ const stablePayload = stableObjectStringify({
105
+ agent_name: input.agentName,
106
+ agent_type: input.agentType,
107
+ process_signature_hash: input.processSignatureHash,
108
+ runtime_identity: input.runtimeIdentity,
109
+ });
110
+ return (0, node_crypto_1.createHash)('sha256').update(stablePayload, 'utf8').digest('hex');
111
+ }
112
+ function buildRuntimeAttestationFingerprint(input) {
113
+ const stablePayload = stableObjectStringify({
114
+ runtime_name: input.runtimeName,
115
+ runtime_type: input.runtimeType,
116
+ runtime_provider: input.runtimeProvider,
117
+ endpoint_hash: input.endpointHash,
118
+ runtime_identity: input.runtimeIdentity,
119
+ process_signature: input.processSignature,
120
+ process_command_hash: input.processCommandHash,
121
+ process_path_hash: input.processPathHash,
122
+ detection_mode: input.detectionMode,
123
+ source_label: input.sourceLabel,
124
+ matched_terms: [...new Set(input.matchedTerms.filter(Boolean))].sort((left, right) => left.localeCompare(right)),
125
+ expected_ports: [...new Set(input.expectedPorts.filter((port) => Number.isFinite(port) && port > 0))].sort((left, right) => left - right),
126
+ });
127
+ return (0, node_crypto_1.createHash)('sha256').update(stablePayload, 'utf8').digest('hex');
128
+ }
129
+ function buildModelObservationFingerprint(input) {
130
+ const stablePayload = stableObjectStringify({
131
+ runtime_name: input.runtimeName,
132
+ runtime_type: input.runtimeType,
133
+ model_name: input.modelName,
134
+ model_id: input.modelId,
135
+ digest: input.digest,
136
+ size_bytes: input.sizeBytes,
137
+ modified_at: input.modifiedAt,
138
+ metadata_fingerprint: input.metadataFingerprint,
139
+ });
140
+ return (0, node_crypto_1.createHash)('sha256').update(stablePayload, 'utf8').digest('hex');
141
+ }
142
+ function applyRuntimeDiscovery(runtime, runtimeIdentity, sources = ['provider_scan']) {
143
+ return {
144
+ ...runtime,
145
+ discoveryHash: buildRuntimeDiscoveryHash({
146
+ runtimeName: runtime.runtimeName,
147
+ runtimeType: runtime.runtimeType,
148
+ sourceEndpoint: runtime.endpoint,
149
+ runtimeIdentity,
150
+ }),
151
+ discoverySources: [...new Set(sources)],
152
+ };
153
+ }
154
+ function applyModelDiscovery(model, runtimeIdentity, sources = ['provider_scan']) {
155
+ return {
156
+ ...model,
157
+ discoveryHash: buildModelDiscoveryHash({
158
+ runtimeName: model.runtimeName,
159
+ runtimeType: model.runtimeType,
160
+ modelName: model.model,
161
+ modelId: model.modelId,
162
+ sourceEndpoint: model.sourceEndpoint,
163
+ runtimeIdentity,
164
+ }),
165
+ discoverySources: [...new Set(sources)],
166
+ };
167
+ }
168
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1,11 @@
1
+ import { type RuntimeProvider, type RuntimeProviderScanResult } from './providers';
2
+ export declare class FilesystemModelProvider implements RuntimeProvider {
3
+ private readonly roots;
4
+ readonly runtimeName = "local-model-files";
5
+ readonly runtimeType: "local-filesystem";
6
+ readonly endpoint = "local://filesystem";
7
+ constructor(roots: string[]);
8
+ scan(): Promise<RuntimeProviderScanResult>;
9
+ }
10
+ export declare function createDefaultFilesystemModelProviders(): FilesystemModelProvider[];
11
+ //# sourceMappingURL=filesystem-models.d.ts.map
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FilesystemModelProvider = void 0;
7
+ exports.createDefaultFilesystemModelProviders = createDefaultFilesystemModelProviders;
8
+ const promises_1 = __importDefault(require("node:fs/promises"));
9
+ const node_os_1 = __importDefault(require("node:os"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const node_crypto_1 = require("node:crypto");
12
+ const providers_1 = require("./providers");
13
+ const DEFAULT_MAX_SCAN_DEPTH = 6;
14
+ const DEFAULT_MAX_MODELS = 250;
15
+ const DEFAULT_MIN_MODEL_BYTES = 8 * 1024 * 1024;
16
+ const MODEL_FILE_EXTENSIONS = new Set([
17
+ '.gguf',
18
+ '.ggml',
19
+ '.safetensors',
20
+ '.onnx',
21
+ '.pt',
22
+ '.pth',
23
+ '.bin',
24
+ ]);
25
+ function expandHomeDir(input) {
26
+ if (!input.startsWith('~/'))
27
+ return input;
28
+ return node_path_1.default.join(node_os_1.default.homedir(), input.slice(2));
29
+ }
30
+ function normalizeConfiguredDir(value) {
31
+ const trimmed = expandHomeDir(String(value || '').trim());
32
+ return trimmed ? node_path_1.default.resolve(trimmed) : null;
33
+ }
34
+ function getDefaultFilesystemModelDirs() {
35
+ const home = node_os_1.default.homedir();
36
+ const candidates = [
37
+ process.env.FORKIT_LOCAL_MODEL_SCAN_DIRS,
38
+ node_path_1.default.join(home, '.cache', 'huggingface', 'hub'),
39
+ process.env.HF_HOME ? node_path_1.default.join(process.env.HF_HOME, 'hub') : null,
40
+ node_path_1.default.join(home, '.cache', 'lm-studio', 'models'),
41
+ node_path_1.default.join(home, '.lmstudio', 'models'),
42
+ node_path_1.default.join(home, 'models'),
43
+ node_path_1.default.join(home, 'model'),
44
+ node_path_1.default.join(home, 'ai', 'models'),
45
+ node_path_1.default.join(home, '.cache', 'mlx-models'),
46
+ ].filter((value) => Boolean(value));
47
+ const seen = new Set();
48
+ const directories = [];
49
+ for (const candidateGroup of candidates) {
50
+ const values = String(candidateGroup)
51
+ .split(/[\n,]/)
52
+ .map((entry) => normalizeConfiguredDir(entry))
53
+ .filter((entry) => Boolean(entry));
54
+ for (const value of values) {
55
+ if (seen.has(value))
56
+ continue;
57
+ seen.add(value);
58
+ directories.push(value);
59
+ }
60
+ }
61
+ return directories;
62
+ }
63
+ async function pathExists(targetPath) {
64
+ try {
65
+ await promises_1.default.access(targetPath);
66
+ return true;
67
+ }
68
+ catch {
69
+ return false;
70
+ }
71
+ }
72
+ function isGenericModelBasename(name) {
73
+ return ['model', 'pytorch_model', 'consolidated', 'weights', 'adapter_model'].includes(name.toLowerCase());
74
+ }
75
+ function stripModelExtension(filename) {
76
+ const extension = node_path_1.default.extname(filename);
77
+ return extension ? filename.slice(0, -extension.length) : filename;
78
+ }
79
+ function makeRelativeHint(filePath, rootDir) {
80
+ const relative = node_path_1.default.relative(rootDir, filePath);
81
+ const parts = relative.split(node_path_1.default.sep).filter(Boolean);
82
+ return parts.slice(-4).join('/');
83
+ }
84
+ function deriveHuggingFaceModelName(filePath) {
85
+ const normalized = filePath.split(node_path_1.default.sep);
86
+ const repoMarker = normalized.find((part) => part.startsWith('models--'));
87
+ if (!repoMarker)
88
+ return null;
89
+ const repoName = repoMarker.replace(/^models--/, '').replaceAll('--', '/');
90
+ return repoName || null;
91
+ }
92
+ function deriveModelName(filePath, rootDir) {
93
+ const huggingFaceName = deriveHuggingFaceModelName(filePath);
94
+ if (huggingFaceName) {
95
+ return { modelName: huggingFaceName, sourceKind: 'huggingface-cache' };
96
+ }
97
+ const parsed = node_path_1.default.parse(filePath);
98
+ const baseName = stripModelExtension(parsed.base);
99
+ if (!isGenericModelBasename(baseName)) {
100
+ return { modelName: baseName, sourceKind: 'local-model-dir' };
101
+ }
102
+ const relativeDir = node_path_1.default.relative(rootDir, parsed.dir).split(node_path_1.default.sep).filter(Boolean);
103
+ const parentName = relativeDir.at(-1) || baseName;
104
+ return { modelName: parentName, sourceKind: 'local-model-dir' };
105
+ }
106
+ function buildSyntheticDigest(input) {
107
+ return (0, node_crypto_1.createHash)('sha256').update(input, 'utf8').digest('hex');
108
+ }
109
+ async function collectModelFiles(rootDir, currentDir, depth, found) {
110
+ if (depth > DEFAULT_MAX_SCAN_DEPTH || found.length >= DEFAULT_MAX_MODELS) {
111
+ return;
112
+ }
113
+ let entries;
114
+ try {
115
+ entries = await promises_1.default.readdir(currentDir, { withFileTypes: true, encoding: 'utf8' });
116
+ }
117
+ catch {
118
+ return;
119
+ }
120
+ for (const entry of entries) {
121
+ if (found.length >= DEFAULT_MAX_MODELS) {
122
+ return;
123
+ }
124
+ const fullPath = node_path_1.default.join(currentDir, entry.name);
125
+ if (fullPath.includes(`${node_path_1.default.sep}.no_exist${node_path_1.default.sep}`)) {
126
+ continue;
127
+ }
128
+ if (entry.isDirectory()) {
129
+ await collectModelFiles(rootDir, fullPath, depth + 1, found);
130
+ continue;
131
+ }
132
+ if (!entry.isFile() && !entry.isSymbolicLink()) {
133
+ continue;
134
+ }
135
+ const extension = node_path_1.default.extname(entry.name).toLowerCase();
136
+ if (!MODEL_FILE_EXTENSIONS.has(extension)) {
137
+ continue;
138
+ }
139
+ let stats;
140
+ try {
141
+ stats = await promises_1.default.stat(fullPath);
142
+ }
143
+ catch {
144
+ continue;
145
+ }
146
+ if (!stats.isFile()) {
147
+ continue;
148
+ }
149
+ if (stats.size < DEFAULT_MIN_MODEL_BYTES) {
150
+ continue;
151
+ }
152
+ const { modelName, sourceKind } = deriveModelName(fullPath, rootDir);
153
+ const relativeHint = makeRelativeHint(fullPath, rootDir);
154
+ found.push({
155
+ modelName,
156
+ modelId: `${modelName}#${relativeHint}`,
157
+ totalSizeBytes: stats.size,
158
+ modifiedAt: Number.isFinite(stats.mtimeMs) ? new Date(stats.mtimeMs).toISOString() : null,
159
+ fileExtension: extension,
160
+ rootDir,
161
+ relativeHint,
162
+ sourceKind,
163
+ });
164
+ }
165
+ }
166
+ function collapseFilesystemCandidates(candidates) {
167
+ const grouped = new Map();
168
+ for (const candidate of candidates) {
169
+ const key = `${candidate.sourceKind}#${candidate.modelName}`;
170
+ const existing = grouped.get(key);
171
+ if (!existing) {
172
+ grouped.set(key, candidate);
173
+ continue;
174
+ }
175
+ grouped.set(key, {
176
+ ...existing,
177
+ totalSizeBytes: existing.totalSizeBytes + candidate.totalSizeBytes,
178
+ modifiedAt: [existing.modifiedAt, candidate.modifiedAt].filter(Boolean).sort().at(-1) ?? existing.modifiedAt,
179
+ relativeHint: existing.relativeHint.length >= candidate.relativeHint.length ? existing.relativeHint : candidate.relativeHint,
180
+ });
181
+ }
182
+ return [...grouped.values()].sort((left, right) => right.totalSizeBytes - left.totalSizeBytes || left.modelName.localeCompare(right.modelName));
183
+ }
184
+ class FilesystemModelProvider {
185
+ roots;
186
+ runtimeName = 'local-model-files';
187
+ runtimeType = 'local-filesystem';
188
+ endpoint = 'local://filesystem';
189
+ constructor(roots) {
190
+ this.roots = roots;
191
+ }
192
+ async scan() {
193
+ const now = new Date().toISOString();
194
+ const existingRoots = [];
195
+ for (const root of this.roots) {
196
+ if (await pathExists(root)) {
197
+ existingRoots.push(root);
198
+ }
199
+ }
200
+ if (existingRoots.length === 0) {
201
+ return {
202
+ ok: false,
203
+ runtime: (0, providers_1.buildDetectedRuntime)({
204
+ runtimeName: this.runtimeName,
205
+ runtimeType: this.runtimeType,
206
+ endpoint: this.endpoint,
207
+ status: 'error',
208
+ lastSeenAt: now,
209
+ error: 'no_model_directories_found',
210
+ }),
211
+ models: [],
212
+ error: 'no_model_directories_found',
213
+ };
214
+ }
215
+ const rawCandidates = [];
216
+ for (const root of existingRoots) {
217
+ await collectModelFiles(root, root, 0, rawCandidates);
218
+ }
219
+ const models = collapseFilesystemCandidates(rawCandidates)
220
+ .slice(0, DEFAULT_MAX_MODELS)
221
+ .map((candidate) => (0, providers_1.normalizeDetectedModel)({
222
+ runtimeName: this.runtimeName,
223
+ runtimeType: this.runtimeType,
224
+ modelName: candidate.modelName,
225
+ modelId: candidate.modelId,
226
+ sourceEndpoint: this.endpoint,
227
+ detectedAt: now,
228
+ digest: buildSyntheticDigest(`${candidate.modelName}|${candidate.relativeHint}|${candidate.totalSizeBytes}|${candidate.modifiedAt || ''}`),
229
+ sizeBytes: candidate.totalSizeBytes,
230
+ modifiedAt: candidate.modifiedAt,
231
+ sourceLabel: 'Verified by Integration',
232
+ metadata: {
233
+ inventory_source: 'filesystem_scan',
234
+ source_kind: candidate.sourceKind,
235
+ root_label: node_path_1.default.basename(candidate.rootDir) || 'model-root',
236
+ relative_path_hint: candidate.relativeHint,
237
+ file_extension: candidate.fileExtension,
238
+ },
239
+ }));
240
+ return {
241
+ ok: models.length > 0,
242
+ runtime: (0, providers_1.buildDetectedRuntime)({
243
+ runtimeName: this.runtimeName,
244
+ runtimeType: this.runtimeType,
245
+ endpoint: this.endpoint,
246
+ status: models.length > 0 ? 'detected' : 'error',
247
+ lastSeenAt: now,
248
+ error: models.length > 0 ? null : 'no_model_files_found',
249
+ sourceLabel: 'Verified by Integration',
250
+ }),
251
+ models,
252
+ error: models.length > 0 ? null : 'no_model_files_found',
253
+ };
254
+ }
255
+ }
256
+ exports.FilesystemModelProvider = FilesystemModelProvider;
257
+ function createDefaultFilesystemModelProviders() {
258
+ const roots = getDefaultFilesystemModelDirs();
259
+ return roots.length > 0 ? [new FilesystemModelProvider(roots)] : [];
260
+ }
261
+ //# sourceMappingURL=filesystem-models.js.map
@@ -0,0 +1,45 @@
1
+ import { ConnectV1Service } from './service';
2
+ import type { ConnectState, DetectedModel, ModelBinding } from './types';
3
+ export interface BoundBindingSelection {
4
+ binding: ModelBinding;
5
+ detectedModel: DetectedModel | undefined;
6
+ }
7
+ export interface HeartbeatSuccess {
8
+ ok: true;
9
+ gaid: string;
10
+ modelName: string;
11
+ sessionId: string;
12
+ lastCheckinAt: string | null;
13
+ }
14
+ export interface HeartbeatFailure {
15
+ ok: false;
16
+ code: 'not_authenticated' | 'missing_binding' | 'missing_model' | 'passport_inaccessible' | 'governor_paused' | 'access_revoked' | 'credential_reconnect_needed' | 'binding_paused' | 'binding_stale' | 'binding_reconsent_required' | 'heartbeat_failed';
17
+ message: string;
18
+ status?: number;
19
+ details?: unknown;
20
+ }
21
+ export type HeartbeatResult = HeartbeatSuccess | HeartbeatFailure;
22
+ export interface HeartbeatBatchEntry {
23
+ gaid: string;
24
+ modelName: string;
25
+ runtimeSignalQueueId: string | null;
26
+ result: HeartbeatResult;
27
+ }
28
+ export interface HeartbeatBatchResult {
29
+ attempted: number;
30
+ succeeded: number;
31
+ failed: number;
32
+ runtimeSignalQueued: number;
33
+ results: HeartbeatBatchEntry[];
34
+ }
35
+ export declare function readBoundModelName(modelKey: string): string;
36
+ export declare function listBoundBindings(state: ConnectState): BoundBindingSelection[];
37
+ export declare function selectBoundBinding(state: ConnectState): BoundBindingSelection | null;
38
+ export declare function sendAllBoundHeartbeats(service: ConnectV1Service, options?: {
39
+ baseUrl?: string;
40
+ queueRuntimeSignal?: boolean;
41
+ }): Promise<HeartbeatBatchResult>;
42
+ export declare function sendBoundHeartbeat(service: ConnectV1Service, options?: {
43
+ baseUrl?: string;
44
+ }): Promise<HeartbeatResult>;
45
+ //# sourceMappingURL=heartbeat.d.ts.map