MCP Terminal Server
by dillip285
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { enableFirebaseTelemetry } from '@genkit-ai/firebase';
import {
FirebaseUserEngagementSchema,
collectUserEngagement,
} from '@genkit-ai/firebase/user_engagement';
import { gemini15Flash, vertexAI } from '@genkit-ai/vertexai';
import { onCallGenkit, onRequest } from 'firebase-functions/https';
import { genkit, z } from 'genkit';
enableFirebaseTelemetry();
const ai = genkit({
plugins: [vertexAI()],
});
export const simpleFlow = ai.defineFlow(
{
name: 'simpleFlow',
inputSchema: z.string(),
outputSchema: z.string(),
},
async (subject) => {
return 'hello world!';
}
);
// No access to secrets (e.g. only works because simpleFlow does not call
// ai.generate). No authPolicy or App Check integration;
export const simple = onCallGenkit(simpleFlow);
const jokeFlow = ai.defineFlow(
{
name: 'jokeFlow',
inputSchema: z.string(),
outputSchema: z.string(),
},
async (subject) => {
const prompt = `Tell me a joke about ${subject}`;
return await ai.run('call-llm', async () => {
const llmResponse = await ai.generate({
model: gemini15Flash,
prompt: prompt,
});
return llmResponse.text;
});
}
);
export const joke = onCallGenkit(
{
secrets: ['apiKey'],
authPolicy: (auth) => auth?.token?.email_verified && auth?.token?.admin,
},
jokeFlow
);
const authFlow = ai.defineFlow(
{
name: 'authFlow',
inputSchema: z.object({ uid: z.string(), input: z.string() }),
outputSchema: z.string(),
},
async ({ input }) => input.toUpperCase()
);
export const auth = onCallGenkit(
{
authPolicy: (auth, input) => !!auth && auth.uid === input.uid,
},
authFlow
);
const streamingFlow = ai.defineFlow(
{
name: 'streamer',
inputSchema: z.number(),
outputSchema: z.string(),
streamSchema: z.object({ count: z.number() }),
},
async (count, { sendChunk }) => {
let i = 0;
for (; i < count; i++) {
await new Promise((r) => setTimeout(r, 1000));
sendChunk({ count: i });
}
return `done: ${count}, streamed: ${i} times`;
}
);
// onCallGenkit automatically handles streaming when passed
// a flow that streams. This example sets invoker to "private",
// which means that IAM enforces access.
export const streamer = onCallGenkit(
{
invoker: 'private',
},
streamingFlow
);
export const streamConsumerFlow = ai.defineFlow(
{
name: 'streamConsumerFlow',
},
async () => {
const { output, stream } = streamingFlow.stream(5);
for await (const chunk of stream) {
console.log(`chunk ${chunk}`);
}
console.log(`Streaming consumer done ${await output}`);
}
);
export const streamConsumer = onCallGenkit(
{
invoker: 'private',
},
streamConsumerFlow
);
export const triggerJokeFlow = onRequest(
{
invoker: 'private',
},
async (req, res) => {
const { subject } = req.query;
console.log('req.query', req.query);
const op = await jokeFlow.run(String(subject), {
context: {
auth: { admin: true },
},
});
console.log('operation', op);
res.send(op);
}
);
/** Example of user engagement collection using Firebase Functions. */
export const collectEngagement = onRequest(
{
memory: '512MiB',
},
async (req, res) => {
await collectUserEngagement(FirebaseUserEngagementSchema.parse(req.body));
res.send({});
}
);