@lazyingart/agent-web 0.1.40
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/LICENSE +22 -0
- package/README.md +438 -0
- package/docs/architecture.md +503 -0
- package/package.json +43 -0
- package/src/aginti-adapter.js +602 -0
- package/src/chat-context.js +1020 -0
- package/src/chat-migrations.js +947 -0
- package/src/chat-store.js +3308 -0
- package/src/cli.js +134 -0
- package/src/cloud-server.js +2043 -0
- package/src/contracts.js +103 -0
- package/src/deterministic-context-summarizer.js +254 -0
- package/src/direct-chat-capability-limits.js +66 -0
- package/src/direct-chat-contract.js +3 -0
- package/src/errors.js +50 -0
- package/src/http-contract.js +592 -0
- package/src/index.js +88 -0
- package/src/localllm-connector.js +667 -0
- package/src/migrations.js +231 -0
- package/src/operator-health.js +184 -0
- package/src/password-verifier.js +131 -0
- package/src/service-config.js +547 -0
- package/src/service.js +408 -0
- package/src/sqlite-health.js +83 -0
- package/src/storage-path.js +130 -0
- package/src/store.js +914 -0
- package/src/validation.js +181 -0
- package/src/vision-attachment.js +404 -0
- package/src/web/aginti-client.js +552 -0
- package/src/web/aginti-protocol.js +1146 -0
- package/src/web/asset-map.js +462 -0
- package/src/web/browser-app.js +6491 -0
- package/src/web/cloud-session-client.js +427 -0
- package/src/web/direct-chat-client.js +1482 -0
- package/src/web/index.js +10 -0
- package/src/web/presentation-state.js +107 -0
- package/src/web/pwa-assets.js +854 -0
- package/src/web/pwa-update-handoff-store.js +179 -0
- package/src/web/safe-rendering.js +836 -0
- package/src/web/vision-image-client.js +546 -0
- package/src/web/vision-image-sanitizer.js +168 -0
- package/src/web/web-release.js +28 -0
package/src/cli.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
|
|
5
|
+
import { loadServiceConfig } from './service-config.js';
|
|
6
|
+
import {
|
|
7
|
+
checkStandaloneServiceHealth,
|
|
8
|
+
checkStandaloneServiceConfiguration,
|
|
9
|
+
createStandaloneServiceEdgeRouteManifest,
|
|
10
|
+
createStandaloneService
|
|
11
|
+
} from './service.js';
|
|
12
|
+
|
|
13
|
+
function parseArguments(argv, env) {
|
|
14
|
+
if (!Array.isArray(argv) || (argv.length !== 1 && argv.length !== 3)) {
|
|
15
|
+
throw new TypeError('usage: lazying-agent-web <serve|config-check|edge-routes|health> [--config ABSOLUTE_PATH]');
|
|
16
|
+
}
|
|
17
|
+
const command = argv[0];
|
|
18
|
+
if (command !== 'serve' && command !== 'config-check'
|
|
19
|
+
&& command !== 'edge-routes' && command !== 'health') {
|
|
20
|
+
throw new TypeError('only serve, config-check, edge-routes, and health commands are supported');
|
|
21
|
+
}
|
|
22
|
+
let configPath;
|
|
23
|
+
if (argv.length === 3) {
|
|
24
|
+
if (argv[1] !== '--config' || typeof argv[2] !== 'string' || !argv[2]) {
|
|
25
|
+
throw new TypeError('the only supported option is --config ABSOLUTE_PATH');
|
|
26
|
+
}
|
|
27
|
+
configPath = argv[2];
|
|
28
|
+
} else {
|
|
29
|
+
configPath = env.LAZYING_AGENT_CONFIG;
|
|
30
|
+
}
|
|
31
|
+
if (typeof configPath !== 'string' || !configPath) {
|
|
32
|
+
throw new TypeError('a config path is required');
|
|
33
|
+
}
|
|
34
|
+
if (typeof env.CREDENTIALS_DIRECTORY !== 'string' || !env.CREDENTIALS_DIRECTORY) {
|
|
35
|
+
throw new TypeError('CREDENTIALS_DIRECTORY is required');
|
|
36
|
+
}
|
|
37
|
+
return Object.freeze({ command, configPath, credentialsDirectory: env.CREDENTIALS_DIRECTORY });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function writeJson(stream, value) {
|
|
41
|
+
if (!stream || typeof stream.write !== 'function') throw new TypeError('output stream must provide write()');
|
|
42
|
+
stream.write(`${JSON.stringify(value)}\n`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function waitForTermination(service) {
|
|
46
|
+
return new Promise((resolve) => {
|
|
47
|
+
let settled = false;
|
|
48
|
+
const finish = () => {
|
|
49
|
+
if (settled) return;
|
|
50
|
+
settled = true;
|
|
51
|
+
process.removeListener('SIGINT', finish);
|
|
52
|
+
process.removeListener('SIGTERM', finish);
|
|
53
|
+
service.server.removeListener('close', finish);
|
|
54
|
+
resolve();
|
|
55
|
+
};
|
|
56
|
+
process.once('SIGINT', finish);
|
|
57
|
+
process.once('SIGTERM', finish);
|
|
58
|
+
service.server.once('close', finish);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export async function runCli({
|
|
63
|
+
argv = process.argv.slice(2),
|
|
64
|
+
env = process.env,
|
|
65
|
+
stdout = process.stdout,
|
|
66
|
+
configLoader = loadServiceConfig,
|
|
67
|
+
configChecker = checkStandaloneServiceConfiguration,
|
|
68
|
+
healthChecker = checkStandaloneServiceHealth,
|
|
69
|
+
edgeRouteManifestBuilder = createStandaloneServiceEdgeRouteManifest,
|
|
70
|
+
serviceFactory = createStandaloneService,
|
|
71
|
+
terminationWaiter = waitForTermination
|
|
72
|
+
} = {}) {
|
|
73
|
+
if (typeof configLoader !== 'function' || typeof configChecker !== 'function'
|
|
74
|
+
|| typeof healthChecker !== 'function'
|
|
75
|
+
|| typeof edgeRouteManifestBuilder !== 'function'
|
|
76
|
+
|| typeof serviceFactory !== 'function' || typeof terminationWaiter !== 'function') {
|
|
77
|
+
throw new TypeError('CLI dependencies must be functions');
|
|
78
|
+
}
|
|
79
|
+
const command = parseArguments(argv, env);
|
|
80
|
+
const loadedConfig = configLoader({
|
|
81
|
+
configPath: command.configPath,
|
|
82
|
+
credentialsDirectory: command.credentialsDirectory
|
|
83
|
+
});
|
|
84
|
+
if (command.command === 'config-check') {
|
|
85
|
+
const report = await configChecker(loadedConfig);
|
|
86
|
+
writeJson(stdout, { ok: true, command: 'config-check', ...report });
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
89
|
+
if (command.command === 'edge-routes') {
|
|
90
|
+
const manifest = await edgeRouteManifestBuilder(loadedConfig);
|
|
91
|
+
writeJson(stdout, { ok: true, command: 'edge-routes', ...manifest });
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
94
|
+
if (command.command === 'health') {
|
|
95
|
+
const report = await healthChecker(loadedConfig);
|
|
96
|
+
const ready = report?.status === 'ready';
|
|
97
|
+
writeJson(stdout, { ...report, ok: ready, command: 'health' });
|
|
98
|
+
return ready ? 0 : 1;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const service = await serviceFactory({ loadedConfig });
|
|
102
|
+
try {
|
|
103
|
+
const endpoint = await service.start();
|
|
104
|
+
writeJson(stdout, {
|
|
105
|
+
ok: true,
|
|
106
|
+
command: 'serve',
|
|
107
|
+
status: 'listening',
|
|
108
|
+
address: endpoint.address,
|
|
109
|
+
port: endpoint.port,
|
|
110
|
+
publicOrigin: service.publicOrigin,
|
|
111
|
+
releaseId: service.releaseId,
|
|
112
|
+
agentEnabled: false
|
|
113
|
+
});
|
|
114
|
+
await terminationWaiter(service);
|
|
115
|
+
return 0;
|
|
116
|
+
} finally {
|
|
117
|
+
await service.shutdown();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export async function main() {
|
|
122
|
+
try {
|
|
123
|
+
const code = await runCli();
|
|
124
|
+
process.exitCode = code;
|
|
125
|
+
} catch {
|
|
126
|
+
// Deliberately do not print exception messages: configuration and credential
|
|
127
|
+
// failures must not turn secret material into service-manager logs.
|
|
128
|
+
writeJson(process.stderr, { ok: false, error: 'standalone_service_command_failed' });
|
|
129
|
+
process.exitCode = 1;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const entry = process.argv[1] ? pathToFileURL(process.argv[1]).href : null;
|
|
134
|
+
if (entry === import.meta.url) await main();
|