@indra.ai/deva 1.60.0 → 1.60.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,489 +1,319 @@
1
- # deva
2
-
3
- ## Summary
4
- Deva is a Node.js module designed to simplify the development of multi-agent systems by providing a consistent foundation for agent interactions. With Deva, developers can quickly create and manage a network of agents that can communicate and collaborate seamlessly. Deva offers features such as private and public socket communication, secure encryption, and consistent message passing. It also provides built-in support for interacting with various APIs, including YouTube, Twitter, Discord, IBM Watson, and ChatGPT. By using Deva, developers can save time and resources in building and integrating basic agent functionalities, and focus on developing more advanced features.
5
-
6
- ## Description
7
-
8
- The Deva module is a JavaScript library for building multi-agent systems that can communicate with each other and with external services. It provides a unified API for creating agents and defining their behaviors, and includes tools for handling communication between agents and for integrating with third-party APIs. The Deva module is designed to be flexible and customizable, allowing developers to easily create complex systems that can perform a wide range of tasks, from data collection and analysis to chatbot interactions and image generation. The module is written in JavaScript and can be used with Node.js, making it easy to integrate with other JavaScript libraries and tools.
9
-
10
- ## Core Features
11
- The core features in the @indra.ai deva.core encompass a wide range of functionalities and capabilities. Here's a brief overview of each feature:
12
-
13
- 1. Security Feature
14
- 2. Guard Feature
15
- 3. Defense Feature
16
- 4. Support Feature
17
- 5. Services Feature
18
- 6. Systems Feature
19
- 7. Networks Feature
20
- 8. Legal Feature
21
- 9. Justice Feature
22
- 10. Authority Feature
23
-
24
- These core features work together to provide a comprehensive and robust platform for users, covering essential aspects such as security, support, services, Legal, Authority, and more.
25
-
26
- ## Functions
27
-
28
- 1. **Class Structure:** The code follows an object-oriented programming approach by defining a `Deva` class. This allows for encapsulation of properties and methods related to the agent.
29
- 2. **State Management:** The `Deva` class has a state management system represented by the `_state` property and the `_states` object. It allows the agent to transition between different states and perform actions based on the current state.
30
- 3. **Event System:** The code utilizes an event system by extending the `EventEmitter` class and creating an `events` object. This enables communication and collaboration between different components of the agent and other entities in the system.
31
- 4. **Modularity and Inheritance:** The code demonstrates modularity by separating functionalities into different objects such as `config`, `lib`, `methods`, and `listeners`. It also showcases inheritance by assigning inherited properties to child Deva instances.
32
- 5. **Error Handling:** The code includes an error handling mechanism through the `error` method. It allows for uniform error reporting and the execution of custom error handling logic.
33
- 6. **Promises:** Promises are used in several asynchronous operations, such as initializing the agent, loading Deva models, and handling method calls. Promises ensure that the code can handle asynchronous operations in a structured and controlled manner.
34
- 7. **Event-driven Architecture:** The code follows an event-driven architecture where different events trigger specific actions or callbacks. This enables loose coupling and flexibility in the agent's behavior and interactions with other components.
35
- 8. **Extensibility:** The code provides hooks for custom logic through methods like `onInit`, `onStart`, `onStop`, `onEnter`, `onExit`, and `onDone`. These allow developers to extend the functionality of the agent by adding custom code at specific stages of its lifecycle.
36
- 9. **Messaging and Communication:** The `talk` and `listen` methods facilitate messaging and communication between agents. Agents can ask questions (`ask` method) and receive responses, enabling interaction and collaboration.
37
- 10. **Utility Functions:** The code includes utility functions like generating unique IDs (`uid` method), hashing data (`hash` method), and handling event listeners (`listen`, `once`, `ignore` methods).
38
-
39
- ## contents
40
- - [install](#install) - How to install the deva core.
41
- - [structure](#structure) - Basic structure of `deva`.
42
- - [agent](#agent) - The `agent` object stores the Agent Profile.
43
- - [vars](#vars) - Variables are stored in the `this.vars` object.
44
- - [listeners](#listeners) - Listeners are setup to allow a deva trigger events.
45
- - [devas](#listeners) - This is where sub-devas are loaded into the current deva.
46
- - [modules](#modules) - A `deva` can add modules to add to their functionality.
47
- - [func](#func) - A `deva` the internal functionality is written here.
48
- - [methods](#methods) - Methods expose the `deva` abilities to external commands/calls.
49
- - [states](#states) - There are various states that triger when a `deva` is doing things.
50
- - [utility](#utility) - Interal to a `deva` there are utility functions available to make actions easier like getting a unique id or status.
51
-
52
-
53
- ## install
54
- ```bash
55
- $ npm i @indra.ai/deva --save
56
- ```
57
-
58
- ## structure
59
- ```javascript
60
- import Deva from '@indra.ai/deva';
61
- import pkg from './package.json' with {type:'json'};
62
- const {agent,vars} = pkg.data;
63
-
64
- // set the __dirname
65
- import {dirname} from 'node:path';
66
- import {fileURLToPath} from 'node:url';
67
- const __dirname = dirname(fileURLToPath(import.meta.url));
68
-
69
- const info = {
70
- id: pkg.id,
71
- name: pkg.name,
72
- describe: pkg.description,
73
- version: pkg.version,
74
- url: pkg.homepage,
75
- dir: __dirname,
76
- git: pkg.repository.url,
77
- bugs: pkg.bugs.url,
78
- author: pkg.author,
79
- license: pkg.license,
80
- copyright: pkg.copyright,
81
- };
82
-
83
- const DEVA = new Deva({
84
- info, // info packet to store entity meta information.
85
- agent, // the agent profile from the package data.
86
- vars, // the variables the agent uses from the package data.
87
- utils: {
88
- translate(input) {return input.trim();},
89
- parse(input) {return input.trim();},
90
- process(input) {return input.trim();}
91
- },
92
- listeners: {},
93
- modules: {},
94
- deva: {},
95
- func: {
96
- list(opts) {
97
- return [
98
- "test 1",
99
- "test 2",
100
- "test 3",
101
- ]
102
- }
103
- },
104
- methods: {
105
- list(packet) {
106
- this.context('list', packet.id);
107
- this.action('method', `list:${packet.id}`);
108
- return new Promise((resolve, reject) => {
109
- try {
110
- const data = this.func.data(packet.q);
111
- return resolve({
112
- text: `See Data`,
113
- html: `See Data`,
114
- data,
115
- });
116
- } catch (err) {
117
- return this.error(err, packet, reject);
118
- }
119
- });
120
- }
121
- },
122
- onReady(data, resolve) {
123
- this.prompt(this.vars.messages.ready);
124
- return resolve(data);
125
- },
126
- onError(err, data, reject) {
127
- this.prompt(this.vars.messages.error);
128
- console.log(err);
129
- return reject(err);
130
- }
131
- });
132
- export default DEVA
133
- ```
1
+ # Deva Core
134
2
 
135
- ## agent
3
+ **`@indra.ai/deva` · v1.60.2**
136
4
 
137
- ```javascript
138
- this.agent();
139
- ```
5
+ Deva Core is a Vedic-inspired, event-based, context-aware Feature, Zone, Action and State machine framework for building integrated artificial intelligence agents ("Devas") in Node.js. Every Deva is one `Deva` class instance on a shared event bus. As it works, it moves through named features, zones, actions, states, intents, beliefs and contexts, and it broadcasts each step as an event. Every packet it builds is stamped with cumulative md5, sha256 and sha512 hashes.
140
6
 
141
- ### Data Attributes
142
-
143
- - **id:** The Agent id generated by `this.uid()`.
144
- - **key:** The key to reference the agent by on the network.
145
- - **prompt:** The prompt configuration for the entity.
146
- - **emoji:** The emoji the for the agent.
147
- - **text:** Algorithm,
148
- - **colors:** The colors for the agent on the prompt. As each agent can set custom prompt colors.
149
- - **label:** The label colors for the agent prompt.
150
- - **R:** The red value 0 to 255.
151
- - **G:** The green value 0 to 255.
152
- - **B:** The blue value 0 to 255.
153
- - **text:** The text colors for the agent prompt.
154
- - **R:** The red value 0 to 255.
155
- - **G:** The green value 0 to 255.
156
- - **B:** The blue value 0 to 255.
157
- - **profile:** The Agent profile configuration data.
158
- - **name:** The name of the agent.
159
- - **hashtag:** The hashtag to reference the agent by.
160
- - **title:** Title of the Agent for media display.
161
- - **subtitle:** Subtitle of the agent for extra context.
162
- - **describe:** Short description of the agent to build from.
163
- - **tweet:** The tweet/post that the agent will share about itself.
164
- - **hashtags:** Comma list of hashtags to add when posting tweets/posts.
165
- - **pronouns:** The pronounds the agent will be going by.
166
- - **gender:** The gender of the agent as pronouns are how they identify and gender is their orientation.
167
- - **style:** The personal style that reflects the agent/entity.
168
- - **voice:** The voice profile the entity will use when speaking.
169
- - **system:** The system the entity/agent is assigned to.
170
- - **layout:** The display layout templte the entity uses for their personal presentation.
171
- - **color:** The text color for the presentation layer.
172
- - **bgcolor:** The background color for the entity presentatino layer.
173
- - **emoji:** A graphic that represents the entity personal emoji.
174
- - **avatar:** A graphic that represents the entity/agent personal avatar.
175
- - **image:** A graphic that represents the entity overall image.
176
- - **background:** The background graphic for the presentation layer.
177
- - **owner:** The name of the owner of the agent/entity.
178
- - **creator:** The name of the creator of the agent/entity.
179
- - **created:** The date and time the entity/agent was created.
180
-
181
- ## vars
7
+ > Deva Core is distributed under the **Vedic License Agreement (VLA)**. Read [License](#license) before you use it.
182
8
 
183
- ```javascript
184
- this.vars
185
- ```
9
+ ## Contents
186
10
 
187
- The vars can be use to set local variables for the deva that need to be used in your program.
11
+ 1. [Requirements](#requirements)
12
+ 2. [Install](#install)
13
+ 3. [Quick start](#quick-start)
14
+ 4. [Constructor options](#constructor-options)
15
+ 5. [Lifecycle](#lifecycle)
16
+ 6. [Messaging: question, answer, ask, talk, listen](#messaging)
17
+ 7. [The packet](#the-packet)
18
+ 8. [Stamping and the hash tiers](#stamping-and-the-hash-tiers)
19
+ 9. [The workflow: features, zones, actions, states, intents, beliefs, contexts](#the-workflow)
20
+ 10. [Events](#events)
21
+ 11. [Error handling](#error-handling)
22
+ 12. [Configuration files](#configuration-files)
23
+ 13. [Testing](#testing)
24
+ 14. [Method reference](#method-reference)
25
+ 15. [License](#license)
26
+ 16. [Links and author](#links-and-author)
188
27
 
189
- There are no default variables, so the scope is for you and your imagination to figure out.
28
+ ## Requirements
190
29
 
191
- ### example
192
- ```javascript
193
- vars: {
194
- foo: 'bar',
195
- steps: 10,
196
- strings: 'Some variable string',
197
- adding: 1 + 9 + 11,
198
- objects: {
199
- key: 'key value'
200
- },
201
- arrays: [
202
- 'value 1',
203
- 'value 2',
204
- ]
205
- }
206
- ```
30
+ - Node.js **22 or later** (`engines.node: ">=22"`), npm 9.5.1 or later.
31
+ - ES modules only. The package is `"type": "module"` and uses JSON import attributes (`import x from './x.json' with {type: 'json'}`). `require()` won't work.
32
+ - A **client object that carries a VLA** matching the one in Deva Core's `package.json`. `init()` refuses to start without it (see [Lifecycle](#lifecycle)).
207
33
 
208
- ## listeners
209
- Listeners are what you setup that allow your Deva to communicate with other Deva or parts of your application/system.
34
+ ## Install
210
35
 
211
- ```javascript
212
- this.listeners
36
+ ```bash
37
+ npm install @indra.ai/deva
213
38
  ```
214
39
 
215
- ### default
216
-
217
- Each Deva comes with a set of default listeners to provide basic functionality.
40
+ ## Quick start
218
41
 
219
- ### start
220
- This will trigger an event to start the Deva.
42
+ This is a minimal working Deva with one method. `client.json` is a client file shaped like [`tests/client.json`](tests/client.json). Its `DATA.VLA` must match the `VLA` block in Deva Core's `package.json`.
221
43
 
222
44
  ```javascript
223
- this.talk(`*agent_key*:start`);
224
- ```
225
-
226
- ### stop
227
- This will trigger an event to stop the Deva.
45
+ import Deva from '@indra.ai/deva';
46
+ import Client from './client.json' with {type: 'json'};
228
47
 
229
- ```javascript
230
- this.talk(`*agent_key*:stop`);
231
- ```
48
+ const client = Client.DATA; // must carry a VLA matching the Deva Core package VLA
232
49
 
233
- ### status
234
- This will trigger an event to broadcast the Deva status.
50
+ const hello = new Deva({
51
+ info: {id: 'hello', name: 'Hello Deva', version: '0.0.1', VLA: client.VLA},
52
+ agent: {
53
+ id: 'hello',
54
+ key: 'hello',
55
+ prompt: {emoji: '👋', text: 'hello'},
56
+ profile: {name: 'Hello Deva'},
57
+ },
58
+ config: {hash: {}}, // required: ready() writes this.config.hash[agent.key]
59
+ vars: {context: {}}, // required: context() looks up this.vars.context
60
+ listeners: {
61
+ 'devacore:error'(packet) {
62
+ console.log('error:', packet.error.message);
63
+ },
64
+ },
65
+ methods: {
66
+ greet(packet) {
67
+ return Promise.resolve({text: `hello ${packet.q.text}`});
68
+ },
69
+ },
70
+ async onReady(data, resolve) {
71
+ const packet = await this.question('/greet world');
72
+ console.log(packet.a.text); // hello world
73
+ return resolve(data);
74
+ },
75
+ });
235
76
 
236
- ```javascript
237
- this.talk(`*agent_key*:status`);
77
+ hello.init(client);
238
78
  ```
239
79
 
240
- ## devas
80
+ Run it with `node hello.mjs` and it prints `hello world`. This sample was run against v1.60.2.
241
81
 
242
- ```javascript
243
- this.devas
244
- ```
82
+ Three things to know from this example:
245
83
 
246
- The main object for Deva that are bwlow this Deva.
84
+ - **Do your work from `onReady`, not after `await init()`.** The `init()` promise currently resolves with `undefined` as soon as the client step finishes, before `start`, `enter`, `done` and `ready` have run. `onReady` is the reliable point where the Deva is fully up.
85
+ - **`info`, `config: {hash: {}}` and `vars.context` are effectively required.** Without them `ready()` or `context()` throws. The error handler then calls `context()` again, and the process ends in a stack overflow.
86
+ - **Methods must return a Promise.** `answer()` calls `this.methods[method](packet).then(...)`.
247
87
 
248
- ## modules
88
+ ## Constructor options
249
89
 
250
- The external modules that your Deva might require to function.
90
+ `new Deva(opts)` accepts:
251
91
 
252
- ```javascript
253
- this.modules
254
- ```
92
+ | Option | What it is |
93
+ |---|---|
94
+ | `id` | Instance id. Defaults to `randomUUID()`. |
95
+ | `info` | Package-style info object (`id`, `name`, `version`, `dir`, `VLA`, ...). Returned by `info()`. `info.VLA.uid` goes into every `uid()`. |
96
+ | `agent` | The agent profile: `id`, `key` (the Deva's name on the bus), `prompt`, `profile` (`name`, and optional `warning`, `notice`, `copyright`, `status`, `vectors`, `owner`, `creator`, `salute`). It can also carry custom `zones`, `actions`, `intents`, `beliefs` and `messages`, which are merged in without overwriting the core ones. |
97
+ | `config` | Local config. Needs a `hash` object. Can set `timeout.ask` in ms (default `30000`, `0` disables it). |
98
+ | `vars` | Free-form variables on `this.vars`. `vars.context` maps context keys to display text. |
99
+ | `utils`, `func` | Your helper functions. Bound to the Deva at `init`. |
100
+ | `methods` | Public commands, reachable by `question('/name ...')` or by another Deva's `#key name ...`. Bound at `init`. Each takes a packet and returns a Promise of a string or `{text, html, data}`. |
101
+ | `listeners` | `{eventName: handler}`. Bound and registered on the event bus at `init`. |
102
+ | `devas` | Child Deva instances. They inherit `events`, `lib` and `config` and are `init`'d during `ready`. |
103
+ | `modules` | Third-party modules for your own use. |
104
+ | `events` | An existing `EventEmitter` to share. Defaults to a new one. |
105
+ | `maxListeners` | Passed to `events.setMaxListeners`. Default `0` (unlimited). |
106
+ | Lifecycle hooks | `onInit`, `onStart`, `onEnter`, `onDone`, `onReady`, `onFinish`, `onComplete`, `onStop`, `onClose`, `onLeave`, `onExit`, `onShutdown`, `onError`. |
255
107
 
256
- ## func
257
- The functions that your deva uses to operate. Functions are not exposed through
258
- the api to public access.
108
+ Any other top-level option is copied onto the instance, as long as it doesn't clash with an existing property.
259
109
 
260
- ```javascript
261
- this.func
262
- ```
110
+ ## Lifecycle
263
111
 
264
- ### methods
265
- ```javascript
266
- this.methods
267
- ```
112
+ ### Start-up: `init(client)`
268
113
 
269
- The methods are exposed publicly through the question event that parses a string
270
- and sends a request to the question method that then interacts with functions, modules, and variables.
114
+ 1. Hashes the core package data (md5, sha256, sha512).
115
+ 2. Runs `license_check(client.VLA, core.VLA)`, comparing sha256 hashes of the two VLA objects. On a mismatch it prompts and resolves with `❌ The Provided Client License Is Invalid`, and the Deva stays inactive.
116
+ 3. Marks the Deva active, then inherits into child devas, binds `listeners`/`methods`/`utils`/`func`/`lib`, and registers listeners.
117
+ 4. Runs the client feature chain: `Client`, then `License`, `Error`, `Log`, `Data`, `Report`, `Communication`, `Treasury`, `Justice`, `Authority`, `Legal`, `Owner`, `Security`, `Medical`, `Support`, `Services`, `Systems`, `Networks`, `Veda`, then `Done`. For each one that the client's `features` object defines, the Deva stores `this._<feature>` = `{client_id, client_name, concerns, global, personal}`, where `personal` is the entry under `devas[agent.key]`. Methods found in `client.features[x].methods` are bound into `this.methods`.
118
+ 5. Calls `onInit(data, resolve)` if you defined it, otherwise `start`.
271
119
 
272
- ## states
273
- Provided are a set of state functions that trigger when a Deva is at various states of starting/stopping.
120
+ ### The invoke chain
274
121
 
275
- ### onStart()
122
+ `start`, `enter`, `done`, `ready`, `finish`, `complete`, `stop`, `close`, `leave`, `exit` and `shutdown` all run through `_invoke`. Each step sets the context, zone, action and state to its key, writes a timestamp under that key on the data (`data.start = Date.now()` and so on), re-stamps the data, and emits its `devacore:<key>` event. Then:
276
123
 
277
- The `onStart()` function runs after the `start` function has completed.
124
+ - if an `on<Key>` hook exists, it calls `on<Key>(data, resolve)`, and **the hook decides what happens next**: call the next step (`this.enter(data, resolve)`) or `resolve(data)`;
125
+ - otherwise it moves on to the next step itself.
278
126
 
279
- ```javascript
280
- this.onStart() {
281
- // some code to run when the deva starts.
282
- }
283
- ```
127
+ | Step | Next by default | Hook |
128
+ |---|---|---|
129
+ | start | enter | onStart |
130
+ | enter | done | onEnter |
131
+ | done | ready | onDone |
132
+ | ready | (resolve) | onReady |
133
+ | finish | complete | onFinish |
134
+ | complete | (resolve) | onComplete |
135
+ | stop | close | onStop |
136
+ | close | leave | onClose |
137
+ | leave | exit | onLeave |
138
+ | exit | shutdown | onExit |
139
+ | shutdown | (resolve) | onShutdown |
284
140
 
285
- ### onStop()
141
+ `ready` also stores sha256 hashes of `vars`, `utils`, `listeners`, `modules`, `func` and `methods` in `config.hash[agent.key]`, and `init`s each child Deva in `devas`.
286
142
 
287
- The `onStop()` function runs after the `stop` function has completed.
143
+ `finish` and `complete` wrap every answer (see [Messaging](#messaging)).
288
144
 
289
- ```javascript
290
- this.onStop() {
291
- // some code to run when the deva stops
292
- }
293
- ```
145
+ ### Shutdown: `stop()`
294
146
 
295
- ### onEnter()
147
+ `stop()` returns a Promise and runs `stop`, `close`, `leave`, `exit` and `shutdown`. `exit` clears the inherited feature data (`_license`, `_security`, and so on). `shutdown` removes listeners and pending asks, and clears `modules`, `listeners`, `events`, `_config` and `_active`. After that, the Deva answers most calls with `⭕️ OFFLINE`. With no hooks defined, `await deva.stop()` resolves with the data object, whose `key` is `'shutdown'`.
296
148
 
297
- The `onEnter()` function runs after the `enter` event has fired.
149
+ ## Messaging
298
150
 
299
- ```javascript
300
- this.onEnter() {
301
- // some code to run when the deva is loaded
302
- }
303
- ```
151
+ ### `question(text, data=false)`
304
152
 
305
- ### onExit()
153
+ `question` is the entry point. It returns a Promise and reads the first word of `text`:
306
154
 
307
- The `onExit()`function runs after the `exit` event has fired.
155
+ | Form | Example | What happens |
156
+ |---|---|---|
157
+ | Command (`/`) | `/greet world` | Calls local `methods.greet` through `answer()`. `packet.q.text` is `world`. A `/method:a:b` form puts `['method','a','b']` in `meta.params`. |
158
+ | Ask (`#`) | `#helper shout hi` | Sends the packet to the Deva whose agent key is `helper` and waits for its reply. |
159
+ | Plain text | `hi there` | Calls `methods.question`, if you defined one. |
308
160
 
309
- ```javascript
310
- this.onExit() {
311
- // some code to run when the deva logs out.
312
- }
313
- ```
161
+ Unknown methods resolve to a packet whose `a.text` is `⛔️ METHOD NOT FOUND <agent> <method>`.
314
162
 
315
- ### onDone()
163
+ ### Ask between Devas
316
164
 
317
- The `onDone()`function runs after the `done` event has fired.
165
+ For `#key method text`, the asking Deva emits `key:ask` and waits once on `key:ask:<packet uid>`. The target's `ask(packet)` runs `methods[method]`, builds `packet.a`, and replies on that event. The asker then runs `finish`/`complete` and resolves. Each Deva listens on `<its key>:ask` automatically, as part of the state listeners registered at `init`.
318
166
 
319
- ```javascript
320
- this.onDone() {
321
- // some code to run when the deva logs out.
322
- }
323
- ```
167
+ - If nobody is listening on `key:ask`, it resolves right away with `⛔️ ASK TARGET NOT FOUND`.
168
+ - If no reply comes within `config.timeout.ask` (default 30 s), it resolves with `⛔️ ASK TIMEOUT`.
324
169
 
325
- ### onInit()
170
+ Tested: a parent Deva with `devas: {helper}` asked `#helper shout hi there` and got `HI THERE` back, with `a.meta.key === 'helper'`.
326
171
 
327
- The `onInit()` function runs after the `init()` function has completed.
172
+ ### Events directly
328
173
 
329
- ```javascript
330
- this.onInit() {
331
- // some code to run when the Deva initializes.
332
- }
333
- ```
174
+ - `talk(evt, packet)` emits on the bus and returns `true` if anyone was listening.
175
+ - `listen(evt, callback)`, `once(evt, callback)` and `ignore(evt, callback)` add, add-once and remove listeners.
176
+ - `prompt(text)` emits a stamped `devacore:prompt` packet.
334
177
 
335
- ## utility
178
+ ## The packet
336
179
 
337
- ### question
180
+ A packet resolved from `question()` looks like this (keys in order, verified):
338
181
 
339
- The question event is the functionality that exposes the methods to the outside world. When a deva asks a question the string is parsed into a question format so that commands to access various methods can be exposed.
182
+ ```text
183
+ packet: id, q, a, created, finish, complete, md5, sha256, sha512
184
+ q: id, agent, client, meta{key, method, params}, text, data, created, md5, sha256, sha512
185
+ a: id, agent, client, meta{key, method, params}, text, html, data, created, md5, sha256, sha512
186
+ ```
340
187
 
341
- The `question(packet)` function is a default function that allows the system to ask questions of itself or other Deva.
188
+ - `id` is a `uid()` object, not a string: `uid, time, iso, utc, date, license, fingerprint, client, agent, machine, core_hash, status, warning, notice, vectors, owner, creator, salute, copyright, md5, sha256, sha512`. Use `packet.id.uid` for the id value. `uid(true)` uses a random UUID for `uid`. The default is a time-based numeric id.
189
+ - `agent` and `client` are copies with their own hashes.
190
+ - `finish` and `complete` are timestamps added by those steps.
191
+ - A method's result becomes `a.text`, `a.html` and `a.data`. A plain string result fills `text`.
342
192
 
343
- The function checks the beginning of a string for a `#` to determine wether to issue a command to run a specific method.
193
+ ## Stamping and the hash tiers
344
194
 
345
- See [Question Listener](#question) for usage.
195
+ Deva Core hashes in three tiers, in the order `config.hashes = ['md5', 'sha256', 'sha512']`:
346
196
 
197
+ | Tier | Intended use |
198
+ |---|---|
199
+ | md5 | Fast, everyday (civilian) verification |
200
+ | sha256 | Government and authority verification |
201
+ | sha512 | Military, agency and legal high-security use |
347
202
 
348
- ```javascript
349
- // async await
350
- const question = await this.question('#*agent_key* *method*:*params* *question string*');
351
-
352
- // promises
353
- this.question('#*agent_key* *method*:*params* *question string*').then(response => {
354
- ...
355
- }).catch(err => {
356
- ...
357
- })
358
- ```
203
+ The tiers are **cumulative by design**. Each hash is taken over the object *including the hashes before it*, so sha256 covers md5, and sha512 covers both. Hashes are base64 digests of `JSON.stringify(data)` (see `hash(data, algo)`).
359
204
 
360
- ### uid()
361
- Generates a unique ID that is used in packet transfer and other various ways.
205
+ - `_stamp(data, label='', uid='')` adds the three hashes in order and returns the same object. When a label is given, it logs a `hash` action per tier (`<label>:<algo>:<uid>`).
206
+ - `_unstamp(data)` removes them, logging a `delete` action per tier with `data.id.uid`, or `⛔️ NO ID PROVIDED` if there is none.
207
+ - To re-stamp after a change, `_stamp(_unstamp(data), label, uid)`. Since the tiers are cumulative, stamping twice without unstamping would change the values.
362
208
 
363
- ```javascript
364
- this.uid() // inside the object
209
+ The return path in Core methods is: the `return` action, then the `good` intent, then `_stamp`.
365
210
 
366
- // example
367
- this.vars.id = this.uid()
211
+ A few spots (`init`, `_workflow`, `client()`, `agent()`, `machine()`, `uid()`) hash manually on purpose and are commented as such. Calling `_stamp` there would log a state change from inside the state machinery and overflow the stack.
368
212
 
369
- ```
213
+ ## The workflow
370
214
 
371
- ### talk(evt, resource=false)
215
+ Each call to `feature()`, `zone()`, `action()`, `state()`, `intent()` or `belief()` takes `(value, extra)`. If `value` exists in the matching list, it sets the current value, emits a hashed `devacore:<key>` event with `text` = the list's label plus `extra`, and returns that data. Unknown values are ignored silently. `context(value, extra)` does the same, using `vars.context` for the label, and accepts any value.
372
216
 
373
- The `talk()` function is used when your Deva needs to broadcast an event that other Deva
374
- or functions would be listening for.
217
+ The plural methods return a stamped object whose `value` is the full list. Counts at v1.60.2, with no agent additions:
375
218
 
376
- ```javascript
377
- this.talk('event', resource); // inside the object
378
- deva.talk('event', resource); // outside the object
379
-
380
- // example
381
- const evt_id = this.uid();
382
- const evt_data = {
383
- task_id: 1,
384
- task_name: 'this is blank data',
385
- task_contact: 'joe@schmo.com',
386
- };
387
-
388
- this.talk('big-event', {
389
- id: evt_id,
390
- key: this.me.key,
391
- q: {
392
- bot: this.me,
393
- text: 'text to send to the event',
394
- data: evt_data,
395
- },
396
- created: Date.now(),
397
- });
398
- ```
219
+ | List | Method | Default | Count | Source |
220
+ |---|---|---|---|---|
221
+ | features | `features()` | — | 21 | `config/features.json` |
222
+ | zones | `zones()` | — | 95 | `config/zones.json` |
223
+ | actions | `actions()` | — | 116 | `config/actions.json` |
224
+ | states | `states()` | `offline` | 134 | `config/states.json` |
225
+ | intents | `intents()` | `neutral` | 78 | `config/intents.json` |
226
+ | beliefs | `beliefs()` | `vedic` | 64 | `config/beliefs.json` |
227
+ | contexts | `contexts()` | — | from your `vars.context` | your agent |
399
228
 
400
- ### listen(evt callback)
229
+ The 21 features are `init, agent, client, license, error, log, data, report, communication, treasury, justice, authority, security, medical, legal, owner, support, services, systems, networks, veda`. Each client feature has a getter of the same name (`security()`, `veda()`, ...) that returns a copy of what the client supplied for it.
401
230
 
402
- The `listen` function can assign listeners to the Deva and designate which `callback`
403
- function to run when an event is fired.
231
+ ## Events
404
232
 
405
- Listeners can be set up individually this way or also added to the listeners object
406
- independently.
233
+ All core events are listed in `config/events.json` (25). The ones you'll usually listen to:
407
234
 
408
- ```javascript
409
- this.listen('some-event', this.func.listener);
235
+ `devacore:prompt`, `devacore:error`, `devacore:question`, `devacore:answer`, `devacore:ask`, `devacore:start`, `devacore:enter`, `devacore:done`, `devacore:ready`, `devacore:finish`, `devacore:complete`, `devacore:stop`, `devacore:exit`, `devacore:shutdown`, `devacore:context`, `devacore:feature`, `devacore:zone`, `devacore:action`, `devacore:state`, `devacore:intent`, `devacore:belief`, `devacore:load`, `devacore:unload`.
410
236
 
411
- this.func.listenter = packet => {
412
- console.log('some-event-fired');
413
- };
237
+ Note: at v1.60.2 `close` is mapped to `devacore:leave`, so the close step emits `devacore:leave` too.
414
238
 
415
- ```
239
+ ## Error handling
416
240
 
417
- ### once(evt, callback)
241
+ `err(err, packet, reject)` is the single error path. It sets the `bad` intent and the `error` context, feature, zone, action and state. It emits a stamped `devacore:error` packet carrying `error: {name, message, stack}` and the related packet. Then:
418
242
 
419
- The `once()` function can assign a one-time listener to a function. This is useful when returning data with an id that one Deva has submitted to another Deva. Also very useful for submit responses that are unique to the request.
243
+ - if you defined `onError(err, packet, reject)`, it returns that, and **you own the outcome**. Call `reject` to fail the caller's promise, or the promise stays pending;
244
+ - otherwise it calls `reject(err)`, or returns `Promise.reject(err)`.
420
245
 
421
- ```javascript
422
- this.once(`some-once-event`, this.func.listener)
423
- this.func.listener = packet => {
424
- console.log('some-once-event-fired');
425
- }
246
+ A method that rejects or throws ends up here. Most calls made while the Deva is inactive return or resolve `⭕️ OFFLINE` instead of throwing.
426
247
 
427
- ```
248
+ ## Configuration files
428
249
 
429
- ### ignore(evt, callback)
250
+ | File | Contents |
251
+ |---|---|
252
+ | `config/index.js` | Command char `/`, ask char `#`, `timeout.ask: 30000`, `hashes`, container markers (`::BEGIN`/`::END`), uid salt range, inherit/bind lists, the invoke chain table, defaults |
253
+ | `config/events.json` | Event names |
254
+ | `config/features.json` | Feature labels |
255
+ | `config/zones.json`, `actions.json`, `states.json`, `intents.json`, `beliefs.json` | Workflow labels |
256
+ | `config/msgs.json` | System messages such as `offline`, `noid`, `asktimeout`, `noask`, `method_not_found`, plus default `warning`, `notice` and `copyright` text |
430
257
 
431
- The `ignore()` function removes a listener from the designated event. This is useful for adding and removing events dynamically or as needed.
258
+ Each JSON file has `id`, `title`, `copyright`, `VLA` and `DATA`, and the values are in `DATA`.
432
259
 
433
- ```javascript
434
- this.ignore('ignore-event', this.func.listener);
435
- this.func.listener = packet => {
436
- console.log('ignore-event-fired');
437
- }
260
+ ## Testing
261
+
262
+ ```bash
263
+ npm test
438
264
  ```
439
265
 
266
+ This runs `node tests` (`tests/index.js`), which builds a Deva from `tests/agent.json` and `tests/client.json`, runs it through the lifecycle and a self-test method, and prints the log. **It passes as long as nothing throws. There are no assertions yet.** Real assertion tests are planned.
440
267
 
441
- ### load(agent, opts)
268
+ `examples/hello-world.js` is out of date at v1.60.2. It uses `require()`, so it fails under `"type": "module"`.
442
269
 
443
- To add a Deva dynamically use the `load()` function. This can be utilized to add Deva to an existing Deva after the object has already been created.
270
+ ## Method reference
444
271
 
445
- ```javascript
446
- const opts = {
447
- agent: {...},
448
- vars: {...},
449
- listeners: {...},
450
- deva: {...},
451
- func: {...},
452
- onStart() {},
453
- onStop() {},
454
- onEnter() {},
455
- onExit() {},
456
- }
457
- this.load('deva-name', opts);
458
- ```
459
-
460
- ### unload(agent)
461
- To delete a Deva for any reason use `unload()`. This will delete the Deva and all it's parts from the current Deva.
272
+ These are the public methods whose behavior was checked against v1.60.2.
462
273
 
463
- ```javascript
274
+ | Method | Returns | Notes |
275
+ |---|---|---|
276
+ | `init(client)` | Promise | Starts the Deva. See the `onReady` caveat above. |
277
+ | `question(text, data?)` | Promise&lt;packet&gt; | `/cmd`, `#key method`, or plain text. |
278
+ | `ask(packet)` | — | Answer side of `#` asks. Usually called for you. |
279
+ | `stop()` | Promise | Runs the shutdown chain. |
280
+ | `talk(evt, packet)` | boolean | Emit on the bus. |
281
+ | `listen` / `once` / `ignore` | — | Manage listeners. |
282
+ | `prompt(text)` | stamped data | Emits `devacore:prompt`. |
283
+ | `feature`/`zone`/`action`/`state`/`intent`/`belief(value, extra?)` | data or `undefined` | Set and broadcast. |
284
+ | `context(value, extra?)` | stamped data | Needs `vars.context`. |
285
+ | `features`/`zones`/`actions`/`states`/`intents`/`beliefs`/`contexts()` | stamped `{id, key, value, agent, client, created}` | Full lists. |
286
+ | `agent()` / `client()` | hashed copy | |
287
+ | `info()` / `core()` | stamped copy | |
288
+ | `status()` | string | `<profile.name> active since <date>` |
289
+ | `uid(guid=false)` | uid object | See [The packet](#the-packet). |
290
+ | `hash(data, algo='md5')` | base64 string | `md5`, `sha256`, `sha512` |
291
+ | `_stamp(data, label?, uid?)` / `_unstamp(data)` | same object | See [Stamping](#stamping-and-the-hash-tiers). |
292
+ | `license_check(personalVLA, packageVLA)` | stamped approval or `false` | |
293
+ | `load(key, client)` / `unload(key)` | Promise | Init or stop a child Deva in `devas`. |
294
+ | `err(err, packet, reject?)` | — | See [Error handling](#error-handling). |
464
295
 
465
- this.unload('deva-key');
296
+ Not covered here because they weren't exercised for this README: `help(msg, help_dir)` (reads `<help_dir>/help/<file>.feecting` sections between `::BEGIN:<PART>` and `::END:<PART>`; feecting is Quinn Michaels' own language), `sign(packet)`, `machine()`, and the `lib` helpers (`this.lib.copy`, `formatDate`, and others).
466
297
 
467
- ```
298
+ ## License
468
299
 
469
- ### status()
470
- The `status()` function will return the running status of the current Deva.
300
+ Deva Core is distributed under the **Vedic License Agreement**, version 1.4.2, VLA `23221940810208468106`, owned by Quinn Arjuna America Michaels, through License Deva. The full text is in [LICENSE.md](LICENSE.md). It states, among other things, that:
471
301
 
472
- ### start()
473
- The `start()` function will start the Deva and run the `onStart()` state function.
302
+ - by accessing or using the Software, you agree to its terms;
303
+ - the Software is the sole proprietary property of the Owner;
304
+ - use is subject to a threefold hierarchy: Vedic Law, the Constitution of the United States, and Owner Authority;
305
+ - modification, distribution, sub-licensing, derivative works, reverse engineering, and official, government or commercial use without the Owner's verified authorization are prohibited;
306
+ - unauthorized use is subject to Vedic fines and sanctions.
474
307
 
475
- ### stop()
476
- The `stop()` function will stop the Deva and run the `onStop()` state function.
308
+ Read LICENSE.md in full before you use the Software. This summary isn't a substitute for it.
477
309
 
478
- ### init(deva=false)
479
- The `init()` function will initialize the Deva and run the `onInit()` state function.
310
+ Copyright ©2000-2026 Quinn Arjuna America Michaels; All rights reserved.
480
311
 
481
- ---
312
+ ## Links and author
482
313
 
483
- [Github Repo](https://github.com/indraai/deva)
484
- [Back to indra.ai](https://indra.ai)
314
+ - Repository: https://github.com/indraai/deva
315
+ - Issues: https://github.com/indraai/deva/issues
316
+ - npm: https://www.npmjs.com/package/@indra.ai/deva
317
+ - Homepage: https://indra.ai
485
318
 
486
- Copyright ©2000-2026 Quinn Arjuna America Michaels; All rights reserved.
487
- Owner Signature Required For Lawful Use.
488
- Distributed under VLA:23221940810208468106 LICENSE.md
489
- Friday, October 9, 2026 - 7:47:02 AM PST
319
+ **Author:** Quinn Arjuna America Michaels, Inside The Net, Inc. (quinn@indra.ai)