@artipod/core 0.4.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/LICENSE +21 -0
- package/README.md +146 -0
- package/dist/agent/index.d.ts +18 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +14 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/local/client.d.ts +24 -0
- package/dist/agent/local/client.d.ts.map +1 -0
- package/dist/agent/local/client.js +88 -0
- package/dist/agent/local/client.js.map +1 -0
- package/dist/agent/local/model-cache.d.ts +15 -0
- package/dist/agent/local/model-cache.d.ts.map +1 -0
- package/dist/agent/local/model-cache.js +61 -0
- package/dist/agent/local/model-cache.js.map +1 -0
- package/dist/agent/local/model-registry.d.ts +24 -0
- package/dist/agent/local/model-registry.d.ts.map +1 -0
- package/dist/agent/local/model-registry.js +56 -0
- package/dist/agent/local/model-registry.js.map +1 -0
- package/dist/agent/local/parse-tool-calls.d.ts +13 -0
- package/dist/agent/local/parse-tool-calls.d.ts.map +1 -0
- package/dist/agent/local/parse-tool-calls.js +46 -0
- package/dist/agent/local/parse-tool-calls.js.map +1 -0
- package/dist/agent/local/protocol.d.ts +39 -0
- package/dist/agent/local/protocol.d.ts.map +1 -0
- package/dist/agent/local/protocol.js +2 -0
- package/dist/agent/local/protocol.js.map +1 -0
- package/dist/agent/local/worker.d.ts +2 -0
- package/dist/agent/local/worker.d.ts.map +1 -0
- package/dist/agent/local/worker.js +189 -0
- package/dist/agent/local/worker.js.map +1 -0
- package/dist/agent/loop.d.ts +21 -0
- package/dist/agent/loop.d.ts.map +1 -0
- package/dist/agent/loop.js +103 -0
- package/dist/agent/loop.js.map +1 -0
- package/dist/agent/ozwell-client.d.ts +22 -0
- package/dist/agent/ozwell-client.d.ts.map +1 -0
- package/dist/agent/ozwell-client.js +57 -0
- package/dist/agent/ozwell-client.js.map +1 -0
- package/dist/agent/tools.d.ts +19 -0
- package/dist/agent/tools.d.ts.map +1 -0
- package/dist/agent/tools.js +76 -0
- package/dist/agent/tools.js.map +1 -0
- package/dist/agent/types.d.ts +123 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +6 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/artimount.d.ts +101 -0
- package/dist/artimount.d.ts.map +1 -0
- package/dist/artimount.js +266 -0
- package/dist/artimount.js.map +1 -0
- package/dist/artipod.d.ts +138 -0
- package/dist/artipod.d.ts.map +1 -0
- package/dist/artipod.js +453 -0
- package/dist/artipod.js.map +1 -0
- package/dist/buildinfo.json +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +626 -0
- package/dist/cli.js.map +1 -0
- package/dist/console/index.d.ts +40 -0
- package/dist/console/index.d.ts.map +1 -0
- package/dist/console/index.js +194 -0
- package/dist/console/index.js.map +1 -0
- package/dist/docker/containerRuntime.d.ts +51 -0
- package/dist/docker/containerRuntime.d.ts.map +1 -0
- package/dist/docker/containerRuntime.js +213 -0
- package/dist/docker/containerRuntime.js.map +1 -0
- package/dist/docker/containerUtils.d.ts +80 -0
- package/dist/docker/containerUtils.d.ts.map +1 -0
- package/dist/docker/containerUtils.js +244 -0
- package/dist/docker/containerUtils.js.map +1 -0
- package/dist/docker/index.d.ts +6 -0
- package/dist/docker/index.d.ts.map +1 -0
- package/dist/docker/index.js +6 -0
- package/dist/docker/index.js.map +1 -0
- package/dist/events.d.ts +98 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +43 -0
- package/dist/events.js.map +1 -0
- package/dist/host/file-buffer.d.ts +44 -0
- package/dist/host/file-buffer.d.ts.map +1 -0
- package/dist/host/file-buffer.js +127 -0
- package/dist/host/file-buffer.js.map +1 -0
- package/dist/host/index.d.ts +14 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +10 -0
- package/dist/host/index.js.map +1 -0
- package/dist/host/terminal-session.d.ts +49 -0
- package/dist/host/terminal-session.d.ts.map +1 -0
- package/dist/host/terminal-session.js +201 -0
- package/dist/host/terminal-session.js.map +1 -0
- package/dist/host/tree-source.d.ts +42 -0
- package/dist/host/tree-source.d.ts.map +1 -0
- package/dist/host/tree-source.js +61 -0
- package/dist/host/tree-source.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/manager/approval.d.ts +66 -0
- package/dist/manager/approval.d.ts.map +1 -0
- package/dist/manager/approval.js +94 -0
- package/dist/manager/approval.js.map +1 -0
- package/dist/manager/audit.d.ts +36 -0
- package/dist/manager/audit.d.ts.map +1 -0
- package/dist/manager/audit.js +53 -0
- package/dist/manager/audit.js.map +1 -0
- package/dist/manager/authority.d.ts +134 -0
- package/dist/manager/authority.d.ts.map +1 -0
- package/dist/manager/authority.js +181 -0
- package/dist/manager/authority.js.map +1 -0
- package/dist/manager/crypto.d.ts +47 -0
- package/dist/manager/crypto.d.ts.map +1 -0
- package/dist/manager/crypto.js +82 -0
- package/dist/manager/crypto.js.map +1 -0
- package/dist/manager/encrypted-sync.d.ts +23 -0
- package/dist/manager/encrypted-sync.d.ts.map +1 -0
- package/dist/manager/encrypted-sync.js +113 -0
- package/dist/manager/encrypted-sync.js.map +1 -0
- package/dist/manager/grants.d.ts +40 -0
- package/dist/manager/grants.d.ts.map +1 -0
- package/dist/manager/grants.js +69 -0
- package/dist/manager/grants.js.map +1 -0
- package/dist/manager/http-store.d.ts +31 -0
- package/dist/manager/http-store.d.ts.map +1 -0
- package/dist/manager/http-store.js +80 -0
- package/dist/manager/http-store.js.map +1 -0
- package/dist/manager/hydration.d.ts +243 -0
- package/dist/manager/hydration.d.ts.map +1 -0
- package/dist/manager/hydration.js +570 -0
- package/dist/manager/hydration.js.map +1 -0
- package/dist/manager/index.d.ts +39 -0
- package/dist/manager/index.d.ts.map +1 -0
- package/dist/manager/index.js +19 -0
- package/dist/manager/index.js.map +1 -0
- package/dist/manager/keyring.d.ts +48 -0
- package/dist/manager/keyring.d.ts.map +1 -0
- package/dist/manager/keyring.js +121 -0
- package/dist/manager/keyring.js.map +1 -0
- package/dist/manager/locker.d.ts +41 -0
- package/dist/manager/locker.d.ts.map +1 -0
- package/dist/manager/locker.js +107 -0
- package/dist/manager/locker.js.map +1 -0
- package/dist/manager/merge.d.ts +53 -0
- package/dist/manager/merge.d.ts.map +1 -0
- package/dist/manager/merge.js +290 -0
- package/dist/manager/merge.js.map +1 -0
- package/dist/manager/overlay-sync.d.ts +51 -0
- package/dist/manager/overlay-sync.d.ts.map +1 -0
- package/dist/manager/overlay-sync.js +152 -0
- package/dist/manager/overlay-sync.js.map +1 -0
- package/dist/manager/pod-store.d.ts +48 -0
- package/dist/manager/pod-store.d.ts.map +1 -0
- package/dist/manager/pod-store.js +116 -0
- package/dist/manager/pod-store.js.map +1 -0
- package/dist/manager/policy.d.ts +32 -0
- package/dist/manager/policy.d.ts.map +1 -0
- package/dist/manager/policy.js +47 -0
- package/dist/manager/policy.js.map +1 -0
- package/dist/manager/session-host.d.ts +51 -0
- package/dist/manager/session-host.d.ts.map +1 -0
- package/dist/manager/session-host.js +112 -0
- package/dist/manager/session-host.js.map +1 -0
- package/dist/manager/sync.d.ts +60 -0
- package/dist/manager/sync.d.ts.map +1 -0
- package/dist/manager/sync.js +149 -0
- package/dist/manager/sync.js.map +1 -0
- package/dist/manifest.d.ts +52 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +87 -0
- package/dist/manifest.js.map +1 -0
- package/dist/nodePodFs.d.ts +9 -0
- package/dist/nodePodFs.d.ts.map +1 -0
- package/dist/nodePodFs.js +19 -0
- package/dist/nodePodFs.js.map +1 -0
- package/dist/oci/cipher.d.ts +38 -0
- package/dist/oci/cipher.d.ts.map +1 -0
- package/dist/oci/cipher.js +101 -0
- package/dist/oci/cipher.js.map +1 -0
- package/dist/oci/command.d.ts +43 -0
- package/dist/oci/command.d.ts.map +1 -0
- package/dist/oci/command.js +384 -0
- package/dist/oci/command.js.map +1 -0
- package/dist/oci/digest.d.ts +12 -0
- package/dist/oci/digest.d.ts.map +1 -0
- package/dist/oci/digest.js +28 -0
- package/dist/oci/digest.js.map +1 -0
- package/dist/oci/file-layer.d.ts +42 -0
- package/dist/oci/file-layer.d.ts.map +1 -0
- package/dist/oci/file-layer.js +50 -0
- package/dist/oci/file-layer.js.map +1 -0
- package/dist/oci/gzip.d.ts +10 -0
- package/dist/oci/gzip.d.ts.map +1 -0
- package/dist/oci/gzip.js +31 -0
- package/dist/oci/gzip.js.map +1 -0
- package/dist/oci/index.d.ts +30 -0
- package/dist/oci/index.d.ts.map +1 -0
- package/dist/oci/index.js +20 -0
- package/dist/oci/index.js.map +1 -0
- package/dist/oci/pull.d.ts +61 -0
- package/dist/oci/pull.d.ts.map +1 -0
- package/dist/oci/pull.js +89 -0
- package/dist/oci/pull.js.map +1 -0
- package/dist/oci/snapshot.d.ts +114 -0
- package/dist/oci/snapshot.d.ts.map +1 -0
- package/dist/oci/snapshot.js +441 -0
- package/dist/oci/snapshot.js.map +1 -0
- package/dist/oci/store.d.ts +95 -0
- package/dist/oci/store.d.ts.map +1 -0
- package/dist/oci/store.js +272 -0
- package/dist/oci/store.js.map +1 -0
- package/dist/oci/tar.d.ts +65 -0
- package/dist/oci/tar.d.ts.map +1 -0
- package/dist/oci/tar.js +237 -0
- package/dist/oci/tar.js.map +1 -0
- package/dist/oci/test-fixtures.d.ts +17 -0
- package/dist/oci/test-fixtures.d.ts.map +1 -0
- package/dist/oci/test-fixtures.js +79 -0
- package/dist/oci/test-fixtures.js.map +1 -0
- package/dist/oci/transport.d.ts +86 -0
- package/dist/oci/transport.d.ts.map +1 -0
- package/dist/oci/transport.js +186 -0
- package/dist/oci/transport.js.map +1 -0
- package/dist/oci/view.d.ts +75 -0
- package/dist/oci/view.d.ts.map +1 -0
- package/dist/oci/view.js +192 -0
- package/dist/oci/view.js.map +1 -0
- package/dist/pathUtils.d.ts +23 -0
- package/dist/pathUtils.d.ts.map +1 -0
- package/dist/pathUtils.js +72 -0
- package/dist/pathUtils.js.map +1 -0
- package/dist/podfs.d.ts +37 -0
- package/dist/podfs.d.ts.map +1 -0
- package/dist/podfs.js +10 -0
- package/dist/podfs.js.map +1 -0
- package/dist/proc/index.d.ts +14 -0
- package/dist/proc/index.d.ts.map +1 -0
- package/dist/proc/index.js +12 -0
- package/dist/proc/index.js.map +1 -0
- package/dist/proc/pod-provider.d.ts +14 -0
- package/dist/proc/pod-provider.d.ts.map +1 -0
- package/dist/proc/pod-provider.js +32 -0
- package/dist/proc/pod-provider.js.map +1 -0
- package/dist/proc/reconcile.d.ts +3 -0
- package/dist/proc/reconcile.d.ts.map +1 -0
- package/dist/proc/reconcile.js +73 -0
- package/dist/proc/reconcile.js.map +1 -0
- package/dist/proc/registry.d.ts +46 -0
- package/dist/proc/registry.d.ts.map +1 -0
- package/dist/proc/registry.js +56 -0
- package/dist/proc/registry.js.map +1 -0
- package/dist/proc/snapshot.d.ts +37 -0
- package/dist/proc/snapshot.d.ts.map +1 -0
- package/dist/proc/snapshot.js +97 -0
- package/dist/proc/snapshot.js.map +1 -0
- package/dist/proc/storage-provider.d.ts +17 -0
- package/dist/proc/storage-provider.d.ts.map +1 -0
- package/dist/proc/storage-provider.js +111 -0
- package/dist/proc/storage-provider.js.map +1 -0
- package/dist/prompts/index.d.ts +5 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +5 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/templates.d.ts +78 -0
- package/dist/prompts/templates.d.ts.map +1 -0
- package/dist/prompts/templates.js +256 -0
- package/dist/prompts/templates.js.map +1 -0
- package/dist/realize/docker.d.ts +25 -0
- package/dist/realize/docker.d.ts.map +1 -0
- package/dist/realize/docker.js +39 -0
- package/dist/realize/docker.js.map +1 -0
- package/dist/realize/zenfs.d.ts +165 -0
- package/dist/realize/zenfs.d.ts.map +1 -0
- package/dist/realize/zenfs.js +342 -0
- package/dist/realize/zenfs.js.map +1 -0
- package/dist/sandbox/edit-command.d.ts +3 -0
- package/dist/sandbox/edit-command.d.ts.map +1 -0
- package/dist/sandbox/edit-command.js +19 -0
- package/dist/sandbox/edit-command.js.map +1 -0
- package/dist/sandbox/git-auth.d.ts +26 -0
- package/dist/sandbox/git-auth.d.ts.map +1 -0
- package/dist/sandbox/git-auth.js +79 -0
- package/dist/sandbox/git-auth.js.map +1 -0
- package/dist/sandbox/git-command.d.ts +3 -0
- package/dist/sandbox/git-command.d.ts.map +1 -0
- package/dist/sandbox/git-command.js +174 -0
- package/dist/sandbox/git-command.js.map +1 -0
- package/dist/sandbox/git.d.ts +62 -0
- package/dist/sandbox/git.d.ts.map +1 -0
- package/dist/sandbox/git.js +254 -0
- package/dist/sandbox/git.js.map +1 -0
- package/dist/sandbox/index.d.ts +44 -0
- package/dist/sandbox/index.d.ts.map +1 -0
- package/dist/sandbox/index.js +134 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/sandbox/module-command.d.ts +2 -0
- package/dist/sandbox/module-command.d.ts.map +1 -0
- package/dist/sandbox/module-command.js +98 -0
- package/dist/sandbox/module-command.js.map +1 -0
- package/dist/sandbox/notes-command.d.ts +3 -0
- package/dist/sandbox/notes-command.d.ts.map +1 -0
- package/dist/sandbox/notes-command.js +49 -0
- package/dist/sandbox/notes-command.js.map +1 -0
- package/dist/sandbox/storage-command.d.ts +31 -0
- package/dist/sandbox/storage-command.d.ts.map +1 -0
- package/dist/sandbox/storage-command.js +505 -0
- package/dist/sandbox/storage-command.js.map +1 -0
- package/dist/sandbox/storage.d.ts +85 -0
- package/dist/sandbox/storage.d.ts.map +1 -0
- package/dist/sandbox/storage.js +348 -0
- package/dist/sandbox/storage.js.map +1 -0
- package/dist/sandbox/sudo-command.d.ts +16 -0
- package/dist/sandbox/sudo-command.d.ts.map +1 -0
- package/dist/sandbox/sudo-command.js +42 -0
- package/dist/sandbox/sudo-command.js.map +1 -0
- package/dist/sandbox/table.d.ts +3 -0
- package/dist/sandbox/table.d.ts.map +1 -0
- package/dist/sandbox/table.js +10 -0
- package/dist/sandbox/table.js.map +1 -0
- package/dist/sandbox/types.d.ts +42 -0
- package/dist/sandbox/types.d.ts.map +1 -0
- package/dist/sandbox/types.js +9 -0
- package/dist/sandbox/types.js.map +1 -0
- package/dist/sandbox/zenfs-adapter.d.ts +56 -0
- package/dist/sandbox/zenfs-adapter.d.ts.map +1 -0
- package/dist/sandbox/zenfs-adapter.js +144 -0
- package/dist/sandbox/zenfs-adapter.js.map +1 -0
- package/dist/server/common.d.ts +12 -0
- package/dist/server/common.d.ts.map +1 -0
- package/dist/server/common.js +19 -0
- package/dist/server/common.js.map +1 -0
- package/dist/server/exec-handler.d.ts +30 -0
- package/dist/server/exec-handler.d.ts.map +1 -0
- package/dist/server/exec-handler.js +47 -0
- package/dist/server/exec-handler.js.map +1 -0
- package/dist/server/folder.d.ts +68 -0
- package/dist/server/folder.d.ts.map +1 -0
- package/dist/server/folder.js +289 -0
- package/dist/server/folder.js.map +1 -0
- package/dist/server/git-proxy.d.ts +34 -0
- package/dist/server/git-proxy.d.ts.map +1 -0
- package/dist/server/git-proxy.js +124 -0
- package/dist/server/git-proxy.js.map +1 -0
- package/dist/server/index.d.ts +20 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +20 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/pod-store-handler.d.ts +33 -0
- package/dist/server/pod-store-handler.d.ts.map +1 -0
- package/dist/server/pod-store-handler.js +113 -0
- package/dist/server/pod-store-handler.js.map +1 -0
- package/dist/server/registry-relay.d.ts +16 -0
- package/dist/server/registry-relay.d.ts.map +1 -0
- package/dist/server/registry-relay.js +55 -0
- package/dist/server/registry-relay.js.map +1 -0
- package/dist/tools/applyPatchParser.d.ts +129 -0
- package/dist/tools/applyPatchParser.d.ts.map +1 -0
- package/dist/tools/applyPatchParser.js +668 -0
- package/dist/tools/applyPatchParser.js.map +1 -0
- package/dist/tools/applyPatchTool.d.ts +23 -0
- package/dist/tools/applyPatchTool.d.ts.map +1 -0
- package/dist/tools/applyPatchTool.js +147 -0
- package/dist/tools/applyPatchTool.js.map +1 -0
- package/dist/tools/bashTool.d.ts +34 -0
- package/dist/tools/bashTool.d.ts.map +1 -0
- package/dist/tools/bashTool.js +65 -0
- package/dist/tools/bashTool.js.map +1 -0
- package/dist/tools/coreTools.d.ts +54 -0
- package/dist/tools/coreTools.d.ts.map +1 -0
- package/dist/tools/coreTools.js +266 -0
- package/dist/tools/coreTools.js.map +1 -0
- package/dist/tools/definitions.d.ts +78 -0
- package/dist/tools/definitions.d.ts.map +1 -0
- package/dist/tools/definitions.js +368 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/editTools.d.ts +54 -0
- package/dist/tools/editTools.d.ts.map +1 -0
- package/dist/tools/editTools.js +266 -0
- package/dist/tools/editTools.js.map +1 -0
- package/dist/tools/index.d.ts +69 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +122 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/podFileTools.d.ts +37 -0
- package/dist/tools/podFileTools.d.ts.map +1 -0
- package/dist/tools/podFileTools.js +337 -0
- package/dist/tools/podFileTools.js.map +1 -0
- package/dist/tools/podTools.d.ts +80 -0
- package/dist/tools/podTools.d.ts.map +1 -0
- package/dist/tools/podTools.js +166 -0
- package/dist/tools/podTools.js.map +1 -0
- package/dist/tools/serializers.d.ts +26 -0
- package/dist/tools/serializers.d.ts.map +1 -0
- package/dist/tools/serializers.js +21 -0
- package/dist/tools/serializers.js.map +1 -0
- package/dist/tools/truncation.d.ts +4 -0
- package/dist/tools/truncation.d.ts.map +1 -0
- package/dist/tools/truncation.js +10 -0
- package/dist/tools/truncation.js.map +1 -0
- package/dist/tools/types.d.ts +193 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +59 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/types.d.ts +32 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +144 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Medical Informatics Engineering, LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# artipod
|
|
2
|
+
|
|
3
|
+
**A pod for artifacts: a virtual filesystem your AI can reason in, your users can shell into, and your infrastructure can version, encrypt, and synchronize — in the browser and on Linux.**
|
|
4
|
+
|
|
5
|
+
> **Status: shipped through plan Phase 6.6.** Everything below marked ✅ ships in `@artipod/core` today — the Node/Docker core, the browser sandbox, OCI layering, encryption & authority, and sync (the browser app lives at [examples/artipod-sync](examples/artipod-sync)). 🔮 marks the remaining design work (Phase 7 live streams), tracked phase-by-phase in [artipod-layer-plan.md](artipod-layer-plan.md). Previous implementation-state READMEs are archived in `attic/` ([v0.1](attic/v0.1-node.README.md), [v0.3](attic/v0.3-node.README.md) — the v0.3 one documents the pre-merge Node/Docker API, including podman support, read-only mounts, and the main mount).
|
|
6
|
+
|
|
7
|
+
## What is an artipod?
|
|
8
|
+
|
|
9
|
+
An **artipod** is a self-contained, portable workspace — a declarative set of mounts over a virtual filesystem, plus everything that operates on it:
|
|
10
|
+
|
|
11
|
+
- a **bash isolate** (real bash semantics, browser and server) ✅
|
|
12
|
+
- **AI agent tools** with VS Code-compatible schemas, an agent loop, and context/prompt building ✅
|
|
13
|
+
- **OCI layering** for revision control: every pod is image/volume layers + a writable upper; snapshot, checkout, diff, commit, push, pull ✅
|
|
14
|
+
- **encryption & authority**: ciphertext at rest, leased keys, offline grants, delegated managers ✅
|
|
15
|
+
- **sync**: content-addressed, resumable, relay-friendly — browser ↔ server ↔ home base ✅
|
|
16
|
+
|
|
17
|
+
Three consumer surfaces, one layer:
|
|
18
|
+
|
|
19
|
+
| Surface | What it gets |
|
|
20
|
+
|---|---|
|
|
21
|
+
| **AI reasoning** | `buildPrompt()` context, VS Code-schema tools (`read_file`, `apply_patch`, …, `bash`), agent loop, `/proc` introspection — all confined to the pod |
|
|
22
|
+
| **Revision control** | OCI snapshots: cheap (reference-based) checkpoints of *everything*, including shell side effects; time-travel, branch, diff, compact |
|
|
23
|
+
| **Synchronization** | push/pull of digest-addressed layers through registries, proxies, or relays; offline-first by construction |
|
|
24
|
+
|
|
25
|
+
> **Coming from Docker or Podman?** The muscle memory transfers (`artipod run -it alpine:3.22`, `artipod pods`), but the model inverts: in Docker the image is the artifact and the container's writable layer is scratch; here the writable state *is* the artifact — versioned, encrypted, pushable. And a pod is **not a Kubernetes Pod** — it's durable state that execution attaches to, not scheduled compute. Full orientation and concept map: [docs/containers.md](docs/containers.md).
|
|
26
|
+
|
|
27
|
+
## Quick starts
|
|
28
|
+
|
|
29
|
+
### The CLI: a pod in your terminal (✅)
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
npx @artipod/core run -it # fresh pod → artipod-bash, kept under ~/.artipod/pods
|
|
33
|
+
npx @artipod/core run -it alpine:3.22 # a registry image, cloned in writable
|
|
34
|
+
npm install -g @artipod/core # permanent `artipod` on PATH
|
|
35
|
+
artipod pods # past runs — the `docker ps -a` of pods
|
|
36
|
+
artipod run -it 500edf8b # resume a kept pod by id prefix
|
|
37
|
+
artipod run -it field/notes:1 # a ref you pushed earlier
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
(`npx github:mieweb/artipod` also works — it compiles from source on first run and caches.)
|
|
41
|
+
|
|
42
|
+
Pods are kept on the real filesystem by default, so `exit` loses nothing — create-on-write: a
|
|
43
|
+
fresh pod that saw no writes is quietly removed again. `--rm` makes the pod ephemeral (RAM only
|
|
44
|
+
— add `--disk` to back it by a deleted-on-exit temp dir when changes may not fit in memory),
|
|
45
|
+
`artipod rm <pod>` / `artipod prune` clean up kept pods, `--dir <path>` keeps a pod at a path of
|
|
46
|
+
your choosing, `--store <path>` (default `~/.artipod/store`) backs `push`/`pull`/`clone` and REF
|
|
47
|
+
lookup, `-c '<cmd>'` runs one line and exits. Inside the shell, `artipod` lists the pod verbs
|
|
48
|
+
(snapshot, commit, push, hydrate, …).
|
|
49
|
+
|
|
50
|
+
### Browser pod with a shell (✅ `@artipod/core/sandbox`)
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import { initFileSystem, createSandbox } from '@artipod/core/sandbox';
|
|
54
|
+
|
|
55
|
+
const { zfs } = await initFileSystem(); // IndexedDB (default) or OPFS
|
|
56
|
+
const sandbox = createSandbox({ zfs }); // just-bash over ZenFS
|
|
57
|
+
const r = await sandbox.exec('git clone https://github.com/user/repo && ls repo | head');
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Linux / server pod with Docker/Podman execution (✅ core shipped)
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { ArtiPod, ArtiMount } from '@artipod/core';
|
|
64
|
+
|
|
65
|
+
const pod = new ArtiPod({
|
|
66
|
+
workspaceDir: '/data/workspaces', // auto-creates the writable 'main' mount
|
|
67
|
+
mounts: [new ArtiMount('src', '/data/project/src', /* readonly */ true)],
|
|
68
|
+
});
|
|
69
|
+
await pod.initialize();
|
|
70
|
+
await pod.startContainer('./container/Dockerfile'); // hardened: CapDrop ALL, seccomp, no network
|
|
71
|
+
const out = await pod.executeCommand('grep -r TODO /context/src | wc -l');
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
See [docs/linux.md](docs/linux.md) for the full server story (realizers, OCI-layout store, systemd).
|
|
75
|
+
|
|
76
|
+
### An agent working inside a pod (✅ `@artipod/core/agent`)
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { createToolRegistry } from '@artipod/core/tools';
|
|
80
|
+
import { ToolCallingLoop } from '@artipod/core/agent';
|
|
81
|
+
|
|
82
|
+
const tools = createToolRegistry(pod); // read_file, apply_patch, bash, … — pod-confined
|
|
83
|
+
const loop = new ToolCallingLoop(client, tools);
|
|
84
|
+
await loop.run('Summarize the README, then fix the failing test.');
|
|
85
|
+
// tool-executing turns auto-snapshot (pod.agentLoopOptions(), default on) — `artipod snapshot diff` shows what the model did
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The agent is **confined to the pod**. Anything outside it requires `sudo` — which the agent cannot self-approve. See [docs/security-model.md](docs/security-model.md).
|
|
89
|
+
|
|
90
|
+
### The Ctrl+~ console (✅)
|
|
91
|
+
|
|
92
|
+
One line to give any web app a drop-down artipod console (Quake-style):
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import { installConsole } from '@artipod/core/console';
|
|
96
|
+
installConsole({ sandbox, hotkey: 'Ctrl+`' }); // Ctrl+` / Ctrl+~ toggles the overlay
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
See [docs/console.md](docs/console.md).
|
|
100
|
+
|
|
101
|
+
## Package layout
|
|
102
|
+
|
|
103
|
+
Single package, ESM subpath exports (browser/node split via export conditions):
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
@artipod/core ArtiPod, ArtiMount, pod manifest, pod events
|
|
107
|
+
@artipod/core/tools VS Code-schema tools + bash, OpenAI & MCP serializers
|
|
108
|
+
@artipod/core/prompts prompt templates + buildPrompt
|
|
109
|
+
@artipod/core/sandbox just-bash isolate, ZenFS adapter, storage backends
|
|
110
|
+
@artipod/core/agent tool-calling loop, OpenAI-compatible + local ONNX clients
|
|
111
|
+
@artipod/core/proc /proc providers (host state as files)
|
|
112
|
+
@artipod/core/host headless UI controllers (terminal session, file buffer, tree)
|
|
113
|
+
@artipod/core/console Ctrl+~ drop-in overlay console
|
|
114
|
+
@artipod/core/manager pod hosting, PodStore, keyring, leases, policy
|
|
115
|
+
@artipod/core/server fetch-style hosting handlers: pod store, exec, git/OCI proxies (node-only)
|
|
116
|
+
@artipod/core/oci blob store, layer FS, snapshots, transports
|
|
117
|
+
@artipod/core/docker hardened Docker execution (node-only)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Security model in five lines
|
|
121
|
+
|
|
122
|
+
1. **Disk holds only ciphertext + wrapped keys**; usable keys live in a memory keyring, on server-issued leases with a TTL. Lock = the key evaporates; login restores it.
|
|
123
|
+
2. **Offline is first-class**: signed offline grants (e.g. 24 h) wrap keys to a device; delegated manager certificates let a ship/station/site issue leases with no home-base round trip.
|
|
124
|
+
3. **The agent is confined to its pod.** `sudo` is the only escape, it requires explicit human approval, and the human may only approve if admin policy grants them that right.
|
|
125
|
+
4. **Relays never need plaintext** — content addressing verifies end-to-end, so untrusted hops can cache and forward.
|
|
126
|
+
5. Honesty: a browser can enforce cryptography, not process boundaries — see the threat-model tables in [docs/encryption.md](docs/encryption.md) before assuming more.
|
|
127
|
+
|
|
128
|
+
Built for real disconnection profiles: a 24-hour offline clinic visit, a light-minutes-away station where all operations are local and sync is merely delayed, and an intermittently-connected ship where laptops relay through an on-board server. Walkthroughs in [docs/encryption.md](docs/encryption.md#offline-use-cases).
|
|
129
|
+
|
|
130
|
+
## Documentation
|
|
131
|
+
|
|
132
|
+
| Doc | Contents |
|
|
133
|
+
|---|---|
|
|
134
|
+
| [docs/containers.md](docs/containers.md) | Orientation for Docker/Podman/Kubernetes users: concept map, where each runtime fits, the pod-term collision |
|
|
135
|
+
| [docs/on-disk-layout.md](docs/on-disk-layout.md) | What lands on disk: `~/.artipod`, the per-pod `/.artipod` store, plaintext vs ciphertext |
|
|
136
|
+
| [docs/browser.md](docs/browser.md) | Browser implementation: ZenFS backends, OPFS/IndexedDB, ingest API, devices |
|
|
137
|
+
| [docs/linux.md](docs/linux.md) | Linux/server implementation: realizers, Docker hardening, stores, deployment |
|
|
138
|
+
| [docs/bash-isolate.md](docs/bash-isolate.md) | The bash isolate in browser and server: semantics, sessions, limits |
|
|
139
|
+
| [docs/encryption.md](docs/encryption.md) | Encryption at rest, keyring, leases, offline grants, delegation |
|
|
140
|
+
| [docs/security-model.md](docs/security-model.md) | Agent confinement, `sudo`, approval flow, admin policy |
|
|
141
|
+
| [docs/console.md](docs/console.md) | The Ctrl+~ installable console module |
|
|
142
|
+
| [artipod-layer-plan.md](artipod-layer-plan.md) | The living implementation plan (phases, decisions, worklogs) |
|
|
143
|
+
|
|
144
|
+
## License
|
|
145
|
+
|
|
146
|
+
MIT
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @artipod/core/agent — tool-calling loop, clients, and sandbox tool bindings.
|
|
3
|
+
*
|
|
4
|
+
* Framework-free (browser + Node). The local ONNX worker is exported as its
|
|
5
|
+
* own entry (`@artipod/core/agent/local/worker`) so bundlers can target it
|
|
6
|
+
* with `new Worker(new URL(...))`.
|
|
7
|
+
*/
|
|
8
|
+
export { ToolCallingLoop } from './loop.js';
|
|
9
|
+
export { OzwellClient } from './ozwell-client.js';
|
|
10
|
+
export type { OzwellClientConfig } from './ozwell-client.js';
|
|
11
|
+
export { createSandboxTools, toOpenAiToolDefinitions, toMcpToolDescriptors, truncateOutput, MAX_TOOL_OUTPUT_BYTES, } from './tools.js';
|
|
12
|
+
export type { ChatCompletionClient, ChatCompletionOptions, ChatCompletionRequest, ChatCompletionResponse, ChatMessage, McpToolDescriptor, MessageRole, TokenUsage, ToolCall, ToolCallingLoopOptions, ToolCallingLoopResult, ToolDefinition, ToolHandler, ToolResult, } from './types.js';
|
|
13
|
+
export { LocalModelClient, webGpuAvailable } from './local/client.js';
|
|
14
|
+
export type { LocalModelClientOptions } from './local/client.js';
|
|
15
|
+
export { CURATED_MODELS, DEFAULT_LOCAL_MODEL, listLocalModels, modelInfo, type LocalModelInfo, type OnnxDtype, } from './local/model-registry.js';
|
|
16
|
+
export { formatBytes, listCachedModels, modelIdFromCacheKey } from './local/model-cache.js';
|
|
17
|
+
export type { CachedModel } from './local/model-cache.js';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,oBAAoB,EACpB,cAAc,EACd,qBAAqB,GACtB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,QAAQ,EACR,sBAAsB,EACtB,qBAAqB,EACrB,cAAc,EACd,WAAW,EACX,UAAU,GACX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACtE,YAAY,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,SAAS,EACT,KAAK,cAAc,EACnB,KAAK,SAAS,GACf,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC5F,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @artipod/core/agent — tool-calling loop, clients, and sandbox tool bindings.
|
|
3
|
+
*
|
|
4
|
+
* Framework-free (browser + Node). The local ONNX worker is exported as its
|
|
5
|
+
* own entry (`@artipod/core/agent/local/worker`) so bundlers can target it
|
|
6
|
+
* with `new Worker(new URL(...))`.
|
|
7
|
+
*/
|
|
8
|
+
export { ToolCallingLoop } from './loop.js';
|
|
9
|
+
export { OzwellClient } from './ozwell-client.js';
|
|
10
|
+
export { createSandboxTools, toOpenAiToolDefinitions, toMcpToolDescriptors, truncateOutput, MAX_TOOL_OUTPUT_BYTES, } from './tools.js';
|
|
11
|
+
export { LocalModelClient, webGpuAvailable } from './local/client.js';
|
|
12
|
+
export { CURATED_MODELS, DEFAULT_LOCAL_MODEL, listLocalModels, modelInfo, } from './local/model-registry.js';
|
|
13
|
+
export { formatBytes, listCachedModels, modelIdFromCacheKey } from './local/model-cache.js';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,oBAAoB,EACpB,cAAc,EACd,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAiBpB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEtE,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,SAAS,GAGV,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LocalModelClient — ChatCompletionClient over the ONNX worker, so
|
|
3
|
+
* ToolCallingLoop works identically with in-browser models. WebGPU only.
|
|
4
|
+
*/
|
|
5
|
+
import type { ChatCompletionClient, ChatCompletionOptions, ChatCompletionResponse, ChatMessage } from '../types.js';
|
|
6
|
+
import type { OnnxDtype } from './model-registry.js';
|
|
7
|
+
export interface LocalModelClientOptions {
|
|
8
|
+
modelId: string;
|
|
9
|
+
dtype?: OnnxDtype;
|
|
10
|
+
/** Download / load progress for the UI. */
|
|
11
|
+
onProgress?: (status: string, file: string, progress?: number) => void;
|
|
12
|
+
}
|
|
13
|
+
export declare function webGpuAvailable(): boolean;
|
|
14
|
+
export declare class LocalModelClient implements ChatCompletionClient {
|
|
15
|
+
private readonly opts;
|
|
16
|
+
private worker;
|
|
17
|
+
private nextId;
|
|
18
|
+
private readonly pending;
|
|
19
|
+
constructor(opts: LocalModelClientOptions);
|
|
20
|
+
private getWorker;
|
|
21
|
+
createChatCompletion(messages: ChatMessage[], options?: ChatCompletionOptions): Promise<ChatCompletionResponse>;
|
|
22
|
+
dispose(): void;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/agent/local/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EACV,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,WAAW,EACZ,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACxE;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAOD,qBAAa,gBAAiB,YAAW,oBAAoB;IAK/C,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJjC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;gBAEzB,IAAI,EAAE,uBAAuB;IAE1D,OAAO,CAAC,SAAS;IAuBX,oBAAoB,CACxB,QAAQ,EAAE,WAAW,EAAE,EACvB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,sBAAsB,CAAC;IAiDlC,OAAO,IAAI,IAAI;CAKhB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
export function webGpuAvailable() {
|
|
2
|
+
return typeof navigator !== 'undefined' && 'gpu' in navigator;
|
|
3
|
+
}
|
|
4
|
+
export class LocalModelClient {
|
|
5
|
+
opts;
|
|
6
|
+
worker = null;
|
|
7
|
+
nextId = 1;
|
|
8
|
+
pending = new Map();
|
|
9
|
+
constructor(opts) {
|
|
10
|
+
this.opts = opts;
|
|
11
|
+
}
|
|
12
|
+
getWorker() {
|
|
13
|
+
if (!this.worker) {
|
|
14
|
+
this.worker = new Worker(new URL('./worker.js', import.meta.url), { type: 'module' });
|
|
15
|
+
this.worker.onmessage = (event) => {
|
|
16
|
+
const msg = event.data;
|
|
17
|
+
if (msg.type === 'progress') {
|
|
18
|
+
this.opts.onProgress?.(msg.status, msg.file, msg.progress);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const pending = msg.id !== undefined ? this.pending.get(msg.id) : undefined;
|
|
22
|
+
if (!pending)
|
|
23
|
+
return;
|
|
24
|
+
this.pending.delete(msg.id);
|
|
25
|
+
if (msg.type === 'result')
|
|
26
|
+
pending.resolve(msg);
|
|
27
|
+
else
|
|
28
|
+
pending.reject(new Error(msg.message));
|
|
29
|
+
};
|
|
30
|
+
this.worker.onerror = (e) => {
|
|
31
|
+
this.pending.forEach((p) => p.reject(new Error(e.message || 'local model worker crashed')));
|
|
32
|
+
this.pending.clear();
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return this.worker;
|
|
36
|
+
}
|
|
37
|
+
async createChatCompletion(messages, options = {}) {
|
|
38
|
+
if (!webGpuAvailable()) {
|
|
39
|
+
throw new Error('WebGPU is not available in this browser — local ONNX models need it.');
|
|
40
|
+
}
|
|
41
|
+
const id = this.nextId++;
|
|
42
|
+
const request = {
|
|
43
|
+
type: 'generate',
|
|
44
|
+
id,
|
|
45
|
+
modelId: this.opts.modelId,
|
|
46
|
+
dtype: this.opts.dtype ?? 'q4',
|
|
47
|
+
messages,
|
|
48
|
+
tools: options.tools,
|
|
49
|
+
maxNewTokens: options.maxTokens ?? 1024,
|
|
50
|
+
};
|
|
51
|
+
const worker = this.getWorker();
|
|
52
|
+
const onAbort = () => worker.postMessage({ type: 'abort', id });
|
|
53
|
+
options.signal?.addEventListener('abort', onAbort, { once: true });
|
|
54
|
+
try {
|
|
55
|
+
const result = await new Promise((resolve, reject) => {
|
|
56
|
+
this.pending.set(id, { resolve, reject });
|
|
57
|
+
worker.postMessage(request);
|
|
58
|
+
});
|
|
59
|
+
const message = {
|
|
60
|
+
role: 'assistant',
|
|
61
|
+
content: result.toolCalls.length && !result.content ? null : result.content,
|
|
62
|
+
...(result.toolCalls.length ? { tool_calls: result.toolCalls } : {}),
|
|
63
|
+
};
|
|
64
|
+
return {
|
|
65
|
+
id: `local-${id}`,
|
|
66
|
+
object: 'chat.completion',
|
|
67
|
+
created: Math.floor(Date.now() / 1000),
|
|
68
|
+
model: this.opts.modelId,
|
|
69
|
+
choices: [
|
|
70
|
+
{
|
|
71
|
+
index: 0,
|
|
72
|
+
message,
|
|
73
|
+
finish_reason: result.toolCalls.length ? 'tool_calls' : 'stop',
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
options.signal?.removeEventListener('abort', onAbort);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
dispose() {
|
|
83
|
+
this.worker?.terminate();
|
|
84
|
+
this.worker = null;
|
|
85
|
+
this.pending.clear();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/agent/local/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which models are already in the OPFS weight cache (artipod-models/).
|
|
3
|
+
* Cache files are named encodeURIComponent(<download URL>), so decoding the
|
|
4
|
+
* names and grouping by HF repo id tells us what's downloaded.
|
|
5
|
+
*/
|
|
6
|
+
/** huggingface.co/<org>/<name>/resolve/... → "<org>/<name>"; null for runtime assets. */
|
|
7
|
+
export declare function modelIdFromCacheKey(decodedUrl: string): string | null;
|
|
8
|
+
export interface CachedModel {
|
|
9
|
+
bytes: number;
|
|
10
|
+
/** True once an .onnx/.onnx_data file is present (config-only ≠ downloaded). */
|
|
11
|
+
hasWeights: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function listCachedModels(): Promise<Map<string, CachedModel>>;
|
|
14
|
+
export declare function formatBytes(bytes: number): string;
|
|
15
|
+
//# sourceMappingURL=model-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-cache.d.ts","sourceRoot":"","sources":["../../../src/agent/local/model-cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,yFAAyF;AACzF,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUrE;AAID,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAyB1E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIjD"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which models are already in the OPFS weight cache (artipod-models/).
|
|
3
|
+
* Cache files are named encodeURIComponent(<download URL>), so decoding the
|
|
4
|
+
* names and grouping by HF repo id tells us what's downloaded.
|
|
5
|
+
*/
|
|
6
|
+
const MODELS_DIR = 'artipod-models';
|
|
7
|
+
/** huggingface.co/<org>/<name>/resolve/... → "<org>/<name>"; null for runtime assets. */
|
|
8
|
+
export function modelIdFromCacheKey(decodedUrl) {
|
|
9
|
+
try {
|
|
10
|
+
const url = new URL(decodedUrl);
|
|
11
|
+
if (url.hostname !== 'huggingface.co')
|
|
12
|
+
return null;
|
|
13
|
+
const segments = url.pathname.split('/').filter(Boolean);
|
|
14
|
+
if (segments.length < 4 || segments[2] !== 'resolve')
|
|
15
|
+
return null;
|
|
16
|
+
return `${segments[0]}/${segments[1]}`;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const isWeightsFile = (decodedUrl) => /\.onnx(_data.*)?$/.test(decodedUrl);
|
|
23
|
+
export async function listCachedModels() {
|
|
24
|
+
const cached = new Map();
|
|
25
|
+
if (typeof navigator === 'undefined' || !navigator.storage?.getDirectory)
|
|
26
|
+
return cached;
|
|
27
|
+
try {
|
|
28
|
+
const root = await navigator.storage.getDirectory();
|
|
29
|
+
const dir = await root.getDirectoryHandle(MODELS_DIR);
|
|
30
|
+
const entries = dir.entries();
|
|
31
|
+
for (;;) {
|
|
32
|
+
const { done, value } = await entries.next();
|
|
33
|
+
if (done)
|
|
34
|
+
break;
|
|
35
|
+
const [name, handle] = value;
|
|
36
|
+
if (handle.kind !== 'file')
|
|
37
|
+
continue;
|
|
38
|
+
const decoded = decodeURIComponent(name);
|
|
39
|
+
const modelId = modelIdFromCacheKey(decoded);
|
|
40
|
+
if (!modelId)
|
|
41
|
+
continue;
|
|
42
|
+
const size = (await handle.getFile()).size;
|
|
43
|
+
const entry = cached.get(modelId) ?? { bytes: 0, hasWeights: false };
|
|
44
|
+
entry.bytes += size;
|
|
45
|
+
entry.hasWeights = entry.hasWeights || isWeightsFile(decoded);
|
|
46
|
+
cached.set(modelId, entry);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// no cache dir yet
|
|
51
|
+
}
|
|
52
|
+
return cached;
|
|
53
|
+
}
|
|
54
|
+
export function formatBytes(bytes) {
|
|
55
|
+
if (bytes >= 1e9)
|
|
56
|
+
return `${(bytes / 1e9).toFixed(1)} GB`;
|
|
57
|
+
if (bytes >= 1e6)
|
|
58
|
+
return `${Math.round(bytes / 1e6)} MB`;
|
|
59
|
+
return `${Math.round(bytes / 1e3)} kB`;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=model-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-cache.js","sourceRoot":"","sources":["../../../src/agent/local/model-cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,UAAU,GAAG,gBAAgB,CAAC;AAEpC,yFAAyF;AACzF,MAAM,UAAU,mBAAmB,CAAC,UAAkB;IACpD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;QAChC,IAAI,GAAG,CAAC,QAAQ,KAAK,gBAAgB;YAAE,OAAO,IAAI,CAAC;QACnD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACzD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QAClE,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,aAAa,GAAG,CAAC,UAAkB,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAQnF,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC9C,IAAI,OAAO,SAAS,KAAK,WAAW,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,YAAY;QAAE,OAAO,MAAM,CAAC;IACxF,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;QACpD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;QACtD,MAAM,OAAO,GAAI,GAAmF,CAAC,OAAO,EAAE,CAAC;QAC/G,SAAS,CAAC;YACR,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YAC7C,IAAI,IAAI;gBAAE,MAAM;YAChB,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC;YAC7B,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM;gBAAE,SAAS;YACrC,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;YAC7C,IAAI,CAAC,OAAO;gBAAE,SAAS;YACvB,MAAM,IAAI,GAAG,CAAC,MAAO,MAA+B,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC;YACrE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;YACrE,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC;YACpB,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC;YAC9D,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,mBAAmB;IACrB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,IAAI,KAAK,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAC1D,IAAI,KAAK,IAAI,GAAG;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;IACzD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-browser ONNX model registry: curated tool-capable defaults merged with
|
|
3
|
+
* a live query of the Hugging Face Hub (the de-facto ONNX model registry —
|
|
4
|
+
* CORS-enabled REST API), so the dropdown stays current without shipping a
|
|
5
|
+
* hardcoded list.
|
|
6
|
+
*/
|
|
7
|
+
/** Quantizations Transformers.js accepts for ONNX models. */
|
|
8
|
+
export type OnnxDtype = 'auto' | 'q4' | 'q4f16' | 'q8' | 'int8' | 'uint8' | 'fp16' | 'fp32';
|
|
9
|
+
export interface LocalModelInfo {
|
|
10
|
+
/** HF repo id, e.g. onnx-community/Qwen2.5-1.5B-Instruct */
|
|
11
|
+
id: string;
|
|
12
|
+
label: string;
|
|
13
|
+
/** Approximate q4 download size, shown in the picker. */
|
|
14
|
+
approxSize?: string;
|
|
15
|
+
/** ONNX quantization to request. */
|
|
16
|
+
dtype: OnnxDtype;
|
|
17
|
+
curated: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare const CURATED_MODELS: LocalModelInfo[];
|
|
20
|
+
export declare const DEFAULT_LOCAL_MODEL: string;
|
|
21
|
+
/** Curated list first, then popular Hub extras; Hub failure degrades to curated. */
|
|
22
|
+
export declare function listLocalModels(fetchFn?: typeof fetch): Promise<LocalModelInfo[]>;
|
|
23
|
+
export declare function modelInfo(id: string, models: LocalModelInfo[]): LocalModelInfo;
|
|
24
|
+
//# sourceMappingURL=model-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-registry.d.ts","sourceRoot":"","sources":["../../../src/agent/local/model-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,6DAA6D;AAC7D,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5F,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,cAAc,EAAE,cAAc,EAsB1C,CAAC;AAEF,eAAO,MAAM,mBAAmB,QAAuB,CAAC;AASxD,oFAAoF;AACpF,wBAAsB,eAAe,CAAC,OAAO,GAAE,OAAO,KAAa,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAiB9F;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,cAAc,CAE9E"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-browser ONNX model registry: curated tool-capable defaults merged with
|
|
3
|
+
* a live query of the Hugging Face Hub (the de-facto ONNX model registry —
|
|
4
|
+
* CORS-enabled REST API), so the dropdown stays current without shipping a
|
|
5
|
+
* hardcoded list.
|
|
6
|
+
*/
|
|
7
|
+
export const CURATED_MODELS = [
|
|
8
|
+
{
|
|
9
|
+
id: 'onnx-community/Qwen2.5-1.5B-Instruct',
|
|
10
|
+
label: 'Qwen2.5 1.5B Instruct (best small tool-caller)',
|
|
11
|
+
approxSize: '~1.8 GB',
|
|
12
|
+
dtype: 'q4',
|
|
13
|
+
curated: true,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: 'onnx-community/Qwen2.5-0.5B-Instruct',
|
|
17
|
+
label: 'Qwen2.5 0.5B Instruct (fastest, weakest)',
|
|
18
|
+
approxSize: '~0.8 GB',
|
|
19
|
+
dtype: 'q4',
|
|
20
|
+
curated: true,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: 'onnx-community/Llama-3.2-1B-Instruct-ONNX',
|
|
24
|
+
label: 'Llama 3.2 1B Instruct',
|
|
25
|
+
approxSize: '~1.7 GB',
|
|
26
|
+
dtype: 'q4',
|
|
27
|
+
curated: true,
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
export const DEFAULT_LOCAL_MODEL = CURATED_MODELS[0].id;
|
|
31
|
+
const HUB_QUERY = 'https://huggingface.co/api/models?author=onnx-community&pipeline_tag=text-generation&sort=downloads&direction=-1&limit=30';
|
|
32
|
+
/** Curated list first, then popular Hub extras; Hub failure degrades to curated. */
|
|
33
|
+
export async function listLocalModels(fetchFn = fetch) {
|
|
34
|
+
const models = [...CURATED_MODELS];
|
|
35
|
+
try {
|
|
36
|
+
const res = await fetchFn(HUB_QUERY);
|
|
37
|
+
if (res.ok) {
|
|
38
|
+
const hub = (await res.json());
|
|
39
|
+
const known = new Set(models.map((m) => m.id));
|
|
40
|
+
for (const { id } of hub) {
|
|
41
|
+
// only instruct/chat-style repos are useful for tool calling
|
|
42
|
+
if (known.has(id) || !/instruct|chat|it-/i.test(id))
|
|
43
|
+
continue;
|
|
44
|
+
models.push({ id, label: id.replace('onnx-community/', ''), dtype: 'q4', curated: false });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// offline / rate-limited: curated list is the fallback
|
|
50
|
+
}
|
|
51
|
+
return models;
|
|
52
|
+
}
|
|
53
|
+
export function modelInfo(id, models) {
|
|
54
|
+
return models.find((m) => m.id === id) ?? { id, label: id, dtype: 'q4', curated: false };
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=model-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-registry.js","sourceRoot":"","sources":["../../../src/agent/local/model-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgBH,MAAM,CAAC,MAAM,cAAc,GAAqB;IAC9C;QACE,EAAE,EAAE,sCAAsC;QAC1C,KAAK,EAAE,gDAAgD;QACvD,UAAU,EAAE,SAAS;QACrB,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,IAAI;KACd;IACD;QACE,EAAE,EAAE,sCAAsC;QAC1C,KAAK,EAAE,0CAA0C;QACjD,UAAU,EAAE,SAAS;QACrB,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,IAAI;KACd;IACD;QACE,EAAE,EAAE,2CAA2C;QAC/C,KAAK,EAAE,uBAAuB;QAC9B,UAAU,EAAE,SAAS;QACrB,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,IAAI;KACd;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAExD,MAAM,SAAS,GACb,2HAA2H,CAAC;AAM9H,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,UAAwB,KAAK;IACjE,MAAM,MAAM,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;QACrC,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAe,CAAC;YAC7C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/C,KAAK,MAAM,EAAE,EAAE,EAAE,IAAI,GAAG,EAAE,CAAC;gBACzB,6DAA6D;gBAC7D,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;oBAAE,SAAS;gBAC9D,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YAC7F,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,uDAAuD;IACzD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,EAAU,EAAE,MAAwB;IAC5D,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC3F,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse tool calls out of small-model chat output into OpenAI shape.
|
|
3
|
+
* Tolerates the two formats our supported templates emit:
|
|
4
|
+
* - Qwen: <tool_call>{"name": "...", "arguments": {...}}</tool_call>
|
|
5
|
+
* - Llama: a bare JSON object {"name": "...", "parameters": {...}}
|
|
6
|
+
*/
|
|
7
|
+
import type { ToolCall } from '../types.js';
|
|
8
|
+
export interface ParsedGeneration {
|
|
9
|
+
content: string;
|
|
10
|
+
toolCalls: ToolCall[];
|
|
11
|
+
}
|
|
12
|
+
export declare function parseGeneration(output: string): ParsedGeneration;
|
|
13
|
+
//# sourceMappingURL=parse-tool-calls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-tool-calls.d.ts","sourceRoot":"","sources":["../../../src/agent/local/parse-tool-calls.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB;AA0BD,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CA2BhE"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
let counter = 0;
|
|
2
|
+
const nextId = () => `local_call_${++counter}_${Date.now().toString(36)}`;
|
|
3
|
+
function toToolCall(raw) {
|
|
4
|
+
if (typeof raw?.name !== 'string' || !raw.name)
|
|
5
|
+
return null;
|
|
6
|
+
const args = raw.arguments ?? raw.parameters ?? {};
|
|
7
|
+
return {
|
|
8
|
+
id: nextId(),
|
|
9
|
+
type: 'function',
|
|
10
|
+
function: {
|
|
11
|
+
name: raw.name,
|
|
12
|
+
arguments: typeof args === 'string' ? args : JSON.stringify(args),
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const TOOL_CALL_BLOCK = /<tool_call>\s*([\s\S]*?)\s*<\/tool_call>/g;
|
|
17
|
+
export function parseGeneration(output) {
|
|
18
|
+
const toolCalls = [];
|
|
19
|
+
const content = output
|
|
20
|
+
.replace(TOOL_CALL_BLOCK, (_match, body) => {
|
|
21
|
+
try {
|
|
22
|
+
const call = toToolCall(JSON.parse(body));
|
|
23
|
+
if (call)
|
|
24
|
+
toolCalls.push(call);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// malformed block: keep it visible as content instead of dropping it
|
|
28
|
+
return _match;
|
|
29
|
+
}
|
|
30
|
+
return '';
|
|
31
|
+
})
|
|
32
|
+
.trim();
|
|
33
|
+
if (toolCalls.length === 0 && content.startsWith('{') && content.endsWith('}')) {
|
|
34
|
+
// Llama-style bare JSON tool call
|
|
35
|
+
try {
|
|
36
|
+
const call = toToolCall(JSON.parse(content));
|
|
37
|
+
if (call)
|
|
38
|
+
return { content: '', toolCalls: [call] };
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// plain JSON-looking prose: fall through
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return { content, toolCalls };
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=parse-tool-calls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-tool-calls.js","sourceRoot":"","sources":["../../../src/agent/local/parse-tool-calls.ts"],"names":[],"mappings":"AAaA,IAAI,OAAO,GAAG,CAAC,CAAC;AAChB,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,cAAc,EAAE,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;AAQ1E,SAAS,UAAU,CAAC,GAAY;IAC9B,IAAI,OAAO,GAAG,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAC5D,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC;IACnD,OAAO;QACL,EAAE,EAAE,MAAM,EAAE;QACZ,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE;YACR,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,SAAS,EAAE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAClE;KACF,CAAC;AACJ,CAAC;AAED,MAAM,eAAe,GAAG,2CAA2C,CAAC;AAEpE,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,MAAM,SAAS,GAAe,EAAE,CAAC;IAEjC,MAAM,OAAO,GAAG,MAAM;SACnB,OAAO,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,IAAY,EAAE,EAAE;QACjD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAC1C,IAAI,IAAI;gBAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,qEAAqE;YACrE,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;SACD,IAAI,EAAE,CAAC;IAEV,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/E,kCAAkC;QAClC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAC7C,IAAI,IAAI;gBAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,yCAAyC;QAC3C,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message protocol between LocalModelClient and the model worker.
|
|
3
|
+
*/
|
|
4
|
+
import type { ChatMessage, ToolCall, ToolDefinition } from '../types.js';
|
|
5
|
+
import type { OnnxDtype } from './model-registry.js';
|
|
6
|
+
export interface GenerateRequest {
|
|
7
|
+
type: 'generate';
|
|
8
|
+
id: number;
|
|
9
|
+
modelId: string;
|
|
10
|
+
dtype: OnnxDtype;
|
|
11
|
+
messages: ChatMessage[];
|
|
12
|
+
tools?: ToolDefinition[];
|
|
13
|
+
maxNewTokens: number;
|
|
14
|
+
}
|
|
15
|
+
export interface AbortRequest {
|
|
16
|
+
type: 'abort';
|
|
17
|
+
id: number;
|
|
18
|
+
}
|
|
19
|
+
export type WorkerRequest = GenerateRequest | AbortRequest;
|
|
20
|
+
export interface ProgressEvent {
|
|
21
|
+
type: 'progress';
|
|
22
|
+
file: string;
|
|
23
|
+
/** 0..100 for determinate files. */
|
|
24
|
+
progress?: number;
|
|
25
|
+
status: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ResultEvent {
|
|
28
|
+
type: 'result';
|
|
29
|
+
id: number;
|
|
30
|
+
content: string;
|
|
31
|
+
toolCalls: ToolCall[];
|
|
32
|
+
}
|
|
33
|
+
export interface ErrorEvent {
|
|
34
|
+
type: 'error';
|
|
35
|
+
id?: number;
|
|
36
|
+
message: string;
|
|
37
|
+
}
|
|
38
|
+
export type WorkerResponse = ProgressEvent | ResultEvent | ErrorEvent;
|
|
39
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/agent/local/protocol.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,YAAY,CAAC;AAE3D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,WAAW,GAAG,UAAU,CAAC"}
|