@web-applets/sdk 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +98 -19
- package/dist/client.js +11 -4
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
@@ -1,18 +1,96 @@
|
|
1
1
|
# Web Applets
|
2
2
|
|
3
|
-
> An open
|
3
|
+
> An open spec & SDK for creating apps that agents can use.
|
4
4
|
|
5
|
-
🔗 [
|
5
|
+
🔗 [Applets Repo](https://github.com/unternet-co/community-applets) | 🔗 [Mailing List](https://groups.google.com/a/unternet.co/g/community) | 🔗 [Applets Chat Demo](https://github.com/unternet-co/applets-chat)
|
6
6
|
|
7
7
|
## What is it?
|
8
8
|
|
9
|
-
Web Applets is
|
9
|
+
Web Applets is an open specification for building software that both humans and AI can understand and use together. Instead of forcing AI to operate traditional point-and-click apps built for humans, Web Applets creates a new kind of software designed for human-AI collaboration. Think of them a bit like artifacts, but they do stuff!
|
10
10
|
|
11
|
-
|
11
|
+
![Demo of a web applets chatbot](./docs/assets/applets-chat-demo.gif)
|
12
12
|
|
13
|
-
|
13
|
+
Web Applets are modular pieces of web software that:
|
14
14
|
|
15
|
-
|
15
|
+
- **Can be used directly by humans with rich, graphical interfaces**
|
16
|
+
- **Can be understood and operated by AI through a clear protocol**
|
17
|
+
- **Run locally in your environment, not on distant servers**
|
18
|
+
- **Share context and state with their environment**
|
19
|
+
- **Can be freely combined and composed**
|
20
|
+
|
21
|
+
Think of any web software you use today - maps, documents, shopping, calendars - and imagine if instead of visiting these as separate websites, you could pull them into your own environment where both you and AI could use them together seamlessly.
|
22
|
+
|
23
|
+
## Key Features
|
24
|
+
|
25
|
+
- **Built on Web Standards:** Create applets using familiar web technologies (HTML, CSS, JavaScript)
|
26
|
+
- **AI-Native Protocol:** Applets expose their state and actions in a way AI can understand and use
|
27
|
+
- **Rich Interfaces:** Full support for complex graphical UIs, not just text
|
28
|
+
- **Local-First:** Runs in your environment, keeping your data under your control
|
29
|
+
- **Composable:** Applets can work together, sharing context and state
|
30
|
+
- **Open Standard:** Designed for interoperability, not platform lock-in
|
31
|
+
|
32
|
+
Web Applets aims to do for AI-enabled software what the web did for documents - create an open platform where anyone can build, share, and connect applications. We believe the future of software should be built on open collaboration, not tight integration with closed platforms.
|
33
|
+
|
34
|
+
## Example
|
35
|
+
|
36
|
+
This is a simple applet that prints "Hello, [your name]" when given the `set_name` action.
|
37
|
+
|
38
|
+
`index.html`:
|
39
|
+
|
40
|
+
```html
|
41
|
+
<!DOCTYPE html>
|
42
|
+
<html lang="en">
|
43
|
+
<script src="./main.js" type="module"></script>
|
44
|
+
<body>
|
45
|
+
Hello! <span id="name">whoever you are</span>.
|
46
|
+
</body>
|
47
|
+
</html>
|
48
|
+
```
|
49
|
+
|
50
|
+
`main.js`:
|
51
|
+
|
52
|
+
```js
|
53
|
+
import { appletContext } from '@web-applets/sdk';
|
54
|
+
|
55
|
+
// Get view element we want to manipulate
|
56
|
+
const nameElem = document.getElementById('name');
|
57
|
+
|
58
|
+
// Connect to the applet context
|
59
|
+
const applet = appletContext.connect();
|
60
|
+
|
61
|
+
// When the set_name action is called, change the state
|
62
|
+
applet.setActionHandler('set_name', ({ name }) => {
|
63
|
+
applet.setState({ name });
|
64
|
+
});
|
65
|
+
|
66
|
+
// Whenever we get a request to render the view, update the name
|
67
|
+
applet.onrender = () => {
|
68
|
+
nameElem.innerText = applet.state?.name;
|
69
|
+
};
|
70
|
+
```
|
71
|
+
|
72
|
+
`manifest.json`:
|
73
|
+
|
74
|
+
```json
|
75
|
+
{
|
76
|
+
"type": "applet",
|
77
|
+
"name": "Hello World",
|
78
|
+
"description": "Displays a greeting to the user.",
|
79
|
+
"entrypoint": "index.html",
|
80
|
+
"actions": [
|
81
|
+
{
|
82
|
+
"id": "set_name",
|
83
|
+
"description": "Sets the name of the user to be greeted",
|
84
|
+
"params": {
|
85
|
+
"name": {
|
86
|
+
"type": "string",
|
87
|
+
"description": "The name of the user"
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
]
|
92
|
+
}
|
93
|
+
```
|
16
94
|
|
17
95
|
## Getting started
|
18
96
|
|
@@ -135,29 +213,30 @@ applet.state = { name: 'Ada Lovelace' };
|
|
135
213
|
It may also be helpful to check available applets at a domain, or in your public folder. For that you can extract the applet headers from the App Manifest at the public root (`/manifest.json`), and see the available applets and a shorthand for the actions you can take in them. This is automatically created when you build your applets.
|
136
214
|
|
137
215
|
```js
|
138
|
-
const
|
216
|
+
const applets = await applets.list('/');
|
139
217
|
```
|
140
218
|
|
141
|
-
This
|
219
|
+
This applets object looks like:
|
142
220
|
|
143
221
|
```js
|
144
|
-
|
145
|
-
{
|
222
|
+
{
|
223
|
+
'/helloworld.applet': {
|
146
224
|
name: 'Hello World',
|
147
225
|
description: 'Displays a greeting to the user.',
|
148
226
|
url: '/applets/helloworld.applet',
|
149
|
-
actions:
|
150
|
-
{
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
227
|
+
actions: {
|
228
|
+
set_name: {
|
229
|
+
description: 'Sets the name of the user to be greeted',
|
230
|
+
params: {
|
231
|
+
name: {
|
232
|
+
type: 'string',
|
233
|
+
description: 'The name of the user'
|
234
|
+
}
|
156
235
|
},
|
157
|
-
|
236
|
+
},
|
158
237
|
},
|
159
238
|
// ...
|
160
|
-
|
239
|
+
};
|
161
240
|
```
|
162
241
|
|
163
242
|
You can use it to present a quick summary of available tools to your model, and then decide on an applet and action to use.
|
package/dist/client.js
CHANGED
@@ -40,14 +40,18 @@ const defaultOpts = {
|
|
40
40
|
};
|
41
41
|
export async function load(url, container, opts) {
|
42
42
|
const _opts = Object.assign(defaultOpts, opts ?? {});
|
43
|
+
url = parseUrl(url);
|
44
|
+
const manifest = await loadManifest(`${url}`);
|
43
45
|
if (!container) {
|
44
46
|
container = hiddenContainer;
|
45
47
|
_opts.headless = true;
|
46
48
|
}
|
47
|
-
if (
|
49
|
+
if (_opts.unsafe || manifest.unsafe) {
|
50
|
+
container.setAttribute('sandbox', 'allow-scripts allow-forms allow-same-origin');
|
51
|
+
}
|
52
|
+
else {
|
48
53
|
container.setAttribute('sandbox', 'allow-scripts allow-forms');
|
49
|
-
|
50
|
-
const manifest = await loadManifest(`${url}`);
|
54
|
+
}
|
51
55
|
const applet = new Applet();
|
52
56
|
applet.manifest = manifest;
|
53
57
|
applet.actions = manifest.actions;
|
@@ -102,7 +106,10 @@ export class Applet extends EventTarget {
|
|
102
106
|
// }
|
103
107
|
}
|
104
108
|
onstateupdated(event) { }
|
105
|
-
disconnect() {
|
109
|
+
disconnect() {
|
110
|
+
this.onstateupdated = () => { };
|
111
|
+
this.container.src = 'about:blank';
|
112
|
+
}
|
106
113
|
async dispatchAction(actionId, params) {
|
107
114
|
const requestMessage = new AppletMessage('action', {
|
108
115
|
actionId,
|
package/dist/types.d.ts
CHANGED