Skip to content

Commit 7481cdb

Browse files
yanomalysamjulien
authored andcommitted
Palmyra comparison app (#12)
1 parent b12ce0d commit 7481cdb

14 files changed

Lines changed: 191 additions & 3 deletions

financial-tools-chat/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tool.poetry]
2-
name = "fc-demo-app"
2+
name = "writer-framework-default"
33
version = "0.1.0"
44
description = ""
55
authors = ["Your Name <you@example.com>"]

palmyra-comparser/.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
WRITER_API_KEY=your Writer api key
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{"id": "c0f99a9e-5004-4e75-a6c6-36f17490b134", "type": "page", "content": {"cssClasses": "model-response", "pageMode": "compact"}, "handlers": {}, "isCodeManaged": false, "parentId": "root", "position": 0, "visible": {"binding": "", "expression": true, "reversed": false}}
2+
{"id": "bebc5fe9-63a7-46a7-b0fa-62303555cfaf", "type": "header", "content": {"text": "Palmyra Comparison"}, "handlers": {}, "isCodeManaged": false, "parentId": "c0f99a9e-5004-4e75-a6c6-36f17490b134", "position": 0, "visible": {"binding": "", "expression": true, "reversed": false}}
3+
{"id": "mx2ph7hyrz2dmq17", "type": "columns", "content": {}, "handlers": {}, "isCodeManaged": false, "parentId": "c0f99a9e-5004-4e75-a6c6-36f17490b134", "position": 1}
4+
{"id": "3b2e0daziszd6kef", "type": "column", "content": {"title": "", "width": "1"}, "handlers": {}, "isCodeManaged": false, "parentId": "mx2ph7hyrz2dmq17", "position": 0}
5+
{"id": "left-dropdown", "type": "dropdowninput", "binding": {"eventType": "wf-option-change", "stateRef": "palmyra-left-model"}, "content": {"cssClasses": "model-dropdown", "label": "", "options": "@{palmyra-models}"}, "handlers": {"wf-option-change": "handle_dropdown_choice"}, "isCodeManaged": false, "parentId": "3b2e0daziszd6kef", "position": 0}
6+
{"id": "29vpe9owkjzxwiey", "type": "section", "content": {"containerBackgroundColor": "#ffd8cd", "isCollapsible": "yes", "startCollapsed": "yes", "title": "@{palmyra-models[palmyra-left-model]}"}, "handlers": {}, "isCodeManaged": false, "parentId": "3b2e0daziszd6kef", "position": 1}
7+
{"id": "atacwt9o6h0b057s", "type": "text", "content": {"cssClasses": "", "text": "@{palmyra-description-left}", "useMarkdown": "yes"}, "handlers": {}, "isCodeManaged": false, "parentId": "29vpe9owkjzxwiey", "position": 0}
8+
{"id": "ppg3ncuom2jj5rl5", "type": "section", "content": {"title": ""}, "handlers": {}, "isCodeManaged": false, "parentId": "3b2e0daziszd6kef", "position": 2}
9+
{"id": "z42d3lavps0u2bi1", "type": "text", "content": {"alignment": "", "cssClasses": "model-response", "text": "@{palmyra-left-response}", "useMarkdown": "yes"}, "handlers": {}, "isCodeManaged": false, "parentId": "ppg3ncuom2jj5rl5", "position": 0}
10+
{"id": "6y3vow1g76mx42i0", "type": "section", "content": {"isCollapsible": "yes", "startCollapsed": "yes", "title": "Model settings"}, "handlers": {}, "isCodeManaged": false, "parentId": "3b2e0daziszd6kef", "position": 3}
11+
{"id": "mzpsdvwrnqa62g54", "type": "columns", "content": {}, "handlers": {}, "isCodeManaged": false, "parentId": "6y3vow1g76mx42i0", "position": 0}
12+
{"id": "ouiqu3l2sfnc8rlf", "type": "column", "content": {"width": "1"}, "handlers": {}, "isCodeManaged": false, "parentId": "mzpsdvwrnqa62g54", "position": 0}
13+
{"id": "l8t8aubcbn2g3eu4", "type": "sliderinput", "binding": {"eventType": "wf-number-change", "stateRef": "palmyra-left-temperature"}, "content": {"label": "Temperature", "maxValue": "1", "minValue": "0", "stepSize": "0.1"}, "handlers": {}, "isCodeManaged": false, "parentId": "ouiqu3l2sfnc8rlf", "position": 0}
14+
{"id": "x4hchodlv4jkh7ah", "type": "column", "content": {"width": "1"}, "handlers": {}, "isCodeManaged": false, "parentId": "mzpsdvwrnqa62g54", "position": 1}
15+
{"id": "hfq214mbadv4nomz", "type": "sliderinput", "binding": {"eventType": "wf-number-change", "stateRef": "palmyra-left-max-tokens"}, "content": {"label": "Max tokens", "maxValue": "64000", "minValue": "0", "stepSize": "50"}, "handlers": {}, "isCodeManaged": false, "parentId": "x4hchodlv4jkh7ah", "position": 0}
16+
{"id": "b99w95l47qi42mh0", "type": "column", "content": {"width": "1"}, "handlers": {}, "isCodeManaged": false, "parentId": "mx2ph7hyrz2dmq17", "position": 1}
17+
{"id": "right-dropdown", "type": "dropdowninput", "binding": {"eventType": "wf-option-change", "stateRef": "palmyra-right-model"}, "content": {"cssClasses": "model-dropdown", "label": "", "options": "@{palmyra-models}"}, "handlers": {"wf-option-change": "handle_dropdown_choice"}, "isCodeManaged": false, "parentId": "b99w95l47qi42mh0", "position": 0}
18+
{"id": "hycef835us94hrl8", "type": "section", "content": {"containerBackgroundColor": "#d4b2f7", "isCollapsible": "yes", "startCollapsed": "yes", "title": "@{palmyra-models[palmyra-right-model]}"}, "handlers": {}, "isCodeManaged": false, "parentId": "b99w95l47qi42mh0", "position": 1}
19+
{"id": "h023lm7lu92gqit4", "type": "text", "content": {"cssClasses": "", "text": "@{palmyra-description-right}", "useMarkdown": "yes"}, "handlers": {}, "isCodeManaged": false, "parentId": "hycef835us94hrl8", "position": 0}
20+
{"id": "beb792yvj93xyv5b", "type": "section", "content": {"title": ""}, "handlers": {}, "isCodeManaged": false, "parentId": "b99w95l47qi42mh0", "position": 2}
21+
{"id": "oah5u3ea9qr91h67", "type": "text", "content": {"alignment": "", "cssClasses": "model-response", "text": "@{palmyra-right-response}", "useMarkdown": "yes"}, "handlers": {}, "isCodeManaged": false, "parentId": "beb792yvj93xyv5b", "position": 0}
22+
{"id": "e1z9290nj1wq3qx9", "type": "section", "content": {"isCollapsible": "yes", "startCollapsed": "yes", "title": "Model settings"}, "handlers": {}, "isCodeManaged": false, "parentId": "b99w95l47qi42mh0", "position": 3}
23+
{"id": "38hr6sep84veupc8", "type": "columns", "content": {}, "handlers": {}, "isCodeManaged": false, "parentId": "e1z9290nj1wq3qx9", "position": 0}
24+
{"id": "f09myqgjo8cqk1is", "type": "column", "content": {"width": "1"}, "handlers": {}, "isCodeManaged": false, "parentId": "38hr6sep84veupc8", "position": 0}
25+
{"id": "6c9zgcn830jdyrem", "type": "sliderinput", "binding": {"eventType": "wf-number-change", "stateRef": "palmyra-right-temperature"}, "content": {"label": "Temperature", "maxValue": "1", "minValue": "0", "stepSize": "0.1"}, "handlers": {}, "isCodeManaged": false, "parentId": "f09myqgjo8cqk1is", "position": 0}
26+
{"id": "5sg0cjnv6amfz12k", "type": "column", "content": {"width": "1"}, "handlers": {}, "isCodeManaged": false, "parentId": "38hr6sep84veupc8", "position": 1}
27+
{"id": "p8hjof458sgbvbhg", "type": "sliderinput", "binding": {"eventType": "wf-number-change", "stateRef": "palmyra-right-max-tokens"}, "content": {"label": "Max tokens", "maxValue": "64000", "minValue": "0", "stepSize": "50"}, "handlers": {}, "isCodeManaged": false, "parentId": "5sg0cjnv6amfz12k", "position": 0}
28+
{"id": "dnf3qmf96ttjz7ln", "type": "textinput", "binding": {"eventType": "wf-change", "stateRef": "user-prompt"}, "content": {"cssClasses": "prompt-input", "label": "", "placeholder": "Ask Palmyras something"}, "handlers": {"wf-change-finish": "handle_user_input"}, "isCodeManaged": false, "parentId": "c0f99a9e-5004-4e75-a6c6-36f17490b134", "position": 2}
29+
{"id": "mse4hifzxkrxu65f", "type": "columns", "content": {}, "handlers": {}, "isCodeManaged": false, "parentId": "c0f99a9e-5004-4e75-a6c6-36f17490b134", "position": 3}
30+
{"id": "r9rvh3iyjwas0467", "type": "column", "content": {"width": "1"}, "handlers": {}, "isCodeManaged": false, "parentId": "mse4hifzxkrxu65f", "position": 0}
31+
{"id": "prompt-left-button", "type": "button", "content": {"buttonColor": "#ff7cea", "cssClasses": "prompt-button", "text": "@{prompt-left-button}"}, "handlers": {"wf-click": "handle_prompt_button"}, "isCodeManaged": false, "parentId": "r9rvh3iyjwas0467", "position": 0}
32+
{"id": "w2t4ga6ax52pfvia", "type": "column", "content": {"width": "1"}, "handlers": {}, "isCodeManaged": false, "parentId": "mse4hifzxkrxu65f", "position": 1}
33+
{"id": "prompt-center-button", "type": "button", "content": {"buttonColor": "#241f31", "cssClasses": "prompt-button", "text": "@{prompt-center-button}"}, "handlers": {"wf-click": "handle_prompt_button"}, "isCodeManaged": false, "parentId": "w2t4ga6ax52pfvia", "position": 0}
34+
{"id": "5x7gojqt67e68boz", "type": "column", "content": {"width": "1"}, "handlers": {}, "isCodeManaged": false, "parentId": "mse4hifzxkrxu65f", "position": 2}
35+
{"id": "prompt-right-button", "type": "button", "content": {"buttonColor": "#5551ff", "cssClasses": "prompt-button", "text": "@{prompt-right-button}"}, "handlers": {"wf-click": "handle_prompt_button"}, "isCodeManaged": false, "parentId": "5x7gojqt67e68boz", "position": 0}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"id": "root", "type": "root", "content": {"appName": "My App"}, "handlers": {}, "isCodeManaged": false, "position": 0, "visible": {"binding": "", "expression": true, "reversed": false}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"id": "workflows_root", "type": "workflows_root", "content": {}, "handlers": {}, "isCodeManaged": false, "position": 0, "visible": {"binding": "", "expression": true, "reversed": false}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"id": "lfltcky7l1fsm6j2", "type": "workflows_workflow", "content": {}, "handlers": {}, "isCodeManaged": false, "parentId": "workflows_root", "position": 0}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"writer_version": "0.8.2"
3+
}

