Skip to content

Commit

Permalink
+++
Browse files Browse the repository at this point in the history
  • Loading branch information
Offirmo committed Sep 4, 2024
1 parent ee087eb commit b3b6448
Show file tree
Hide file tree
Showing 25 changed files with 519 additions and 155 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

/////////////////////////////////////////////////

// https://gemini.google.com/share/a4665036f4b9
type LLMTemperature = number
type LLMTopK = number
type LLMTokenCount = number
Expand Down
2 changes: 1 addition & 1 deletion stack--current/3-advanced--browser/wc--social/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ A social media icons web component.

## Usage

WARNING example does not work on Safari! TODO fix
WARNING example does not work on Safari! TODO fix https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/is

https://codepen.io/Offirmo/pen/vYeobzP

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ inheritance -- diamond
inheritance -- prototypal
inheritance -- substitutability = an object (such as a class) may be replaced by a sub-object (such as a class that extends the first class) without breaking the program
inner-platform effect https://en.wikipedia.org/wiki/Inner-platform_effect
interface
interface -- abstract = no implementation, only to be extended (OOP)
Interface segregation principle = instead of a class interface with all possible methods clients might need, there should be separate interfaces catering to the specific needs of each type of client https://en.wikipedia.org/wiki/Interface_segregation_principle
Joel test
JS equality
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ User Agent Interface (UA) https://www.bram.us/2021/07/08/the-large-small-and-dyn
UX -- Above the fold = is the area of a webpage that fits in a browser window without a user having to scroll down. This is the content that is first seen by the user and often dictates whether they’ll continue reading the webpage.
UX -- honeycomb = useful + usable + findable + desirable + accessible + credible = valuable https://en.wikipedia.org/wiki/User_interface#A_model_of_design_criteria:_User_Experience_Honeycomb
viewport
temporal dead zone (TDZ) https://devdocs.io/javascript/statements/let#temporal_dead_zone_tdz
viewport -- small <= dynamic <= large
viewport -- visual
viewport -- Visual Viewport API = Window.visualViewport https://developer.mozilla.org/en-US/docs/Web/API/VisualViewport
Expand All @@ -183,6 +184,7 @@ web components -- custom elements
web components -- is
web components -- shadow DOM
web components -- templates
web components -- "autonomous" = no extends, no "is", must inherit from HTMLElement
web components -- templates -- slots https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/slot
web components https://developer.mozilla.org/en-US/docs/Web/API/Web_components
web workers -- dedicated = utilized by a single script https://devdocs.io/dom/worker
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# https://securitytxt.org/

Please report any security issue or danger to the community to:
- https://github.com/Yvem/applied-ai--8ball/issues
- https://github.com/Yvem/applied-ai--2024/issues

Thanks for your contribution!
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<!doctype html>
<html lang="en" xml:lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="content-language" content="en" />
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<link
rel="icon"
href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>✨</text></svg>"
/>

<title>Free LLM AAI ✨</title>

<style>
@layer offirmo--reset, offirmo--foundation, offirmo--framework;
@import "offirmo-framework.css";
@import "index.css";

body {
--o⋄content-recommended-width: 120ch;
}
</style>

<script src="./js/common/wc--ensure-ai-enabled/index.js"></script>
</head>

<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

<main>
<h1>✨ Free & Unfettered LLM AI ✨</h1>
<ensure-ai-enabled>
<section>
<form class="o⋄flex--directionꘌcolumn">
<strong>(optional) System prompt:</strong>
<textarea rows="3" id="input--system-prompt">You're a helpful assistant.</textarea>
<small>tokens: TODO</small>
<strong>(optional) Please type your question:</strong>
<textarea rows="3" id="input--prompt">How are you today?</textarea>
<small>tokens: TODO</small>
<button type="button" id="button--prompt">Prompt</button>
</form>
</section>

<section style="
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1em;
">

