Monday, March 24, 2025

Clear formatting from selected text using keyboard shortcuts in Word

 To clear formatting from selected text using keyboard shortcuts:

  • Press Ctrl + Spacebar to clear character formatting only (such as bold, font and font size) from selected text.
  • Press Ctrl + Q to clear paragraph formatting only (such as indents and line spacing) from selected text.
  • Press Ctrl + Shift + N to reapply the Normal style to selected text.

Sub ResetParagraphFormat()
'
' Reset Selection Paragraph Formatting
'
'
    With Selection.ParagraphFormat
        .Reset
        .LeftIndent = CentimetersToPoints(0)
        .RightIndent = CentimetersToPoints(0)
        .SpaceBefore = 0
        .SpaceBeforeAuto = False
        .SpaceAfter = 0
        .SpaceAfterAuto = False
        .LineSpacingRule = wdLineSpaceSingle
        .Alignment = wdAlignParagraphJustify
        .WidowControl = False
        .KeepWithNext = False
        .KeepTogether = False
        .PageBreakBefore = False
        .NoLineNumber = False
        .Hyphenation = True
        .FirstLineIndent = CentimetersToPoints(0)
        .OutlineLevel = wdOutlineLevelBodyText
        .CharacterUnitLeftIndent = 0
        .CharacterUnitRightIndent = 0
        .CharacterUnitFirstLineIndent = 0
        .LineUnitBefore = 0
        .LineUnitAfter = 0
        .MirrorIndents = False
        .TextboxTightWrap = wdTightNone
        .CollapsedByDefault = False
    End With
End Sub


Sub SelectionClearFormatting()
'
' Clear All Formatting
'
    With Selection
        .ClearFormatting
    End With
End Sub
 

Sub ResetParagraph()
' Removes manual paragraph formatting (formatting not applied using a style).
' If you manually right align a paragraph and the underlying style has a different alignment,
' the Reset method changes the alignment to match the formatting of the underlying style.
    Selection.Paragraphs.Reset
End Sub



 

Saturday, March 22, 2025

Economic Terminology German - English - French - ihk.de