palmyra-comparser/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
This app was created using Writer Framework.
2+
3+
To learn more about it, visit https://dev.writer.com/framework

palmyra-comparser/main.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import asyncio
2+
3+
import writer as wf
4+
from dotenv import load_dotenv
5+
from writer import WriterState
6+
from writerai import AsyncWriter
7+
from writerai.types.chat_chat_params import Message
8+
9+
load_dotenv()
10+
11+
def handle_user_input(payload: str, state: WriterState) -> None:
12+
asyncio.run(_ask_models(payload, state))
13+
14+
15+
def handle_prompt_button(context: dict, state: WriterState) -> None:
16+
state["user-prompt"] = state[context["target"]+'-full']
17+
asyncio.run(_ask_models(state[context["target"]+'-full'], state))
18+
19+
20+
def handle_dropdown_choice(context: dict, payload: str, state: WriterState) -> None:
21+
if "right" in context["target"]:
22+
state["palmyra-description-right"] = state["palmyra-models-description"][payload]
23+
else:
24+
state["palmyra-description-left"] = state["palmyra-models-description"][payload]
25+
26+
27+
async def _ask_models(prompt: str, state: WriterState) -> None:
28+
state["palmyra-left-conversation"].append(Message(role="user", content=prompt))
29+
state["palmyra-right-conversation"].append(Message(role="user", content=prompt))
30+
31+
async_writer_client = AsyncWriter()
32+
33+
await asyncio.gather(
34+
_perform_async_streaming(async_writer_client, state["palmyra-left-model"], "left", state),
35+
_perform_async_streaming(async_writer_client, state["palmyra-right-model"], "right", state),
36+
)
37+
38+
39+
async def _perform_async_streaming(client: AsyncWriter, model: str, side: str, state: WriterState) -> None:
40+
try:
41+
response = await client.chat.chat(
42+
model=model,
43+
messages=state[f"palmyra-{side}-conversation"],
44+
stream=True,
45+
max_tokens=state[f"palmyra-{side}-max-tokens"],
46+
temperature=state[f"palmyra-{side}-temperature"],
47+
)
48+
49+
response_message = ""
50+
state[f"palmyra-{side}-response"] = ""
51+
52+
async for message in response:
53+
content = message.choices[0].delta.content
54+
content = content if content is not None else ""
55+
response_message += content
56+
state[f"palmyra-{side}-response"] += content
57+
58+
state[f"palmyra-{side}-conversation"].append(Message(role="assistant", content=response_message))
59+
60+
except Exception as e:
61+
response_message = "Something went wrong. Please, try again."
62+
state[f"palmyra-{side}-conversation"].append(Message(role="assistant", content=response_message))
63+
raise e
64+
65+
palmyra_models_description = {
66+
"palmyra-x-004": "**Palmyra X 004** is our newest and most advanced language model with a large context window of up to 128,000 tokens. This model excels in processing and understanding complex tasks, making it ideal for workflow automation, coding tasks, and data analysis.",
67+
"palmyra-med": "**Palmyra Medical** is the latest version of our healthcare model and the most accurate in the market. The Writer full-stack generative AI platform is used by the world’s leading Fortune 50 healthcare companies to help improve patient outcomes with powerful AI that are infused with deep medical knowledge.",
68+
"palmyra-fin-32k": "**Palmyra Financial** is Writer’s specialized language model for the finance industry, designed to support critical financial workflows with precision in terminology and document analysis. Palmyra Fin empowers financial organizations to streamline processes and make data-driven decisions confidently.",
69+
"palmyra-creative": "**Palmyra Creative** is Writer's purpose-built language model, engineered to elevate creative thinking and writing across diverse professional contexts. With capabilities that amplify originality and adaptability, it caters to industries and teams where innovation drives success. ",
70+
}
71+
72+
initial_state = wf.init_state(
73+
{
74+
"palmyra-models": {
75+
"palmyra-x-004": "Palmyra X 004",
76+
"palmyra-med": "Palmyra Medical",
77+
"palmyra-fin-32k": "Palmyra Financial",
78+
"palmyra-creative": "Palmyra Creative",
79+
},
80+
"palmyra-models-description": palmyra_models_description,
81+
"palmyra-left-conversation": [],
82+
"palmyra-left-response": "Model response will appear here...",
83+
"palmyra-left-model": "palmyra-x-004",
84+
"palmyra-left-temperature": 0.7,
85+
"palmyra-left-max-tokens": 16384,
86+
"palmyra-description-left": palmyra_models_description["palmyra-x-004"],
87+
"palmyra-right-conversation": [],
88+
"palmyra-right-response": "Model response will appear here...",
89+
"palmyra-right-model": "palmyra-creative",
90+
"palmyra-right-temperature": 0.7,
91+
"palmyra-right-max-tokens": 16384,
92+
"palmyra-description-right": palmyra_models_description["palmyra-creative"],
93+
"user-prompt": "",
94+
"prompt-left-button": "Brainstorm bakery strategies",
95+
"prompt-left-button-full": "Imagine you're a struggling small-town bakery competing with a chain that opened across the street. Brainstorm unconventional strategies to win over customers without lowering prices.",
96+
"prompt-center-button": "Explain AI to a high schooler",
97+
"prompt-center-button-full": "Write a guide for a programmer who wants to explain their AI side project to a high schooler. The explanation must be engaging, simple, and use humorous analogies, while avoiding technical jargon.",
98+
"prompt-right-button": "Zero gravity game",
99+
"prompt-right-button-full": "Design a game that could only exist in zero gravity.",
100+
}
101+
)
102+
103+
initial_state.import_stylesheet("style", "/static/custom.css")

palmyra-comparser/pyproject.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[tool.poetry]
2+
name = "writer-framework-default"
3+
version = "0.1.0"
4+
description = ""
5+
authors = ["Your Name <you@example.com>"]
6+
readme = "README.md"
7+
8+
[tool.poetry.dependencies]
9+
python = "^3.11"
10+
writer = "0.8.2"
11+
python-dotenv = "^1.0.1"
12+
13+
14+
[build-system]
15+
requires = ["poetry-core"]
16+
build-backend = "poetry.core.masonry.api"

0 commit comments

Comments
 (0)