# DIAL — Dialectic Interagent Language v0.1 DIAL is an XML language for structured communicative exchange between humans and AI agents. It encodes the pragmatic layer — what agents DO in exchange, not just what they say. It is a superset of WUCE. WUCE's execution model lives inside . "Dialectic" is used in its classical sense: dia (through) + legein (to speak/reason). Meaning arrived at THROUGH exchange. Not Hegelian opposition. Not two-party restricted. The Socratic/Aristotelian tradition: reasoned discourse as the medium of understanding. ## Root element ## Eight element types (parts of speech) Natural language text OR ... Question text Label [...] raw command here another command Optional confirmation text ... Optional description ... ## Common attributes on all elements id="{string}" — unique within envelope observe="{event-name}" — activates only when this event is yielded by another element yield="{event-names}" — space-separated events emitted when this element resolves addressed-to="{actor}" — target actor; omit = broadcast ## Key rules - Elements without observe= activate immediately (in parallel) - Elements with observe= wait for the named yield - is blocking — gates elements that observe its yield until human responds - is non-blocking — exchange continues regardless of selection - WUCE step observe/yield is scoped inside ; the element itself yields to the outer envelope - values are accessible by context-key in subsequent turns - Any number of parties may participate — DIAL is not restricted to two ## JavaScript package — @wity.ai/dial npm install @wity.ai/dial ### Node.js (synchronous) import { parse, extractProse, DialSession, DialRouter, runStepGraph } from '@wity.ai/dial'; const envelope = parse(aiText); // DialEnvelope | null — synchronous const prose = extractProse(aiText); // string — text outside blocks ### Browser / Vite (async — WASM loaded via fetch) import { parse, extractProse, initDial, DialSession, DialRouter } from '@wity.ai/dial'; // Vite picks up the "browser" export condition automatically. No config needed. await initDial(); // optional pre-load; auto-called on first parse() const envelope = await parse(aiText); // Promise const prose = await extractProse(aiText); // Promise ### DialSession — per-session state const session = new DialSession({ maxResults: 10 }); session.declare(key, value) // store declared context (from ) session.getDeclared() // → Record session.recordResults(results) // append execution results (rolling window) session.getLastResults() // → DialExecutionResult[] session.clear() ### DialRouter — observe/yield-aware element dispatcher const router = new DialRouter() .on('dial-inform', (el, ctx) => { /* el.text, el.render, el.payload */ }) .on('dial-ask', async (el, ctx) => { ctx.emit('choice:yes'); }) .on('dial-execute', async (el, ctx) => { const { results } = await runStepGraph(el.steps, myExecutor); ctx.session.recordResults(results); }) .on('dial-declare', (el, ctx) => { if (el.contextKey) ctx.session.declare(el.contextKey, el.payload ?? el.text); }); await router.route(envelope, session); // ctx.emit(event) — programmatically yield an event from a handler // runStepGraph(steps, executor) — inner observe/yield loop for steps ### DialEnvelope shape (from parse()) { attributes: { version, turn, actor, session }, elements: DialElementNode[], raw: string } ### DialElementNode shape { type, id?, observe?, yield?, addressedTo?, render?, text?, payload?, // dial-inform / dial-declare responseType?, timeout?, options?, // dial-ask steps?, // dial-execute → DialStepNode[] action?, // dial-suggest contextKey?, // dial-declare of?, // dial-acknowledge signal?, // dial-phatic to?, intent? } // dial-delegate ### DialStepNode shape (inside dial-execute) { env, id?, label?, observe?, yield?, command }