Deutsch
Amerikanisches
Englisch
Britisches
Englisch
Französisch
Aktiengesellschaft (AG)
Stock Corporation (Corp. oder Inc.)
Public Limited Company (Plc)
Société Anonyme (S.A.)
Mitglied des Vorstandes
Member of the Executive Board,
Member of the Board of Management
Member of the Board of Management
Membre du Directoire
Stv. Mitglied des Vorstandes
Deputy Member of the Executive Board,
Deputy Member of the Board of Management
Deputy Member of the Board of Management
Membre Suppléant du Directoire
Vorsitzender des Vorstandes
President and Chief Executive Officer,
Chief Executive Officer,
President,
Chairman of the Executive Board,
Chairman of the Board of Management
Managing Director,
Chief Executive Officer,
Chairman of the Board of Management
Président du Directoire
Stv. Vorsitzender des Vorstandes
Deputy Chairman of the Executive Board,
Deputy Chairman of the Board of Management
Vice Chairman of the Board of Management
Vice-Président du Directoire
Generalbevollmächtigter
General Manager
General Manager
Directeur Général
Arbeitsdirektor
Executive for Labor Relations
Director of the Labour Relations
Directeur des Affaires Sociales
Prokurist
Authorized Officer
Authorised Officer
Fondé de Pouvoir
Handlungsbevoll-
mächtigter
Assistant Manager
Assistant Manager
Mandataire,
Fondé de Pouvoir
Aufsichtsrat
Supervisory Board
Supervisory Board
Conseil de Surveillance
Mitglied des Aufsichtsrates
Member of the Supervisory Board
Member of the Supervisory Board
Membre du Conseil de Surveillance
Vorsitzender des Aufsichtsrates
Chairman of the Supervisory Board
Chairman of the Supervisory Board
Président du Conseil de Surveillance
Stv. Vorsitzender des Aufsichtsrates
Deputy Chairman of the Supervisory Board
Vice Chairman of the Supervisory Board
Vice-Président du Conseil de Surveillance
Verwaltungsrat
Administrative Board
Administrative Board
Conseil d´Administration
Vorsitzender des Verwaltungsrates
Chairman of the Administrative Board
Chairman of the Administrative Board
Président Directeur Général
Beirat
Advisory Board
Advisory Board
Comité Consultatif
Aktionär
Stockholder,
Shareholder
Shareholder
Actionaire
Hauptversammlung
Stockholders Meeting,
Shareholders Meeting
Shareholders´ Meeting,
General Meeting
Assemblée Générale des Actionaires
GmbH
Closed Corporation Privately-Held Corporation
Private Limited Company (Ltd.)
Société à responsabilité limitée (S.A.R.L.)
Geschäftsführer
General Manager,
Managing Director
Director
Gérant
Vorsitzender der Geschäftsführung
Chief Executive Officer,
President,
Chairman of the Board of Management
Chairman of the Board of Directors
Président Directeur Général
Prokurist
Authorized Officer
Authorised Officer
Fondé de Pouvoir Supérieur
Handlungsbevollmächtigter
Assistant Manager
Assistant Manager
Fondé de Pouvoir,
Mandataire
Deutsch
Amerikanisch
Englisch
Französisch
Aufsichtsrat
Supervisory Board
Supervisory Board
Conseil de Surveillance
Beirat
Advisory Board
Advisory Board
Comité Consultatif
Gesellschafter
Stockholder,
Shareholder
Shareholder,
Member
Associé
Gesellschafterversammlung
Stockholders Meeting,
Shareholders Meeting
Shareholders`Meeting,
General Meeting
Assemblée Général des Associés
OHG
Partnership
Partnership
Société en nom collectif
Gesellschafter
Partner
Partner
Associé
Geschäftsführender Gesellschafter
Managing Partner
Managing Partner
Associé Gérant
KG
Limited Partnership
Limited Partnership
Société en commandite simple
Komplementär
General Partner
General Partner
Commandité
Persönlich haftender Gesellschafter
General Partner
General Partner
Commandité
Kommanditist
Limited Partner
Limited Partner
Commanditaire
Geschäftsführender Gesellschafter
Managing Partner
Managing Partner
Associé Gérant
GmbH & Co. KG
Limited Partnership with Limited Company as General Partner
Limited Partnership with Limited Company as General Partner
Société à responsabilité limitée et Co., Société en commandite
Einzelunternehmen / Einzelkaufmann
Sole Proprietorship
Sole Proprietorship,
Sole Trader
Entreprise individuelle / Etablissement
Geschäftsinhaber
Proprietor
Proprietor
Propriétaire exploitant
Geschäftsteilhaber
Co-owner
Co-owner,
Co-Proprietor
Co-Proprétaire
Alleininhaber
Sole Proprietor
Sole Proprietor
Propriétaire
Prokurist
Authorized Officer
Authorised Officer
Fondé de Pouvoir
Verband
Association
Association
Association
Geschäftsführer
Managing Director
Director
Directeur
Hauptgeschäftsführer
General Executive Manager
Managing Director
Secrétaire Général
Präsident
President
President
Président
Vorstand / Präsidium
Board of Directors,
Executive Board
Board of Directors,
Executive Board
Conseil d`Administration
Ehrenvorsitzender
Honorary Chairman of the Board of Directors
Honorary Chairman of the Board of Directors
Président d`Honneur
Vorsitzender
Chairman of the Board of Directors
Chairman of the Executive Board,
Chairman of the Board of Directors
Président du Conseil d`Administration
Hauptausschuss
Executive Committee
Executive Committee
Comité Executif
Sonstige Titel