<ai-prompt-result temperature="0.2" topK="default"></ai-prompt-result>
<ai-prompt-result temperature="0.2" topK="50"></ai-prompt-result>
<ai-prompt-result temperature="0.2" topK="128"></ai-prompt-result>
<ai-prompt-result temperature="0.5" topK="default"></ai-prompt-result>
<ai-prompt-result temperature="0.5" topK="50"></ai-prompt-result>
<ai-prompt-result temperature="0.5" topK="128"></ai-prompt-result>
<ai-prompt-result temperature="0.9" topK="default"></ai-prompt-result>
<ai-prompt-result temperature="0.9" topK="50"></ai-prompt-result>
<ai-prompt-result temperature="0.9" topK="128"></ai-prompt-result>
</section>
</ensure-ai-enabled>
</main>
<script type="module">
import main from './js/fuai/index.js'
console.log('Hi from html')
main()
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@

async function ೱisꓽai_webapi_available(progressCallback = () => {}) {
const err = new Error(`AI WebAPI not available!`)
err.url = 'https://docs.google.com/document/d/1VG8HIyz361zGduWgNG7R_R8Xkv0OOJ8b5C9QKeCjU0c/edit#heading=h.witohboigk0o'
progressCallback(0)

return new Promise((resolve, reject) => {
if (!globalThis.ai) {
reject(err)
return
}
progressCallback(0.1)

if (!'assistant' in ai) {
reject(err)
return
}

let ೱsession = ai.assistant.create({
monitor(m) {
m.addEventListener("downloadprogress", e => {
console.log(`ai.assistant: Downloaded ${e.loaded} of ${e.total} bytes.`);
progressCallback(Math.max(0.1, e.loaded / e.total))
});
}
}
)

return ೱsession.then((session) => {
progressCallback(1)
session.destroy()
})
})
}

