@mmgt-cloud/ai-client
v1.1.0
Published
Provider-neutral TypeScript client for MMGT Cloud AI.
Maintainers
Readme
@mmgt-cloud/ai-client
Provider-neutral browser and backend client for MMGT Cloud AI. It supports OpenAI Responses, Anthropic Messages and an experimental managed Codex App Server connection without shipping any provider SDK to your application.
pnpm add @mmgt-cloud/ai-clientimport { AIClient } from "@mmgt-cloud/ai-client";
const ai = new AIClient({
baseUrl: "https://api.mmgt.cloud/ai",
appId: import.meta.env.VITE_APP_ID,
tokenProvider: () => session.accessToken,
});
const response = await ai.generate({
connectionId: "connection-id-from-catalog",
model: "model-id-from-catalog",
input: [
{
role: "user",
content: [{ type: "text", text: "Summarize this release." }],
},
],
});Use AIAppClient only on trusted backends with AI_APP_API_KEY. Never expose that key in a browser bundle. Model identifiers and reasoning levels are intentionally strings; discover supported values through catalog() rather than hard-coding provider catalogs.
Public API
catalog(signal?)returns the enabled models. Each model carries the connection ID required by generation requests.upload(blob, signal?)anddeleteFile(fileId, signal?)manage encrypted one-hour input files.generate(request, signal?)performs a stateless non-streaming request.stream(request, signal?)returnsAsyncIterable<AIStreamEvent>with normalized text, reasoning-summary, usage, tool and terminal events.runTools(request, registry, options?)executes declared function tools in your application and continues until completion over one sticky WebSocket connection.AIClientErrorexposes normalizedstatus,code,retryableand provider-safe details.
Streaming and cancellation
const controller = new AbortController();
for await (const event of ai.stream(
{
connectionId: "connection-id-from-catalog",
model: "model-id-from-catalog",
input: [
{
role: "user",
content: [{ type: "text", text: "Explain the deployment." }],
},
],
},
controller.signal,
)) {
if (event.type === "output.text.delta") process.stdout.write(event.delta);
if (event.type === "response.error") console.error(event.error);
}
// controller.abort() cancels the provider request and closes the socket.Files and structured output
const file = await ai.upload(new Blob([report], { type: "text/markdown" }));
try {
const result = await ai.generate({
connectionId: "connection-id-from-catalog",
model: "model-id-from-catalog",
input: [
{
role: "user",
content: [
{ type: "text", text: "Extract the release owner." },
{ type: "file", fileId: file.id },
],
},
],
outputSchema: {
type: "object",
properties: { owner: { type: "string" } },
required: ["owner"],
additionalProperties: false,
},
});
console.log(result.structuredOutput);
} finally {
await ai.deleteFile(file.id);
}Caller-executed tools
const response = await ai.runTools(
{
connectionId: "connection-id-from-catalog",
model: "model-id-from-catalog",
input: [
{
role: "user",
content: [{ type: "text", text: "What time is it in Warsaw?" }],
},
],
tools: [
{
name: "get_time",
description: "Return the current time for an IANA timezone",
parameters: {
type: "object",
properties: { timezone: { type: "string" } },
required: ["timezone"],
},
strict: true,
},
],
},
{
get_time: async (args) => getAuthorizedTime(args),
},
);Tool handlers are trusted application code: validate arguments, authorize every side effect and keep the default iteration limit. Requests are not automatically retried or moved to another provider. Uploaded files are limited to ten per request, 25 MiB each and 50 MiB total.
Every request selects an explicitly enabled connectionId and opaque model ID. Reasoning, output limits, structured output and tools are forwarded to that model through its provider adapter; unsupported combinations produce a normalized provider error. Optional systemPrompt is scoped to that request; MMGT Cloud does not persist defaults or profiles.