Abteilungsdirektor
Division Manager
Division Manager
Chef de Division/Département
Handlungsbevollmächtigter
Assistant Manager
Assistant Manager
Fondé de Pouvoir
Bevollmächtigter
Authorized Representative
Authorised Representative
Mandataire
Deutsch
Amerikanisches
Englisch
Britisches
Englisch
Französisch
Leiter der Rechtsabteilung
Head of Legal Department,
General Counsel
Head of the Legal Department,
General Counsel
Chef du Département juridique
Leiter der Personalabteilung
Head of Personnel Department,
Head of Human Resources Department
Head of the Personnel Department,
Director of Personnel
Chef du Personnel,
Directeur du Personnel
Betriebsdirektor
Production Manager
Production Manager
Directeur Technique
Werksleiter
Plant Manager
Works Manager
Directeur d`Usine
Hauptabteilungsleiter
Head of Division
Head of Division
Directeur de Division
Bereichsleiter
Head of Department
Head of Department
Directeur de Département
Betriebsleiter
Production Manager
Production Manager
Chef de Production

Tuesday, March 11, 2025

Romanian NLP

 Table of contents

Unlabeled text Corpora

The FuLG dataset is a comprehensive Romanian language corpus comprising
150 billion tokens, carefully extracted from Common Crawl. 

arXiv

Part of a large multilanguage corpus originated from Common Crawl.
It's a raw, unannotated corpus. It has roughly 50 GB of Romanian text
in 4.5 million documnets. For details check its homepage 
and the paper

arXiv Homepage

 Similar to Oscar, part of a multilanguage corpus also based on Common Crawl
 from 2018. Romanian text is 16GB large

arXiv Homepage

  Romanian language wikipedia dump. 
  A collection of varoius unannotated corpora collected around 2018-2019.
  Includes books, scraped newspapers and juridical documents  
  A collection of written and spoken text from various
  sources: Articles, Fairy tales, Fiction, History, Theatre, News
 Romanian national legilation from  1881 to 2021. The corpus
 includes mainly: governmental decisions, ministerial orders,
 decisions, decrees and laws.
 Automatically annotated for Named Entities

ACL Homepage

Mega-COV is a billion-scale dataset from Twitter for studying COVID-19. It is available in over 100+ languages, Romanian being one of them. Tweets need to be rehydrated

arXiv Medium

A corpus of Romanian tweets related to COVID and vaccination against COVID, created and collected between January 2021 and February 2022. It contains 19319 tweets.

Minutes of the Sittings of the Chamber of Deputies of Romania (2016-2018)
Unannotated corpus
contains 500k+ instances of speech from the parliament podium from
1996 to 2018. Sentence splitting and deduplication onm sentence level
have been applied as processing steps
Unannotated corpus
Romanian presidential discouses (1990-2020) split in 4 files
one for each president. Unannotated corpus
Monolingual Romanian corpus, including content from public websites related to culture

Monolingual (ron) corpus, containing 38063991 tokens and 854096 lexical types in the law domain.

Monolingual Romanian corpus, containing 360833 sentences (9064764 words) in the public administration domain.

The New Civil Procedure Code in Romanian (monolingual) comprising 297888 words.

The Romanian updated criminal code: text with law content.

news articles dataset from romanian newssites title, summary and article

multi-language corpus from online available news sources. It contains also 43mil words in Romanian language from Twitter, Blogs and Newspapers

Homepage

The Romanian novel collection for ELTeC, the European Literary Text Collection Sources: Biblioteca Metropolitana din Bucuresti, Biblioteca Universitara "Mihai Eminescu" din Iasi, Biblioteca Judeteana din Botosani, personal micro-collections uploaded on Zenodo under the following labels: "Hajduks Library"; "RomanianNovel Library"; "CityMysteries Library"; "BibliotecaDHL_Iasi"

Public dataset of 1447 manually annotated Romanian business-oriented emails. The corpus is annotated with 5 token-related labels, as well as 5 sequence-related classes

MDPI

The corpus consists of texts written by Romanian authors between 19th century and present, representing stories, short-stories, fairy tales and sketches. The current version contains 19 authors, 1263 full texts and 12516 paragraphs of around 200 words each, preserving paragraphs integrity.

A dataset containing 400 Romanian texts written by 10 authors The dataset contains stories, short stories, fairy tales, novels, articles, and sketches written by Ion Creangă, Barbu Ştefănescu Delavrancea, Mihai Eminescu, Nicolae Filimon, Emil Gârleanu, Petre Ispirescu, Mihai Oltean, Emilia Plugaru, Liviu Rebreanu, Ioan Slavici.

MDPI

891 Cooking Recipes in Romanian Language

Semantic Textual Similarity / Paraphrasing

Semantic Textual Similarity dataset for the Romanian language RO-STS contains 8,628 sentence pairs with their similarity scores

NeurIPS

A paraphprase corpus created from 10 different Romanian language Bible versions. The final dataset contains 904,815 similar records and 218,977 non matching records, totaling 1,123,927

Around ~100k examples of paraphrases. No clear explanation on how the dataset was built

A multi-language paraphrase corpus for 73 languages extracted from the Tatoeba database. It has ~ 2000 romanian phrases totaling 941 paraphrase groups.

ACL Homepage

Natural Language Inference

We introduce the first Romanian NLI corpus (RoNLI) comprising 58K training sentence pairs, which are obtained via distant supervision, and 6K validation and test sentence pairs, which are manually annotated with the correct labels. ACL

The repository seems to be just an attempt at starting to build the dataset

Summarization

Around ~72k Full texts and their summary. Source seems to be news websites. No description or explanation available

Dialect and regional speech identification

varied compilation of speech samples from five distinct regions of Romania, covering both urban and rural environments. Around 2800 records labeled with age, gender and type of dialect

arXiv

MOROCO: The Moldavian and Romanian Dialectal Corpus The MOROCO data set contains Moldavian and Romanian samples of text collected from the news domain. The samples belong to one of the following six topics: culture, finance, politics, science, sports, tech totaling over 32.000 labeled records

arXiv

Named Entity Recognition (NER)

Autorship Attribution

Sentiment Analysis

Dependency Parsing

Diacritics Restoration / Grammar Correction

Fake News / Clickbait / Satirical News

Offensive Language

manually annotated 4,052 comments on a Romanian local news website into one of the following classes: non-offensive, targeted insults, racist, homophobic, and sexist.

arXiv

4455 organic generated comments from Facebook live broadcasts annotated not binary offensive language detection tasks and for fine-grained offensive language detection

IEEE

4800 Romanian comments annotated with offensive text spans Offensive span detection

MDPI

3860 labeled hate speech records

Dataset consists of 5000 tweets, from which 924 were labeled as offensive (18.48 %) and 4076 tweets as non-offensive.

ACL

The corpus contains 39 245 tweets, annotated by multiple annotators, following the sexist label set of a recent study.

ACL

Questions and Answers

This dataset is just the translation of the gsm8k dataset. GSM8K (Grade School Math 8K) is a dataset of 8.5K high quality linguistically diverse grade school math word problems. There is no information on the quality of the translation

RoCode, a competitive programming dataset, consisting of 2,642 problems written in Romanian, 11k solutions in C, C++ and Python and comprehensive testing suites for each problem. The purpose of RoCode is to provide a benchmark for evaluating the code intelligence of language models trained on Romanian / multilingual text as well as a fine-tuning set for pretrained Romanian models.

arXiv

Spelling, Dictionaries and Gramatical Errors

Synthetic dataset with ~1.9M records. Altered and correct statement as columns

Romanian Archaisms Regionalisms Lexicon containing ~ 1940 Word definitions

Romanian Rules for Dialects - 1940 regionalisms, meanings and the region of provenience

Monday, March 10, 2025

Run Gemini Nano Locally in Google Chrome

 Running Gemini Nano in Google Chrome doesn't require any data network.

Requirements

A "desktop platform" with

  • Recent operating system (OS) version
  • 22+ GB on the volume that contains your Chrome profile.
  • GPU
  • 4 GB Video RAM
Requirements for Gemini Nano in Google Chrome

Download Google Chrome for Developers

To run Gemini Nano in Google Chrome you will have to download a special version of Google Chrome — Google Chrome for developers / Canary.

Download Google Chrome for Developers from Dev channel (or Canary channel), version at least 128.0.6545.0.

Check the version by typing chrome://version it into the URL bar and pressing Enter.

Enable Feature Flags & Check For Updates

Enable two feature flags :

  1. Prompt API — To send natural language instructions to an instance of Gemini Nano in Chrome.
  2. On-device model — To bypass performance checks that might get in the way of downloading Gemini Nano on your device.

On-device model Flag

Open a new tab in Chrome, go to chrome://flags/#optimization-guide-on-device-model

Select Enabled BypassPerfRequirement to facilitate a smooth download of Gemini Nano on your laptop.

None

Relaunch Google Chrome for Developers.

Prompt API Flag

Open a new tab in Chrome, go to chrome://flags/#prompt-api-for-gemini-nano to Enabled.

None

If you do not see "Optimization Guide On Device Model" listed, you may need to wait 1–2 days before it shows up (this was the case for me).

Relaunch Google Chrome for Developers.

Check For Updates

At this point, it's good to check for updates. As said above, this is an experimental feature and might change over time even with short notice.

Go to chrome://components and click "Check for Update" on "Optimization Guide On Device Model"

None

The version should be greater or equal to 2024.5.21.1031.

If you do not see "Optimization Guide On Device Model" listed, you may need to wait a few minutes or some hours (this was the case for me).

Once the model has downloaded go to the next step: Run Gemini Nano in Google Chrome.

Run Gemini Nano in Google Chrome

To verify that everything is working correctly, open the browser console e.g. DevTools (Shift + CTRL + J on Windows/Linux or Option + ⌘ + J on macOS) and run the following code:

(await ai.languageModel.capabilities()).available;

If this returns "readily", then you are all set.

If it fails, we need to force Chrome to recognize that we want to use this API.

So, from the same console send the following code:

await ai.languageModel.create();

This will likely fail but apparently it's intended.

Relaunch Google Chrome for Developers.

Then go through the Check For Updates section again.

Use Gemini Nano With UI

At this point, you are ready to try the built-in version of Gemini Nano on Chrome for developers!

You can find an intuitive UI using the Chrome Dev Playground.

Chrome Dev Playground.

Use Gemini Nano APIs

Try out the API by simply using it in the browser console.

Start by checking if it's possible to create a session based on the availability of the model, and the characteristics of the device.

In the browser console, run:

const {available, defaultTemperature, defaultTopK, maxTopK } = await ai.languageModel.capabilities();

if (available !== "no") {
  const session = await ai.languageModel.create();

  // Prompt the model and wait for the whole result to come back.  
  const result = await session.prompt("Tell me a German joke");
  console.log(result);
}

Built-in AI models guarantee certain benefits over using models online:

  • Virtually Zero Costs
  • Faster Response Time
  • Offline availability
  • Local processing of sensitive data

This early preview of Gemini Nano allows text interactions. Naturally, the quality of the output does not match the quality of bigger LLM models...

The core object is window.ai. It has three core methods:

  • canCreateTextSession
  • createTextSession
  • textModelInfo

If you first check for window.ai, you could then use canCreateTextSession to see if AI support is really ready, if it iss on a supported browser and the model has been loaded. This does not return true, but... readily.

textModelInfo returns information about the model:

{
    "defaultTemperature": 0.800000011920929,
    "defaultTopK": 3,
    "maxTopK": 128
}
Finally: createTextSession.
const model = await window.ai.createTextSession();
await model.prompt("Who are you?"); 
promptStreaming method is for working with a streamed response.
Example: 
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>

<h2>window.ai demo</h2>

<div x-data="app">
	<div x-show="!hasAI">
		Sorry, no AI for you. Have a nice day.
	</div>
	<div x-show="hasAI">
		<div class="row">
			<div class="column">
				<label for="prompt">Prompt: </label>
			</div>
			<div class="column column-90">
			<input type="text" x-model="prompt" id="prompt">
			</div>
		</div>
		<button @click="testPrompt">Test</button>
		<p x-html="result"></p>
	</div>
</div> 
document.addEventListener('alpine:init', () => {
  Alpine.data('app', () => ({
		hasAI:false,
		prompt:"",
		result:"",
		session:null,
		async init() {
			if(window.ai) {
				let ready = await window.ai.canCreateTextSession();
				if(ready === 'readily') this.hasAI = true;
				else alert('Browser has AI, but not ready.');
				this.session = await window.ai.createTextSession();
			}
		},
		async testPrompt() {
			if(this.prompt === '') return;
			console.log(`test ${this.prompt}`);
			this.result = '<i>Working...</i>';
			try {
				this.result = await this.session.prompt(this.prompt);
			} catch(e) {
				console.log('window.ai error', e);
			}
		}
  }))
}); 
Text summarization:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>

<h2>window.ai demo</h2>

<div x-data="app">
  <div x-show="!hasAI">
    Sorry, no AI for you. Have a nice day.
  </div>
  <div x-show="hasAI">
    <p>
      <label for="inputText">Enter the text you would like summarized below:</label>
      <textarea x-model="inputText" id="inputText"></textarea>
    </p>

    <button @click="testSummarize">Summarize</button>
    <p x-html="result"></p>
  </div>
</div>
 document.addEventListener('alpine:init', () => {
  Alpine.data('app', () => ({
    hasAI:false,
    inputText:"",
    result:"",
    session:null,
    async init() {
      if(window.ai) {
        let ready = await window.ai.canCreateTextSession();
        if(ready === 'readily') this.hasAI = true;
        else alert('Browser has AI, but not ready.');
        this.session = await window.ai.createTextSession();
      }
    },
    async testSummarize() {
      if(this.inputText === '') return;
      this.result = '<i>Working...</i>';
      try {
        let prompt = `Summarize the following text:
        
