diff --git a/app.py b/app.py index 8c39355..a104a02 100644 --- a/app.py +++ b/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 ): diff --git a/migrations/env.py b/migrations/env.py index 4c97092..d004741 100644 --- a/migrations/env.py +++ b/migrations/env.py @@ -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(): diff --git a/migrations/versions/190d5ef26e20_add_token_count_to_message.py b/migrations/versions/190d5ef26e20_add_token_count_to_message.py index 8ca0137..3b81852 100644 --- a/migrations/versions/190d5ef26e20_add_token_count_to_message.py +++ b/migrations/versions/190d5ef26e20_add_token_count_to_message.py @@ -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") diff --git a/migrations/versions/a9e886c56482_create_room_table.py b/migrations/versions/a9e886c56482_create_room_table.py index 6d0ea9f..704fb53 100644 --- a/migrations/versions/a9e886c56482_create_room_table.py +++ b/migrations/versions/a9e886c56482_create_room_table.py @@ -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") diff --git a/migrations/versions/d737de68d6fa_add_metadata_field_to_activitystate.py b/migrations/versions/d737de68d6fa_add_metadata_field_to_activitystate.py index 0ac2450..6779615 100644 --- a/migrations/versions/d737de68d6fa_add_metadata_field_to_activitystate.py +++ b/migrations/versions/d737de68d6fa_add_metadata_field_to_activitystate.py @@ -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 ### diff --git a/research/activity21.yaml b/research/activity21.yaml index b54ac9d..1933554 100644 --- a/research/activity21.yaml +++ b/research/activity21.yaml @@ -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. ❓" diff --git a/research/guarded_ai.py b/research/guarded_ai.py index 628c19e..4595bfb 100644 --- a/research/guarded_ai.py +++ b/research/guarded_ai.py @@ -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