black and also set_language isn't "correct" anymore.
so it doesn't move the student on. modified: app.py modified: migrations/env.py modified: migrations/versions/190d5ef26e20_add_token_count_to_message.py modified: migrations/versions/a9e886c56482_create_room_table.py modified: migrations/versions/d737de68d6fa_add_metadata_field_to_activitystate.py modified: research/activity21.yaml modified: research/guarded_ai.py
This commit is contained in:
parent
5f4cf76372
commit
f5df195e9b
7 changed files with 187 additions and 117 deletions
28
app.py
28
app.py
|
|
@ -2164,13 +2164,22 @@ def handle_activity_response(room_name, user_response, username):
|
|||
for key, value in transition["metadata_add"].items():
|
||||
if value == "the-users-response":
|
||||
value = user_response
|
||||
elif isinstance(value, str) and (value.startswith("n+") or value.startswith("n-")):
|
||||
# Extract the numeric part c and apply the operation +/-
|
||||
c = int(value[1:])
|
||||
if value.startswith("n+"):
|
||||
value = activity_state.dict_metadata.get(key, 0) + c
|
||||
elif value.startswith("n-"):
|
||||
value = activity_state.dict_metadata.get(key, 0) - c
|
||||
elif isinstance(value, str):
|
||||
if value.startswith("n+random(") and value.endswith(")"):
|
||||
# Extract the range and apply the random increment
|
||||
range_values = value[9:-1].split(",")
|
||||
if len(range_values) == 2:
|
||||
x, y = map(int, range_values)
|
||||
value = activity_state.dict_metadata.get(
|
||||
key, 0
|
||||
) + random.randint(x, y)
|
||||
elif value.startswith("n+") or value.startswith("n-"):
|
||||
# Extract the numeric part c and apply the operation +/-
|
||||
c = int(value[1:])
|
||||
if value.startswith("n+"):
|
||||
value = activity_state.dict_metadata.get(key, 0) + c
|
||||
elif value.startswith("n-"):
|
||||
value = activity_state.dict_metadata.get(key, 0) - c
|
||||
new_metadata[key] = value
|
||||
activity_state.add_metadata(key, value)
|
||||
|
||||
|
|
@ -2271,9 +2280,10 @@ def handle_activity_response(room_name, user_response, username):
|
|||
if (
|
||||
category
|
||||
not in [
|
||||
"off_topic",
|
||||
"asking_clarifying_questions",
|
||||
"partial_understanding",
|
||||
"asking_clarifying_questions",
|
||||
"set_language",
|
||||
"off_topic",
|
||||
]
|
||||
or activity_state.attempts >= activity_state.max_attempts
|
||||
):
|
||||
|
|
|
|||
|
|
@ -12,32 +12,31 @@ config = context.config
|
|||
# Interpret the config file for Python logging.
|
||||
# This line sets up loggers basically.
|
||||
fileConfig(config.config_file_name)
|
||||
logger = logging.getLogger('alembic.env')
|
||||
logger = logging.getLogger("alembic.env")
|
||||
|
||||
|
||||
def get_engine():
|
||||
try:
|
||||
# this works with Flask-SQLAlchemy<3 and Alchemical
|
||||
return current_app.extensions['migrate'].db.get_engine()
|
||||
return current_app.extensions["migrate"].db.get_engine()
|
||||
except (TypeError, AttributeError):
|
||||
# this works with Flask-SQLAlchemy>=3
|
||||
return current_app.extensions['migrate'].db.engine
|
||||
return current_app.extensions["migrate"].db.engine
|
||||
|
||||
|
||||
def get_engine_url():
|
||||
try:
|
||||
return get_engine().url.render_as_string(hide_password=False).replace(
|
||||
'%', '%%')
|
||||
return get_engine().url.render_as_string(hide_password=False).replace("%", "%%")
|
||||
except AttributeError:
|
||||
return str(get_engine().url).replace('%', '%%')
|
||||
return str(get_engine().url).replace("%", "%%")
|
||||
|
||||
|
||||
# add your model's MetaData object here
|
||||
# for 'autogenerate' support
|
||||
# from myapp import mymodel
|
||||
# target_metadata = mymodel.Base.metadata
|
||||
config.set_main_option('sqlalchemy.url', get_engine_url())
|
||||
target_db = current_app.extensions['migrate'].db
|
||||
config.set_main_option("sqlalchemy.url", get_engine_url())
|
||||
target_db = current_app.extensions["migrate"].db
|
||||
|
||||
# other values from the config, defined by the needs of env.py,
|
||||
# can be acquired:
|
||||
|
|
@ -46,7 +45,7 @@ target_db = current_app.extensions['migrate'].db
|
|||
|
||||
|
||||
def get_metadata():
|
||||
if hasattr(target_db, 'metadatas'):
|
||||
if hasattr(target_db, "metadatas"):
|
||||
return target_db.metadatas[None]
|
||||
return target_db.metadata
|
||||
|
||||
|
|
@ -64,9 +63,7 @@ def run_migrations_offline():
|
|||
|
||||
"""
|
||||
url = config.get_main_option("sqlalchemy.url")
|
||||
context.configure(
|
||||
url=url, target_metadata=get_metadata(), literal_binds=True
|
||||
)
|
||||
context.configure(url=url, target_metadata=get_metadata(), literal_binds=True)
|
||||
|
||||
with context.begin_transaction():
|
||||
context.run_migrations()
|
||||
|
|
@ -84,13 +81,13 @@ def run_migrations_online():
|
|||
# when there are no changes to the schema
|
||||
# reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html
|
||||
def process_revision_directives(context, revision, directives):
|
||||
if getattr(config.cmd_opts, 'autogenerate', False):
|
||||
if getattr(config.cmd_opts, "autogenerate", False):
|
||||
script = directives[0]
|
||||
if script.upgrade_ops.is_empty():
|
||||
directives[:] = []
|
||||
logger.info('No changes in schema detected.')
|
||||
logger.info("No changes in schema detected.")
|
||||
|
||||
conf_args = current_app.extensions['migrate'].configure_args
|
||||
conf_args = current_app.extensions["migrate"].configure_args
|
||||
if conf_args.get("process_revision_directives") is None:
|
||||
conf_args["process_revision_directives"] = process_revision_directives
|
||||
|
||||
|
|
@ -98,9 +95,7 @@ def run_migrations_online():
|
|||
|
||||
with connectable.connect() as connection:
|
||||
context.configure(
|
||||
connection=connection,
|
||||
target_metadata=get_metadata(),
|
||||
**conf_args
|
||||
connection=connection, target_metadata=get_metadata(), **conf_args
|
||||
)
|
||||
|
||||
with context.begin_transaction():
|
||||
|
|
|
|||
|
|
@ -11,17 +11,18 @@ import sqlalchemy as sa
|
|||
from sqlalchemy.orm import Session
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '190d5ef26e20'
|
||||
down_revision = 'a9e886c56482'
|
||||
revision = "190d5ef26e20"
|
||||
down_revision = "a9e886c56482"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
from app import Message
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('message', schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column('token_count', sa.Integer(), nullable=True))
|
||||
with op.batch_alter_table("message", schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column("token_count", sa.Integer(), nullable=True))
|
||||
|
||||
# Use this binding to connect to the database
|
||||
bind = op.get_bind()
|
||||
|
|
@ -38,5 +39,5 @@ def upgrade():
|
|||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('message', schema=None) as batch_op:
|
||||
batch_op.drop_column('token_count')
|
||||
with op.batch_alter_table("message", schema=None) as batch_op:
|
||||
batch_op.drop_column("token_count")
|
||||
|
|
|
|||
|
|
@ -3,36 +3,36 @@ import sqlalchemy as sa
|
|||
from sqlalchemy.sql import table, column, select
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'a9e886c56482'
|
||||
revision = "a9e886c56482"
|
||||
down_revision = None
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# Create room table
|
||||
op.create_table('room',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('name', sa.String(length=128), nullable=False),
|
||||
sa.Column('title', sa.String(length=128), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('name')
|
||||
op.create_table(
|
||||
"room",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("name", sa.String(length=128), nullable=False),
|
||||
sa.Column("title", sa.String(length=128), nullable=True),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
sa.UniqueConstraint("name"),
|
||||
)
|
||||
|
||||
# Add room_id column to message table
|
||||
op.add_column('message', sa.Column('room_id', sa.Integer(), nullable=True))
|
||||
op.add_column("message", sa.Column("room_id", sa.Integer(), nullable=True))
|
||||
|
||||
# Temporary table objects
|
||||
message_table = table('message',
|
||||
column('id', sa.Integer),
|
||||
column('username', sa.String),
|
||||
column('content', sa.String),
|
||||
column('room', sa.String),
|
||||
column('room_id', sa.Integer),
|
||||
)
|
||||
room_table = table('room',
|
||||
column('id', sa.Integer),
|
||||
column('name', sa.String)
|
||||
message_table = table(
|
||||
"message",
|
||||
column("id", sa.Integer),
|
||||
column("username", sa.String),
|
||||
column("content", sa.String),
|
||||
column("room", sa.String),
|
||||
column("room_id", sa.Integer),
|
||||
)
|
||||
room_table = table("room", column("id", sa.Integer), column("name", sa.String))
|
||||
|
||||
# Execution context
|
||||
conn = op.get_bind()
|
||||
|
|
@ -40,74 +40,86 @@ def upgrade():
|
|||
# Insert distinct rooms into room table and create mapping
|
||||
distinct_rooms = conn.execute(select(message_table.c.room).distinct())
|
||||
room_name_to_id = {}
|
||||
for room_name, in distinct_rooms:
|
||||
for (room_name,) in distinct_rooms:
|
||||
conn.execute(room_table.insert().values(name=room_name))
|
||||
room_id = conn.execute(select(room_table.c.id).where(room_table.c.name == room_name)).scalar()
|
||||
room_id = conn.execute(
|
||||
select(room_table.c.id).where(room_table.c.name == room_name)
|
||||
).scalar()
|
||||
room_name_to_id[room_name] = room_id
|
||||
|
||||
# Update message table with room_id
|
||||
for room_name, room_id in room_name_to_id.items():
|
||||
conn.execute(message_table.update().where(message_table.c.room == room_name).values(room_id=room_id))
|
||||
conn.execute(
|
||||
message_table.update()
|
||||
.where(message_table.c.room == room_name)
|
||||
.values(room_id=room_id)
|
||||
)
|
||||
|
||||
# Create new_message table
|
||||
new_message_table = op.create_table('new_message',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('username', sa.String(length=128), nullable=False),
|
||||
sa.Column('content', sa.String(length=1024), nullable=False),
|
||||
sa.Column('room_id', sa.Integer(), nullable=False),
|
||||
sa.ForeignKeyConstraint(['room_id'], ['room.id']),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
new_message_table = op.create_table(
|
||||
"new_message",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("username", sa.String(length=128), nullable=False),
|
||||
sa.Column("content", sa.String(length=1024), nullable=False),
|
||||
sa.Column("room_id", sa.Integer(), nullable=False),
|
||||
sa.ForeignKeyConstraint(["room_id"], ["room.id"]),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
)
|
||||
|
||||
# Copy data from old message table to new_message table
|
||||
old_messages = conn.execute(sa.select(message_table)).fetchall()
|
||||
for old_message in old_messages:
|
||||
conn.execute(new_message_table.insert().values(
|
||||
id=old_message.id,
|
||||
username=old_message.username,
|
||||
content=old_message.content,
|
||||
room_id=old_message.room_id
|
||||
))
|
||||
conn.execute(
|
||||
new_message_table.insert().values(
|
||||
id=old_message.id,
|
||||
username=old_message.username,
|
||||
content=old_message.content,
|
||||
room_id=old_message.room_id,
|
||||
)
|
||||
)
|
||||
|
||||
# Drop old message table and rename new_message to message
|
||||
op.drop_table('message')
|
||||
op.rename_table('new_message', 'message')
|
||||
op.drop_table("message")
|
||||
op.rename_table("new_message", "message")
|
||||
|
||||
|
||||
def downgrade():
|
||||
# Recreate old_message table with 'room' column
|
||||
old_message_table = op.create_table('old_message',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('username', sa.String(length=128), nullable=False),
|
||||
sa.Column('content', sa.String(length=1024), nullable=False),
|
||||
sa.Column('room', sa.String(length=128), nullable=False),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
old_message_table = op.create_table(
|
||||
"old_message",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("username", sa.String(length=128), nullable=False),
|
||||
sa.Column("content", sa.String(length=1024), nullable=False),
|
||||
sa.Column("room", sa.String(length=128), nullable=False),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
)
|
||||
|
||||
# Copy data back from message to old_message
|
||||
message_table = table('message',
|
||||
column('id', sa.Integer),
|
||||
column('username', sa.String),
|
||||
column('content', sa.String),
|
||||
column('room_id', sa.Integer)
|
||||
)
|
||||
room_table = table('room',
|
||||
column('id', sa.Integer),
|
||||
column('name', sa.String)
|
||||
message_table = table(
|
||||
"message",
|
||||
column("id", sa.Integer),
|
||||
column("username", sa.String),
|
||||
column("content", sa.String),
|
||||
column("room_id", sa.Integer),
|
||||
)
|
||||
room_table = table("room", column("id", sa.Integer), column("name", sa.String))
|
||||
|
||||
conn = op.get_bind()
|
||||
messages = conn.execute(select(message_table)).fetchall()
|
||||
for message in messages:
|
||||
room_name = conn.execute(select(room_table.c.name).where(room_table.c.id == message.room_id)).scalar()
|
||||
conn.execute(old_message_table.insert().values(
|
||||
id=message.id,
|
||||
username=message.username,
|
||||
content=message.content,
|
||||
room=room_name
|
||||
))
|
||||
room_name = conn.execute(
|
||||
select(room_table.c.name).where(room_table.c.id == message.room_id)
|
||||
).scalar()
|
||||
conn.execute(
|
||||
old_message_table.insert().values(
|
||||
id=message.id,
|
||||
username=message.username,
|
||||
content=message.content,
|
||||
room=room_name,
|
||||
)
|
||||
)
|
||||
|
||||
# Drop current message table and rename old_message to message
|
||||
op.drop_table('message')
|
||||
op.rename_table('old_message', 'message')
|
||||
op.drop_table('room')
|
||||
|
||||
op.drop_table("message")
|
||||
op.rename_table("old_message", "message")
|
||||
op.drop_table("room")
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@ depends_on = None
|
|||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table("activity_state", schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column("json_metadata", sa.UnicodeText(), server_default="{}"))
|
||||
batch_op.add_column(
|
||||
sa.Column("json_metadata", sa.UnicodeText(), server_default="{}")
|
||||
)
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ sections:
|
|||
- "Python is a powerful tool for hackers due to its simplicity and extensive libraries."
|
||||
- "Think about why Python is favored in the hacking community. Consider aspects like ease of use, versatility, and community support."
|
||||
tokens_for_ai: "Guide the student to think about the reasons Python is popular among hackers. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correct. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correctly. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
question: "Why do you think Python is a popular choice for hackers? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
|
|
@ -34,17 +34,24 @@ sections:
|
|||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
correct_answers: "n+1"
|
||||
points: "n+random(1,20)"
|
||||
attempts: "n+1"
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
metadata_add:
|
||||
points: "n+random(1,4)"
|
||||
attempts: "n+1"
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. Why do you think Python is favored by hackers? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
metadata_add:
|
||||
points: "n+random(1,2)"
|
||||
attempts: "n+1"
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
|
|
@ -71,7 +78,7 @@ sections:
|
|||
- "Python has many libraries that are useful for security tasks, such as Scapy, Nmap, and PyCrypto."
|
||||
- "Think about how these libraries can be used in security analysis and hacking. Consider aspects like network scanning, packet manipulation, and encryption."
|
||||
tokens_for_ai: "Guide the student to think about the use of Python libraries in security. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correct. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correctly. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
question: "How do you think Python libraries like Scapy and PyCrypto are used in security tasks? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
|
|
@ -87,17 +94,24 @@ sections:
|
|||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
correct_answers: "n+1"
|
||||
points: "n+random(1,20)"
|
||||
attempts: "n+1"
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
metadata_add:
|
||||
points: "n+random(1,4)"
|
||||
attempts: "n+1"
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. How do you think these libraries are used in security? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
metadata_add:
|
||||
points: "n+random(1,2)"
|
||||
attempts: "n+1"
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
|
|
@ -127,7 +141,7 @@ sections:
|
|||
- "Python can be used in forensic analysis to automate tasks and analyze data."
|
||||
- "Think about how Python scripts can help in forensic investigations. Consider aspects like data parsing, log analysis, and evidence extraction."
|
||||
tokens_for_ai: "Guide the student to think about the use of Python in forensic analysis. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correct. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correctly. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
question: "How do you think Python can be used in forensic analysis? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
|
|
@ -143,17 +157,24 @@ sections:
|
|||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
correct_answers: "n+1"
|
||||
points: "n+random(1,20)"
|
||||
attempts: "n+1"
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
metadata_add:
|
||||
points: "n+random(1,4)"
|
||||
attempts: "n+1"
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. How do you think Python helps in forensic analysis? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
metadata_add:
|
||||
points: "n+random(1,2)"
|
||||
attempts: "n+1"
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
|
|
@ -180,7 +201,7 @@ sections:
|
|||
- "Automation is key in forensic analysis to handle large volumes of data efficiently."
|
||||
- "Think about how Python can automate repetitive tasks in forensic investigations. Consider aspects like script execution, data filtering, and report generation."
|
||||
tokens_for_ai: "Guide the student to think about automating forensic tasks with Python. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correct. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correctly. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
question: "How do you think Python can automate tasks in forensic investigations? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
|
|
@ -196,17 +217,24 @@ sections:
|
|||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
correct_answers: "n+1"
|
||||
points: "n+random(1,20)"
|
||||
attempts: "n+1"
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
metadata_add:
|
||||
points: "n+random(1,4)"
|
||||
attempts: "n+1"
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. How do you think Python automates forensic tasks? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
metadata_add:
|
||||
points: "n+random(1,2)"
|
||||
attempts: "n+1"
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
|
|
@ -236,7 +264,7 @@ sections:
|
|||
- "Python is used in security engineering to develop tools and scripts for vulnerability assessment and penetration testing."
|
||||
- "Think about how Python can be used to identify and exploit vulnerabilities. Consider aspects like script development, tool integration, and testing automation."
|
||||
tokens_for_ai: "Guide the student to think about the use of Python in security engineering. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correct. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correctly. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
question: "How do you think Python is used in security engineering? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
|
|
@ -252,17 +280,24 @@ sections:
|
|||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
correct_answers: "n+1"
|
||||
points: "n+random(1,20)"
|
||||
attempts: "n+1"
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
metadata_add:
|
||||
points: "n+random(1,4)"
|
||||
attempts: "n+1"
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. How do you think Python is used in security engineering? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
metadata_add:
|
||||
points: "n+random(1,2)"
|
||||
attempts: "n+1"
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
|
|
@ -289,7 +324,7 @@ sections:
|
|||
- "Python is often used to develop custom security tools for specific tasks."
|
||||
- "Think about how you can use Python to create tools for security analysis. Consider aspects like functionality, user interface, and integration with other tools."
|
||||
tokens_for_ai: "Guide the student to think about developing security tools with Python. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correct. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correctly. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
question: "How do you think you can use Python to develop security tools? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
|
|
@ -305,17 +340,24 @@ sections:
|
|||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
correct_answers: "n+1"
|
||||
points: "n+random(1,20)"
|
||||
attempts: "n+1"
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
metadata_add:
|
||||
points: "n+random(1,4)"
|
||||
attempts: "n+1"
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. How do you think Python can be used to develop security tools? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
metadata_add:
|
||||
points: "n+random(1,2)"
|
||||
attempts: "n+1"
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
|
|
|
|||
|
|
@ -226,13 +226,20 @@ def simulate_activity(yaml_file_path):
|
|||
for key, value in transition["metadata_add"].items():
|
||||
if value == "the-users-response":
|
||||
value = user_response
|
||||
elif isinstance(value, str) and (value.startswith("n+") or value.startswith("n-")):
|
||||
# Extract the numeric part c and apply the operation +/-
|
||||
c = int(value[1:])
|
||||
if value.startswith("n+"):
|
||||
value = metadata.get(key, 0) + c
|
||||
elif value.startswith("n-"):
|
||||
value = metadata.get(key, 0) - c
|
||||
elif isinstance(value, str):
|
||||
if value.startswith("n+random(") and value.endswith(")"):
|
||||
# Extract the range and apply the random increment
|
||||
range_values = value[9:-1].split(",")
|
||||
if len(range_values) == 2:
|
||||
x, y = map(int, range_values)
|
||||
value = metadata.get(key, 0) + random.randint(x, y)
|
||||
elif value.startswith("n+") or value.startswith("n-"):
|
||||
# Extract the numeric part c and apply the operation +/-
|
||||
c = int(value[1:])
|
||||
if value.startswith("n+"):
|
||||
value = metadata.get(key, 0) + c
|
||||
elif value.startswith("n-"):
|
||||
value = metadata.get(key, 0) - c
|
||||
metadata[key] = value
|
||||
|
||||
if "metadata_tmp_add" in transition:
|
||||
|
|
@ -264,9 +271,10 @@ def simulate_activity(yaml_file_path):
|
|||
print(f"\nMetadata: {json.dumps(metadata, indent=2)}")
|
||||
|
||||
if category not in [
|
||||
"off_topic",
|
||||
"asking_clarifying_questions",
|
||||
"partial_understanding",
|
||||
"asking_clarifying_questions",
|
||||
"set_language",
|
||||
"off_topic",
|
||||
]:
|
||||
break
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue