~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/atlibs-agents

agents and atirc modules for atlibs: launch agents from a composition, chat on atirc; pages and the agents service

0
0
main
51 lines · 2.2 KB Raw History
import { BrowserOAuthClient } from '@atproto/oauth-client-browser'
import { Agent } from '@atproto/api'

import './agents-launch.js'
import './agents-list.js'
import { AgentsCubit, SCOPE } from './agents-cubit.js'
import { pageClientId } from 'atlibs/oauth/index.js'

// Wiring only: user events go to the cubit, cubit state goes to the views. One OAuth session, whose
// only scope is minting service auth for the agents service's three methods.
// pageClientId: the loopback client on localhost, ./stage.json's clientId when deployed.
const client = pageClientId(SCOPE).then((clientId) => BrowserOAuthClient.load({ clientId, handleResolver: 'https://bsky.social' }));
const service = new URLSearchParams(location.search).get('service') ?? undefined;
const agents = new AgentsCubit({ client, makeAgent: (session) => new Agent(session), service });
globalThis.agentsCubit = agents;

const show = (id, on) => (document.getElementById(id).style.display = on ? "block" : "none");

async function init() {
	const names = ["agents-launch", "agents-list"];
	await Promise.all(names.map((name) => customElements.whenDefined(name)));
	const views = names.map((name) => document.querySelector(name));

	const on = (type, fn) => document.addEventListener(type, (e) => fn(e.detail ?? {}));
	on("login", ({ username }) => agents.login(username));
	on("set-service", ({ service }) => agents.setService(service).catch((error) => alert(error.message)));
	on("launch", (input) => agents.launch(input));
	on("refresh", () => agents.refresh());
	on("status", ({ rkey }) => agents.status(rkey));
	on("shutdown", ({ rkey, delete: remove }) => agents.shutdown(rkey, remove));
	document.getElementById("logout-nav").onclick = (e) => {
		e.preventDefault();
		agents.logout();
	};

	let previous;
	const render = () => {
		const state = agents.state;
		show("loading", state.session === "loading");
		show("loading-error", state.session === "error");
		document.getElementById("loading-error").innerText = state.error ?? "";
		show("logout-nav", state.session === "signed-in");
		document.getElementById("whoami").innerText = state.did ? `${state.handle ?? ""} ${state.did}` : "";
		for (const view of views) view.render(state, previous);
		previous = state;
	};
	agents.subscribe(render);
	await agents.init();
}

init();