Languages
Languages are essentially Node.js modules that encapsulate how to retrieve and create content. You can think of them as small edge functions that are executed on the Agents device and that can communicate with different backends and technologies.
Why Deno Compatibility?
Deno compatibility is required because Languages get executed inside a sandbox that the ADAM executor spawns, and since it needs access to internals of ADAM, this needs to be an integrated JavaScript interpreter that is intertwined with the ADAM implementation. We've decided to build this Language engine on Deno of its several advantages:
- Security: Deno is secure by default. No file, network, or environment access (unless explicitly enabled).
- TypeScript Support: Deno supports TypeScript out of the box.
- Standard Modules: Deno provides a set of reviewed (audited) standard modules that are guaranteed to work with Deno.
How to Make Your Language Deno Compatible?
To make your Language Deno compatible, you need to follow these steps:
-
Use ES Modules: Deno uses ES Modules (ESM) instead of CommonJS, which is used by Node.js. So, you need to use
import
andexport
instead ofrequire()
andmodule.exports
. -
Use Node Specifiers: Unlike Node.js, Deno requires the full file name including its extension when importing modules. For example, use
import { serve } from "./server.ts";
instead ofimport { serve } from "./server";
. -
No
node_modules
: Deno doesn't use thenode_modules
directory orpackage.json
. Instead, it imports modules from URLs or file paths. -
Use Built-in Functions and Standard Modules: Deno has several built-in functions and does not rely on a
package.json
. So, you need to use Deno's built-in functions and standard modules instead of npm packages. You can find more about Deno's standard modules here (opens in a new tab).
Remember, making your Language Deno compatible means it can run in more environments and take advantage of the benefits that Deno provides.
Language Templates
To help you get started with creating your own languages, we have provided some templates that you can use as a starting point. These templates are Deno compatible and provide a basic structure for your language.
- Expression Language without DNA template (opens in a new tab)
- Expression Language with DNA template (opens in a new tab)
- Link Language without DNA template (opens in a new tab)
- Link Language with DNA template (opens in a new tab)
You can clone these repositories and modify them to create your own language. Remember to follow the guidelines for making your language Deno compatible.
Creating a Language
There are several types of Languages, but let's start with the most common one – an Expression Language.
Let's create a super simple Readonly
Language that gives you the Open Graph data for a given website.
import type {
Address,
Expression,
ExpressionAdapter,
ReadonlyLanguage,
LanguageContext,
} from "@coasys/ad4m";
import PutAdapter from "./putAdapter.js";
import openGraph from "open-graph-scraper";
class PutAdapter implements ReadonlyLanguage {
getAddress(url: string) {
return url;
}
}
class Adapter implements ExpressionAdapter {
putAdapter: ReadonlyLanguage;
constructor() {
this.putAdapter = new PutAdapter();
}
async get(address: Address): Promise<Expression> {
const url = address.toString();
const data = await openGraph({ url });
return data;
}
}
import type { LanguageContext, Language} from '@coasys/ad4m'
export default function create(context: LanguageContext): Language {
return {
name: 'open-graph',
expressionAdapter: new Adapter(context),
isImmutableExpression: true
} as Language
}