${this.inputText}`;
        this.result = await this.session.prompt(prompt);
      } catch(e) {
        console.log('window.ai error', e);
      }
    }
  }))
});
-------
const session = await ai.languageModel.create();

// Prompt the model and wait for the whole result to come back.
const result = await session.prompt("Write me a poem.");
console.log(result);

// Prompt the model and stream the result:
const stream = await session.promptStreaming("Write me an extra-long poem.");
for await (const chunk of stream) {
console.log(chunk);

System prompts

The language model can be configured with a special "system prompt" which gives it the context for future interactions:
const session = await ai.languageModel.create({
  systemPrompt: "Pretend to be an eloquent hamster."
});

console.log(await session.prompt("What is your favorite food?"));

The system prompt is special, in that the language model will not respond to it, and it will be preserved even if the context window otherwise overflows due to too many calls to prompt().

If the system prompt is too large, then the promise will be rejected with a QuotaExceededError exception.

N-shot prompting

If developers want to provide examples of the user/assistant interaction, they can use the initialPrompts array. This aligns with the common "chat completions API" format of { role, content } pairs, including a "system" role which can be used instead of the systemPrompt option shown above.

 const session = await ai.languageModel.create({
  initialPrompts: [
    { role: "system", content: "Predict up to 5 emojis as a response to a comment. Output emojis, comma-separated." },
    { role: "user", content: "This is amazing!" },
    { role: "assistant", content: "❤️, ➕" },
    { role: "user", content: "LGTM" },
    { role: "assistant", content: "👍, 🚢" }
  ]
});

// Clone an existing session for efficiency, instead of recreating one each time.
async function predictEmoji(comment) {
  const freshSession = await session.clone();
  return await freshSession.prompt(comment);
}

const result1 = await predictEmoji("Back to the drawing board");

const result2 = await predictEmoji("This code is so good you should get promoted");

(Note that merely creating a session does not cause any new responses from the language model. We need to call prompt() or promptStreaming() to get a response.)

Some details on error cases:

  • Using both systemPrompt and a { role: "system" } prompt in initialPrompts, or using multiple { role: "system" } prompts, or placing the { role: "system" } prompt anywhere besides at the 0th position in initialPrompts, will reject with a TypeError.
  • If the combined token length of all the initial prompts (including the separate systemPrompt, if provided) is too large, then the promise will be rejected with a QuotaExceededError exception.

Customizing the role per prompt

Our examples so far have provided prompt() and promptStreaming() with a single string. Such cases assume messages will come from the user role. These methods can also take in objects in the { role, content } format, or arrays of such objects, in case you want to provide multiple user or assistant messages before getting another assistant message:

 const multiUserSession = await ai.languageModel.create({
  systemPrompt: "You are a mediator in a discussion between two departments."
});

const result = await multiUserSession.prompt([
  { role: "user", content: "Marketing: We need more budget for advertising campaigns." },
  { role: "user", content: "Finance: We need to cut costs and advertising is on the list." },
  { role: "assistant", content: "Let's explore a compromise that satisfies both departments." }
]);

// `result` will contain a compromise proposal from the assistant.

Emulating tool use or function-calling via assistant-role prompts

A special case of the above is using the assistant role to emulate tool use or function-calling, by marking a response as coming from the assistant side of the conversation:

 const session = await ai.languageModel.create({
  systemPrompt: `
    You are a helpful assistant. You have access to the following tools:
    - calculator: A calculator. To use it, write "CALCULATOR: <expression>" where <expression> is a valid mathematical expression.
  `
});

async function promptWithCalculator(prompt) {
  const result = await session.prompt(prompt);

  // Check if the assistant wants to use the calculator tool.
  const match = /^CALCULATOR: (.*)$/.exec(result);
  if (match) {
    const expression = match[1];
    const mathResult = evaluateMathExpression(expression);

    // Add the result to the session so it's in context going forward.
    await session.prompt({ role: "assistant", content: mathResult });

    // Return it as if that's what the assistant said to the user.
    return mathResult;
  }

  // The assistant didn't want to use the calculator. Just return its response.
  return result;
}

console.log(await promptWithCalculator("What is 2 + 2?"));

Multimodal inputs

All of the above examples have been of text prompts. Some language models also support other inputs. Our design initially includes the potential to support images and audio clips as inputs. This is done by using objects in the form { type: "image", content } and { type: "audio", content } instead of strings. The content values can be the following:

  • For image inputs: ImageBitmapSource, i.e. Blob, ImageData, ImageBitmap, VideoFrame, OffscreenCanvas, HTMLImageElement, SVGImageElement, HTMLCanvasElement, or HTMLVideoElement (will get the current frame). Also raw bytes via BufferSource (i.e. ArrayBuffer or typed arrays).

  • For audio inputs: for now, Blob, AudioBuffer, or raw bytes via BufferSource. Other possibilities we're investigating include HTMLAudioElement, AudioData, and MediaStream, but we're not yet sure if those are suitable to represent "clips": most other uses of them on the web platform are able to handle streaming data.

Sessions that will include these inputs need to be created using the expectedInputs option, to ensure that any necessary downloads are done as part of session creation, and that if the model is not capable of such multimodal prompts, the session creation fails. (See also the below discussion of expected input languages, not just expected input types.)

const session = await ai.languageModel.create({
  // { type: "text" } is not necessary to include explicitly, unless
  // you also want to include expected input languages for text.
  expectedInputs: [
    { type: "audio" },
    { type: "image" }
  ]
});

const referenceImage = await (await fetch("/reference-image.jpeg")).blob();
const userDrawnImage = document.querySelector("canvas");

const response1 = await session.prompt([
  "Give a helpful artistic critique of how well the second image matches the first:",
  { type: "image", content: referenceImage },
  { type: "image", content: userDrawnImage }
]);

console.log(response1);

const audioBlob = await captureMicrophoneInput({ seconds: 10 });

const response2 = await session.prompt([
  "My response to your critique:",
  { type: "audio", content: audioBlob }
]);

Future extensions may include more ambitious multimodal inputs, such as video clips, or realtime audio or video. (Realtime might require a different API design, more based around events or streams instead of messages.)

Details:

  • Cross-origin data that has not been exposed using the Access-Control-Allow-Origin header cannot be used with the prompt API, and will reject with a "SecurityError" DOMException. This applies to HTMLImageElement, SVGImageElement, HTMLVideoElement, HTMLCanvasElement, and OffscreenCanvas. Note that this is more strict than createImageBitmap(), which has a tainting mechanism which allows creating opaque image bitmaps from unexposed cross-origin resources. For the prompt API, such resources will just fail. This includes attempts to use cross-origin-tainted canvases.

  • Raw-bytes cases (Blob and BufferSource) will apply the appropriate sniffing rules (for images, for audio) and reject with a "NotSupportedError" DOMException if the format is not supported. This behavior is similar to that of createImageBitmap().

  • Animated images will be required to snapshot the first frame (like createImageBitmap()). In the future, animated image input may be supported via some separate opt-in, similar to video clip input. But we don't want interoperability problems from some implementations supporting animated images and some not, in the initial version.

  • For HTMLVideoElement, even a single frame might not yet be downloaded when the prompt API is called. In such cases, calling into the prompt API will force at least a single frame's worth of video to download. (The intent is to behave the same as createImageBitmap(videoEl).)

  • Text prompts can also be done via { type: "text", content: aString }, instead of just aString. This can be useful for generic code.

  • Attempting to supply an invalid combination, e.g. { type: "audio", content: anImageBitmap }, { type: "image", content: anAudioBuffer }, or { type: "text", content: anArrayBuffer }, will reject with a TypeError.

  • As described above, you can also supply a role value in these objects, so that the full form is { role, type, content }. However, for now, using any role besides the default "user" role with an image or audio prompt will reject with a "NotSupportedError" DOMException. (As we explore multimodal outputs, this restriction might be lifted in the future.)

Structured output or JSON output

To help with programmatic processing of language model responses, the prompt API supports structured outputs defined by a JSON schema.

 const session = await ai.languageModel.create();

const responseJSONSchemaObj = new AILanguageModelResponseSchema({
  type: "object",
  required: ["Rating"],
  additionalProperties: false,
  properties: {
    Rating: {
      type: "number",
      minimum: 0,
      maximum: 5,
    },
  },
});

// Prompt the model and wait for the json response to come back.
const result = await session.prompt("Summarize this feedback into a rating between 0-5: "+
  "The food was delicious, service was excellent, will recommend.",
  {responseJSONSchema : responseJSONSchemaObj}
);
console.log(result);

The responseJSONSchema option for prompt() and promptStreaming() can also accept a JSON schema directly as a JavaScript object. This is particularly useful for cases where the schema is not reused for other prompts.

While processing the JSON schema, in cases where the user agent detects unsupported schema a "NotSupportedError" DOMException, will be raised with appropriate error message. The result value returned is a string, that can be parsed with JSON.parse(). If the user agent is unable to produce a response that is compliant with the schema, a "SyntaxError" DOMException will be raised.

Configuration of per-session parameters

In addition to the systemPrompt and initialPrompts options shown above, the currently-configurable model parameters are temperature and top-K. The params() API gives the default and maximum values for these parameters.

 const customSession = await ai.languageModel.create({
  temperature: 0.8,
  topK: 10
});

const params = await ai.languageModel.params();
const conditionalSession = await ai.languageModel.create({
  temperature: isCreativeTask ? params.defaultTemperature * 1.1 : params.defaultTemperature * 0.8,
  topK: isGeneratingIdeas ? params.maxTopK : params.defaultTopK
});

https://github.com/webmachinelearning/prompt-api