customElements.define('ensure-ai-enabled', class Component extends HTMLElement {
static _DEBUG = true
_DEBUG = Component._DEBUG

static _id_generator = 0
_id = Component._id_generator++

loaded = 0.05
err = null

static get observedAttributes() { return [ 'apis' ] }

get_debug_id() {
const segments = [
`⟨${this.localName}${this.getAttribute('is') ? `--${this.getAttribute('is')}` : ''}⟩`,
`#${this._id}`,
]
return segments.join('')
}

constructor() {
super()
if (this._DEBUG) console.log(`[${this.get_debug_id()}].constructor()]:`, { _this: this })
// The constructor for a custom element is not supposed to read or write its DOM
// also NOT supposed to read attributes, since createElement(...) may be in progress
// In general, work should be deferred to connectedCallback as much as possible
// https://stackoverflow.com/a/43837330

ೱisꓽai_webapi_available((completion_rate) => {
this.loaded = completion_rate
this._render()
})
.then(() => {
this.loaded = 1
})
.catch((err) => {
this.err = err
})
.finally(() => {
this._render()
})
}

_pendingRender = false
_render() {
if (this._pendingRender) return

if (this._DEBUG) console.log(`[${this.get_debug_id()}]._render()]:`, {
progress: this.loaded,
err: this.err,
})

this.progress‿elt ??= document.createElement('progress')

setTimeout(() => {
this._pendingRender = false

if (this.err) {
this.replaceChildren(
new Text(`[ERROR] ${this.err.message}`),
new Text(`(TODO instructions)`),
)
return
}

// can only test here!!!
if (!this._original_children) {
if (this.children.length === 0) {
// DOM not loaded yet, need to wait!
return
}
this._original_children = Array.from(this.children)
}

if (this.loaded >= 1) {
this.replaceChildren(...this._original_children)
return
}

this.progress‿elt.value = this.loaded
this.replaceChildren(
new Text( `Loading AI-enhanced experience: `),
this.progress‿elt
)
})
this._pendingRender = true
}

// called each time the element is added to the document. The specification recommends that, as far as possible, developers should implement custom element setup in this callback rather than the constructor.
// WARNING https://dev.to/dannyengelman/web-component-developers-do-not-connect-with-the-connectedcallback-yet-4jo7
connectedCallback() {
if (this._DEBUG) console.log(`[${this.get_debug_id()}].connectedCallback()]:`, { _this: this })

this._render()
}
// called each time the element is removed from the document.
disconnectedCallback() {
if (this._DEBUG) console.log(`[${this.get_debug_id()}].disconnectedCallback()]:`, { _this: this })
}
// called each time the element is moved to a new document.
adoptedCallback() {
if (this._DEBUG) console.log(`[${this.get_debug_id()}].adoptedCallback()]:`, { _this: this })
}
attributeChangedCallback(name, old_value, new_value) {
if (this._DEBUG) console.log(`[${this.get_debug_id()}].attributeChangedCallback():`, { name, old_value, new_value, _this: this })
this._render()
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

customElements.define('no-ai', class Component extends HTMLElement {
static _DEBUG = true
_DEBUG = Component._DEBUG

static _id_generator = 0
_id = Component._id_generator++

static get observedAttributes() { return [ 'apis' ] }

get_debug_id() {
const segments = [
`⟨${this.localName}${this.getAttribute('is') ? `--${this.getAttribute('is')}` : ''}⟩`,
`#${this._id}`,
]
return segments.join('')
}

constructor() {
super()
if (this._DEBUG) console.log(`[${this.get_debug_id()}].constructor()]:`, {
'this': this
})
// The constructor for a custom element is not supposed to read or write its DOM
// also NOT supposed to read attributes, since createElement(...) may be in progress
// In general, work should be deferred to connectedCallback as much as possible
// https://stackoverflow.com/a/43837330
}

// called each time the element is added to the document. The specification recommends that, as far as possible, developers should implement custom element setup in this callback rather than the constructor.
// WARNING https://dev.to/dannyengelman/web-component-developers-do-not-connect-with-the-connectedcallback-yet-4jo7
connectedCallback() {
if (this._DEBUG) console.log(`[${this.get_debug_id()}].connectedCallback()]:`, {
'this': this
})
setTimeout(() => {
this.innerHTML = `[${this.get_debug_id()}: Not Implemented ]`
})
}
// called each time the element is removed from the document.
disconnectedCallback() {
if (this._DEBUG) console.log(`[${this.get_debug_id()}].disconnectedCallback()]:`, {
'this': this
})
}
// called each time the element is moved to a new document.
adoptedCallback() {
if (this._DEBUG) console.log(`[${this.get_debug_id()}].adoptedCallback()]:`, {
'this': this
})
}
attributeChangedCallback(name, old_value, new_value) {
if (this._DEBUG) console.log(`[${this.get_debug_id()}].attributeChangedCallback():`, {
'this': this,
name, old_value, new_value,
})
}

});
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@

import { registry } from './wc--result/index.js'


// How many r are there in "strawberry"?

// TODO https://devdocs.io/dom/device_memory_api

export default async function main() {
const elt_button_prompt = document.getElementById('button--prompt')

function on_click_ask() {
const systemPrompt = (document.getElementById('input--system-prompt').value).normalize('NFC').trim()
const prompt = (document.getElementById('input--prompt').value).normalize('NFC').trim()

for (let key in registry) {
registry[key].prompt({
systemPrompt,
prompt,
})
}
}

elt_button_prompt.onclick = on_click_ask
//setTimeout(on_click_ask, 500) // for tests, TODO remove

// https://gemini.google.com/share/a4665036f4b9
// temperature = 0...1
// low = 0.2
// high = 0.8
// Top-k = 1...100
// small = 5
// large = 40
}

function get_random_standard_8ball_answer() {
const d20 = getRandomIntInRange(1, 20)
const sentence = STANDARD_RESPONSES[d20 - 1]

return { d20, sentence }
}

async function get_response__ai(question, d20) {
console.log({ question, d20 })

const session = await ai.assistant.create({
// TODO on day monitor
})

const result_raw = await(async () => {
if (d20 <= 10) {
// affirmative
return session.prompt("Generate an affirmative, reassuring prompt to proceed.");
}
else if (d20 <= 15) {
// non-committal
return session.prompt("Generate an excuse saying you'll answer this question later.");
}
else {
// negative
return session.prompt("Generate a gentle but firm prompt to NOT proceed. Make excuses or invoke sources.");
}
})()

return filter_in_last_quoted_sentence_if_any(result_raw)
}
Loading

0 comments on commit b3b6448

Please sign in to comment.