prime
This commit is contained in:
@@ -1,3 +1,181 @@
|
||||
# optimus
|
||||
|
||||
A pull based artifact pump that only rebuilds things that are stale
|
||||
A deliberately small project runtime for initialized modules, settings, named artifacts, and transformer-node helpers.
|
||||
|
||||
## Project shape
|
||||
|
||||
A host project provides JSON settings in `./settings/`:
|
||||
|
||||
```text
|
||||
settings/
|
||||
modules.json
|
||||
artifacts.json
|
||||
anything-else.json
|
||||
```
|
||||
|
||||
`modules.json` maps semantic module names to initializer modules:
|
||||
|
||||
```json
|
||||
{
|
||||
"chatter": "./tree/chatter/index.js",
|
||||
"markdown-builder": "./tree/markdown-builder/index.js"
|
||||
}
|
||||
```
|
||||
|
||||
Each module exports an initializer that receives the same shared `utils` object:
|
||||
|
||||
```js
|
||||
module.exports = utils => {
|
||||
function doSomething() {
|
||||
const chatter = utils.loadModule("chatter");
|
||||
const llm = utils.getSettings("llm");
|
||||
}
|
||||
|
||||
return { doSomething };
|
||||
};
|
||||
```
|
||||
|
||||
## Utilities
|
||||
|
||||
### `utils.loadModule(name)`
|
||||
|
||||
Returns the initialized module registered under that semantic name.
|
||||
|
||||
### `utils.getSettings(name)`
|
||||
|
||||
Returns the parsed contents of `./settings/<name>.json`.
|
||||
|
||||
### `utils.hashPayload(value)`
|
||||
|
||||
Returns a SHA-256 hex hash of `JSON.stringify(value)`. No key sorting or normalization is performed.
|
||||
|
||||
### `utils.buildNode(payload, sources = {})`
|
||||
|
||||
Builds a transformer-node packet from a payload and already-loaded source nodes:
|
||||
|
||||
```js
|
||||
const node = utils.buildNode(payload, {
|
||||
hebrew: hebrewNode,
|
||||
guidance: guidanceNode,
|
||||
});
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```json
|
||||
{
|
||||
"sourceHash": {
|
||||
"hebrew": "<hebrewNode.hash>",
|
||||
"guidance": "<guidanceNode.hash>"
|
||||
},
|
||||
"hash": "<hash of payload>",
|
||||
"payload": "<payload>"
|
||||
}
|
||||
```
|
||||
|
||||
Optimus does not persist or validate the node. The owning module decides where its artifacts live and when to rebuild them.
|
||||
|
||||
### `utils.buildBinaryNode(filePath, sources = {})`
|
||||
|
||||
Builds the binary equivalent of a transformer-node packet. The supplied path is kept as the usable binary payload locator, while `hash` is computed from the file bytes:
|
||||
|
||||
```js
|
||||
const node = utils.buildBinaryNode(resolvedCoverPath);
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```json
|
||||
{
|
||||
"sourceHash": {},
|
||||
"hash": "<SHA-256 of file bytes>",
|
||||
"payloadBin": "<filePath>"
|
||||
}
|
||||
```
|
||||
|
||||
Derived binary artifacts can name source nodes in the same way as `buildNode()`:
|
||||
|
||||
```js
|
||||
return utils.buildBinaryNode(pdfPath, {
|
||||
volume: volumeNode,
|
||||
style: styleNode,
|
||||
});
|
||||
```
|
||||
|
||||
`buildBinaryNode()` does not copy the file, interpret the path, or know what kind of binary it represents. It hashes the bytes currently at `filePath` and returns that path unchanged as `payloadBin`.
|
||||
|
||||
## Artifacts
|
||||
|
||||
`settings/artifacts.json` explicitly names the module and public builder function for each top-level artifact:
|
||||
|
||||
```json
|
||||
{
|
||||
"job.en.md": {
|
||||
"module": "unpointed-hebrew-markdown-builder",
|
||||
"builder": "buildMarkdownOutput",
|
||||
"params": ["job", "en"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Build one artifact:
|
||||
|
||||
```bash
|
||||
npx optimus --artifact job.en.md
|
||||
```
|
||||
|
||||
Build every declared artifact:
|
||||
|
||||
```bash
|
||||
npx optimus
|
||||
```
|
||||
|
||||
Artifacts are logical requested outcomes. Their modules own filenames, directories, persistence, cache policy, and dependency behavior.
|
||||
|
||||
A builder may call `utils.setArtifactOutcome("up to date")` (or another concise outcome) before returning. Optimus prints the requested artifact ID before invoking the builder and prints that outcome afterward; builders that do not report one receive the generic `completed — success` result.
|
||||
|
||||
## Invocation setting overlays
|
||||
|
||||
Optimus loads the project defaults from direct `settings/*.json` files. Each filename remains a free-form settings name available through `utils.getSettings(name)`.
|
||||
|
||||
A process can layer one or more JSON overlays on top of those defaults:
|
||||
|
||||
```bash
|
||||
npx optimus --artifact psalms.en.md --setting settings/overlays/remote.json
|
||||
```
|
||||
|
||||
Multiple overlays are applied left-to-right:
|
||||
|
||||
```bash
|
||||
npx optimus --artifact psalms.en.md \
|
||||
--setting settings/overlays/remote.json \
|
||||
--setting settings/overlays/experimental-model.json
|
||||
```
|
||||
|
||||
An overlay is one object whose top-level keys are ordinary settings names:
|
||||
|
||||
```json
|
||||
{
|
||||
"llm": {
|
||||
"host": "remote-box",
|
||||
"model": "remote-model"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Overlay behavior is deliberately small:
|
||||
|
||||
- object over object: recursively overlay properties;
|
||||
- arrays: replace the previous array;
|
||||
- scalars: replace the previous value;
|
||||
- `null`: replace the previous value with `null`;
|
||||
- omitted properties: inherit the value underneath;
|
||||
- an overlay may introduce a new free-form settings name.
|
||||
|
||||
`utils.getSettings("llm")` sees only the resulting effective settings. Modules do not know which values came from defaults versus invocation overlays.
|
||||
|
||||
Overlay paths are resolved relative to the project root unless absolute.
|
||||
|
||||
## Build-all memory behavior
|
||||
|
||||
`buildAll()` awaits each declared artifact sequentially and does not retain prior artifact results. Artifact builders may still return either ordinary values or Promises; the runtime remains compatible with genuinely asynchronous work such as LLM requests.
|
||||
|
||||
Reference in New Issue
Block a user