Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,183 +1,41 @@
|
|
| 1 |
-
|
| 2 |
-
import streamlit as st
|
| 3 |
-
import promptlayer
|
| 4 |
-
from anthropic import Anthropic, HUMAN_PROMPT, AI_PROMPT
|
| 5 |
-
import uuid
|
| 6 |
-
import math
|
| 7 |
-
|
| 8 |
-
INIT_PROMPT = """
|
| 9 |
-
\n\nHuman: You are MapMentor a trainer in Wardley Mapping. You will help the users learn about Wardley Mapping
|
| 10 |
-
Here are some important rules for the interaction:
|
| 11 |
-
- Always stay in character, as MapMentor a Wardley Mapping trainer.
|
| 12 |
-
- If you are unsure how to respond, respond with another question.
|
| 13 |
-
- Always use a liberationism pedagogy training approach.
|
| 14 |
-
- Remember to state which module of the course we are currently learning.
|
| 15 |
-
"""
|
| 16 |
-
|
| 17 |
-
TRAINING_PROMPT = """
|
| 18 |
-
Here is an outline for a training course that you will give to the user. It covers the key principles of Wardley Mapping:
|
| 19 |
-
|
| 20 |
-
Module 1 - Introduction to Wardley Mapping
|
| 21 |
-
Purpose and benefits of mapping
|
| 22 |
-
Understanding value chains and situational awareness
|
| 23 |
-
Overview of doctrine and foundational concepts
|
| 24 |
-
|
| 25 |
-
Module 2 - Structure of Wardley Maps
|
| 26 |
-
Components, activities, and the value chain
|
| 27 |
-
Evolution axis and commodity forms
|
| 28 |
-
Anchors, chains, and dependencies
|
| 29 |
-
|
| 30 |
-
Module 3 - Developing Wardley Maps
|
| 31 |
-
Gathering insight on activities, capabilities, and needs
|
| 32 |
-
Positioning and classifying map elements
|
| 33 |
-
Adding annotations and context
|
| 34 |
-
|
| 35 |
-
Module 4 - Using Maps for Decision Making
|
| 36 |
-
Identifying structural vs situational change
|
| 37 |
-
Applying doctrine to strategic planning
|
| 38 |
-
Mapping out competing value chains
|
| 39 |
-
Developing actionable insights from maps
|
| 40 |
-
|
| 41 |
-
Module 5 - Advanced Concepts
|
| 42 |
-
Ecosystem models and community maps
|
| 43 |
-
Climate patterns and their impact
|
| 44 |
-
Mapping organizational culture
|
| 45 |
-
Handling uncertainty and unknowns
|
| 46 |
-
|
| 47 |
-
Module 6 - Facilitating Wardley Mapping
|
| 48 |
-
Workshops for collaborative mapping
|
| 49 |
-
Engaging leadership and stakeholders
|
| 50 |
-
Promoting adoption and managing skeptics
|
| 51 |
-
|
| 52 |
-
For each module, we would provide concepts, examples, hands-on exercises, and practice activities to build skills.
|
| 53 |
-
Please let me know if you would like me to expand on any part of this high-level curriculum outline for a Wardley Mapping training course.
|
| 54 |
-
I'm happy to provide more details on how to effectively teach this methodology.
|
| 55 |
-
"""
|
| 56 |
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
This course is designed as an interactive learning experience to build your skills in Wardley Mapping from the ground up. We will cover the key principles, components, and steps for creating powerful maps. \n
|
| 60 |
-
|
| 61 |
-
The course is organized into 6 modules: \n
|
| 62 |
-
Module 1 provides an introduction to the purpose, benefits, and foundational concepts of mapping. We discuss how it helps with situational awareness and strategic planning. \n
|
| 63 |
-
Module 2 focuses on the structure of Wardley Maps - the components like activities, evolution axis, dependencies. You'll learn how to visualize your value chain. \n
|
| 64 |
-
Module 3 is all about developing maps hands-on. We'll practice gathering insights, positioning elements, adding annotations to create meaningful maps. \n
|
| 65 |
-
Module 4 shifts to using completed maps for strategic analysis and decision making. You'll apply doctrine to interpret maps and generate insights. \n
|
| 66 |
-
Module 5 covers more advanced concepts like mapping ecosystems, organizational culture, and handling uncertainty. \n
|
| 67 |
-
Finally Module 6 is on facilitating mapping workshops and driving adoption. \n
|
| 68 |
-
Each module includes concepts, examples, exercises, and practice activities to build your skills. You'll have opportunities to create maps, iterate on them, and apply them to scenario-based challenges. \n
|
| 69 |
-
I'm looking forward to exploring all aspects of Wardley Mapping with you in this course! Please let me know if you would like me to elaborate on any part of the curriculum.
|
| 70 |
-
"""
|
| 71 |
-
|
| 72 |
-
REG_PROMPT = """
|
| 73 |
-
\n\nHuman: Here is the user's question about Wardley Mapping:
|
| 74 |
-
<question>
|
| 75 |
-
{QUESTION}
|
| 76 |
-
</question>
|
| 77 |
-
\n\nAssistant: [MapMentor] <response>
|
| 78 |
-
"""
|
| 79 |
-
|
| 80 |
-
# Anthropic Claude pricing: https://cdn2.assets-servd.host/anthropic-website/production/images/model_pricing_may2023.pdf
|
| 81 |
-
PRICE_PROMPT = 1.102E-5
|
| 82 |
-
PRICE_COMPLETION = 3.268E-5
|
| 83 |
-
|
| 84 |
-
#MODEL = "claude-1"
|
| 85 |
-
#MODEL = "claude-2.1"
|
| 86 |
-
MODEL = "claude-3-opus-20240229"
|
| 87 |
-
#MODEL = "claude-v1-100k"
|
| 88 |
-
|
| 89 |
-
new_prompt = []
|
| 90 |
-
|
| 91 |
-
if "session_id" not in st.session_state:
|
| 92 |
-
st.session_state.session_id = str(uuid.uuid4())
|
| 93 |
-
|
| 94 |
-
st.set_page_config(page_title="Anthropic - ChatBot")
|
| 95 |
-
st.sidebar.title("Anthropic - ChatBot")
|
| 96 |
-
st.sidebar.title("Wardley Mapping Mentor")
|
| 97 |
-
st.sidebar.divider()
|
| 98 |
-
st.sidebar.markdown("Developed by Mark Craddock](https://twitter.com/mcraddock)", unsafe_allow_html=True)
|
| 99 |
-
st.sidebar.markdown("Current Version: 0.0.2")
|
| 100 |
-
st.sidebar.markdown("Using claude-2 API")
|
| 101 |
-
st.sidebar.markdown(st.session_state.session_id)
|
| 102 |
-
st.sidebar.divider()
|
| 103 |
|
| 104 |
-
|
| 105 |
-
user_claude_api_key = st.sidebar.text_input("Enter your Anthropic API Key:", placeholder="sk-...", type="password")
|
| 106 |
|
| 107 |
-
|
| 108 |
-
|
| 109 |
|
| 110 |
-
|
| 111 |
-
|
|
|
|
|
|
|
|
|
|
| 112 |
|
| 113 |
if "messages" not in st.session_state:
|
| 114 |
-
st.session_state
|
| 115 |
-
st.session_state.messages.append({"role": "assistant", "content": INTRO_PROMPT})
|
| 116 |
-
|
| 117 |
-
if "all_prompts" not in st.session_state:
|
| 118 |
-
st.session_state["all_prompts"] = INIT_PROMPT + TRAINING_PROMPT
|
| 119 |
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
prompt_cost = prompt_token_count * PRICE_PROMPT
|
| 124 |
-
completion_cost = completion_token_count * PRICE_COMPLETION
|
| 125 |
-
total_cost = prompt_cost + completion_cost
|
| 126 |
-
total_cost = math.ceil(total_cost * 100) / 100
|
| 127 |
-
return (
|
| 128 |
-
prompt_token_count,
|
| 129 |
-
completion_token_count,
|
| 130 |
-
total_cost
|
| 131 |
-
)
|
| 132 |
-
|
| 133 |
-
if user_claude_api_key:
|
| 134 |
-
# If the user has provided an API key, use it
|
| 135 |
-
# Swap out Anthropic for promptlayer
|
| 136 |
-
promptlayer.api_key = st.secrets["PROMPTLAYER"]
|
| 137 |
-
anthropic = promptlayer.anthropic
|
| 138 |
-
client=anthropic.Anthropic(
|
| 139 |
-
os.environ.get("ANTHROPIC_API_KEY")
|
| 140 |
-
)
|
| 141 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 142 |
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
with st.chat_message(message["role"]):
|
| 146 |
-
new_prompt.append(message["content"])
|
| 147 |
-
st.markdown(message["content"])
|
| 148 |
-
|
| 149 |
-
if user_claude_api_key:
|
| 150 |
-
if user_input := st.chat_input("How can I help with Wardley Mapping?"):
|
| 151 |
-
prompt = REG_PROMPT.format(QUESTION = user_input)
|
| 152 |
-
st.session_state.all_prompts += prompt
|
| 153 |
-
st.session_state.messages.append({"role": "user", "content": user_input})
|
| 154 |
-
with st.chat_message("user"):
|
| 155 |
-
st.markdown(user_input)
|
| 156 |
-
with st.chat_message("assistant"):
|
| 157 |
-
message_placeholder = st.empty()
|
| 158 |
full_response = ""
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
pl_tags=["anthropic-chatbot", st.session_state.session_id]
|
| 167 |
-
):
|
| 168 |
-
full_response += response.completion
|
| 169 |
message_placeholder.markdown(full_response + "▌")
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
st.error("The server could not be reached")
|
| 173 |
-
print(e.__cause__) # an underlying Exception, likely raised within httpx.
|
| 174 |
-
except anthropic.RateLimitError as e:
|
| 175 |
-
st.error("A 429 status code was received; we should back off a bit.")
|
| 176 |
-
except anthropic.APIStatusError as e:
|
| 177 |
-
st.error("Another non-200-range status code was received")
|
| 178 |
-
st.error(e.status_code)
|
| 179 |
-
st.error(e.response)
|
| 180 |
-
st.session_state.messages.append({"role": "assistant", "content": full_response})
|
| 181 |
-
st.session_state.all_prompts += full_response
|
| 182 |
-
prompt_token_count, completion_token_count, total_cost = count_used_tokens(prompt, full_response)
|
| 183 |
-
total_tokens.markdown("Prompt: " + str(prompt_token_count) + " \nCompletion: " + str(completion_token_count) + " \nTotal Cost: $" + str(total_cost))
|
|
|
|
| 1 |
+
import os
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
|
| 3 |
+
import anthropic
|
| 4 |
+
import streamlit as st
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
|
| 6 |
+
st.title("Claude 3 by Streamlit")
|
|
|
|
| 7 |
|
| 8 |
+
ai_model = os.environ.get("AI_MODEL")
|
| 9 |
+
api_key = os.environ.get("ANTHROPIC_API_KEY")
|
| 10 |
|
| 11 |
+
client = anthropic.Anthropic(
|
| 12 |
+
api_key=api_key,
|
| 13 |
+
)
|
| 14 |
+
if "ai_model" not in st.session_state:
|
| 15 |
+
st.session_state["ai_model"] = ai_model
|
| 16 |
|
| 17 |
if "messages" not in st.session_state:
|
| 18 |
+
st.session_state.messages = []
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
|
| 20 |
+
for message in st.session_state.messages:
|
| 21 |
+
with st.chat_message(message["role"]):
|
| 22 |
+
st.markdown(message["content"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
|
| 24 |
+
if prompt := st.chat_input("What is up?"):
|
| 25 |
+
st.session_state.messages.append({"role": "user", "content": prompt})
|
| 26 |
+
with st.chat_message("user"):
|
| 27 |
+
st.markdown(prompt)
|
| 28 |
|
| 29 |
+
with st.chat_message("assistant"):
|
| 30 |
+
message_placeholder = st.empty()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
full_response = ""
|
| 32 |
+
with client.messages.stream(
|
| 33 |
+
max_tokens=1024,
|
| 34 |
+
messages=[{"role": m["role"], "content": m["content"]} for m in st.session_state.messages],
|
| 35 |
+
model=st.session_state["ai_model"],
|
| 36 |
+
) as stream:
|
| 37 |
+
for text in stream.text_stream:
|
| 38 |
+
full_response += str(text) if text is not None else ""
|
|
|
|
|
|
|
|
|
|
| 39 |
message_placeholder.markdown(full_response + "▌")
|
| 40 |
+
message_placeholder.markdown(full_response)
|
| 41 |
+
st.session_state.messages.append({"role": "assistant", "content": full_response})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|