Skip to main content
v2

UI Integration

This page shows end-to-end UI wiring with:

  • React (Vite) in JS + TS
  • Angular (standalone) in TS
  • SSE now + STOMP commented for later switch
1

Call message API

POST to /api/v1/conversation/message using conversationId and message.

2

Subscribe to stream

Use EventSource on /api/v1/conversation/stream/{conversationId}.

3

Refresh timeline

On each stream event, refresh /audit/{conversationId} or trace endpoint.

React Vite (JavaScript)

convengine.api.js
package: src/apifile: src/api/convengine.api.js
JS
App.jsx
package: srcfile: src/App.jsx
JSX
import { useEffect, useState } from "react";
import { subscribeConversationSse } from "./api/convengine.api.js";

export default function App() {
const [conversationId] = useState(crypto.randomUUID());
const [auditVersion, setAuditVersion] = useState(0);

useEffect(() => {
const stream = subscribeConversationSse(conversationId, {
onConnected: () => setAuditVersion((v) => v + 1),
onEvent: () => setAuditVersion((v) => v + 1),
});

// STOMP alternate:
// const stream = subscribeConversationStomp(conversationId, { ... });

return () => stream.close();
}, [conversationId]);

return <div>conversationId={conversationId} auditVersion={auditVersion}</div>;
}

React Vite (TypeScript)

convengine.api.ts
package: src/apifile: src/api/convengine.api.ts
TS
App.tsx
package: srcfile: src/App.tsx
TSX
import { useEffect, useState } from "react";
import { subscribeConversationSse } from "./api/convengine.api";

export default function App() {
const [conversationId] = useState<string>(crypto.randomUUID());
const [auditVersion, setAuditVersion] = useState<number>(0);

useEffect(() => {
const stream = subscribeConversationSse(conversationId, {
onConnected: () => setAuditVersion((v) => v + 1),
onEvent: () => setAuditVersion((v) => v + 1),
onError: () => {},
});

return () => stream.close();
}, [conversationId]);

return <main>auditVersion={auditVersion}</main>;
}

Angular Integration (authored sample)

convengine-api.service.ts
package: src/app/corefile: src/app/core/convengine-api.service.ts
TS
chat.component.ts
package: src/app/features/chatfile: src/app/features/chat/chat.component.ts
TS
chat.component.html
package: src/app/features/chatfile: src/app/features/chat/chat.component.html
HTML
<section class="chat-shell">
<div class="messages">
<div *ngFor="let m of messages" [class.user]="m.role === 'user'" [class.assistant]="m.role === 'assistant'">
{{ m.text }}
</div>
<div *ngIf="typing" class="assistant typing">Agent is typing...</div>
</div>

<div class="composer">
<input [(ngModel)]="message" placeholder="Type message" />
<button (click)="send()" [disabled]="typing">Send</button>
</div>
</section>
React + Angular parity

Keep one shared backend contract for conversationId, payload.type, and audit stage names. Only transport/client wrappers should differ per framework.