|
1 |
| -paths = [ |
2 |
| - 'recipes/alkaline-noodles.md', |
3 |
| - 'recipes/almond-cake.md', |
4 |
| - 'recipes/banana-bread.md', |
5 |
| - 'recipes/basque-cheesecake.md', |
6 |
| - 'recipes/black-bean-soup.md', |
7 |
| - 'recipes/blueberry-muffins.md', |
8 |
| - 'recipes/caldo-verde.md', |
9 |
| - 'recipes/candied-walnuts.md', |
10 |
| - 'recipes/chicken-and-dumplings.md', |
11 |
| - 'recipes/chicken-and-pepper-stir-fry.md', |
12 |
| - 'recipes/chicken-noodle-soup.md', |
13 |
| - 'recipes/chicken-salad.md', |
14 |
| - 'recipes/chili-oil.md', |
15 |
| - 'recipes/chocolate-chip-cookies.md', |
16 |
| - 'recipes/chocolate-ice-cream.md', |
17 |
| - 'recipes/chocolate-mug-cake.md', |
18 |
| - 'recipes/churros.md', |
19 |
| - 'recipes/cioppino.md', |
20 |
| - 'recipes/clam-chowder.md', |
21 |
| - 'recipes/daikon-rib-soup.md', |
22 |
| - 'recipes/dashi.md', |
23 |
| - 'recipes/dumplings.md', |
24 |
| - 'recipes/egg-and-tomato.md', |
25 |
| - 'recipes/financiers.md', |
26 |
| - 'recipes/florentines.md', |
27 |
| - 'recipes/garlic-shrimp.md', |
28 |
| - 'recipes/gazpacho.md', |
29 |
| - 'recipes/general-tsos-chicken.md', |
30 |
| - 'recipes/granola.md', |
31 |
| - 'recipes/lemon-bars.md', |
32 |
| - 'recipes/lobster-rolls.md', |
33 |
| - 'recipes/miso-soup.md', |
34 |
| - 'recipes/nachos.md', |
35 |
| - 'recipes/oatmeal-raisin-cookies.md', |
36 |
| - 'recipes/orecchiette-with-sausage-and-broccoli-rabe.md', |
37 |
| - 'recipes/pan-con-tomate.md', |
38 |
| - 'recipes/pan-fried-baozi.md', |
39 |
| - 'recipes/panzanella.md', |
40 |
| - 'recipes/pho-bo.md', |
41 |
| - 'recipes/pie-crust.md', |
42 |
| - 'recipes/pizza.md', |
43 |
| - 'recipes/pizzelles.md', |
44 |
| - 'recipes/pot-beans.md', |
45 |
| - 'recipes/potato-salad.md', |
46 |
| - 'recipes/pumpkin-pie.md', |
47 |
| - 'recipes/ratatouille.md', |
48 |
| - 'recipes/red-cooked-fish.md', |
49 |
| - 'recipes/red-cooked-ribs.md', |
50 |
| - 'recipes/rice-pudding.md', |
51 |
| - 'recipes/roasted-chicken.md', |
52 |
| - 'recipes/roasted-vegetable.md', |
53 |
| - 'recipes/scones.md', |
54 |
| - 'recipes/sheet-pan-brats.md', |
55 |
| - 'recipes/shoyu-ramen.md', |
56 |
| - 'recipes/smashed-cucumber-salad.md', |
57 |
| - 'recipes/soft-boiled-eggs.md', |
58 |
| - 'recipes/soltero.md', |
59 |
| - 'recipes/somen.md', |
60 |
| - 'recipes/soondubu-jjigae.md', |
61 |
| - 'recipes/spaetzle.md', |
62 |
| - 'recipes/sugar-cookies.md', |
63 |
| - 'recipes/taiwanese-beef-noodle-soup.md', |
64 |
| - 'recipes/thumbprint-cookies.md', |
65 |
| - 'recipes/tomato-soup.md', |
66 |
| - 'recipes/wontons-in-chili-oil.md', |
67 |
| - 'recipes/yeasted-waffles.md', |
68 |
| - 'recipes/yuca-fries.md', |
69 |
| -] |
70 |
| - |
71 |
| -contents = [] |
72 |
| -for path in paths: |
73 |
| - with open(path) as f: |
74 |
| - content = f.read() |
75 |
| - contents.append(content.strip()) |
| 1 | +import logging |
| 2 | +import os |
| 3 | +from logging.config import dictConfig |
| 4 | + |
| 5 | +from dotenv import load_dotenv |
| 6 | +from slack_bolt import App |
| 7 | + |
| 8 | + |
| 9 | +dictConfig({ |
| 10 | + 'version': 1, |
| 11 | + 'disable_existing_loggers': False, |
| 12 | + 'formatters': { |
| 13 | + 'standard': { |
| 14 | + 'format': '{asctime} {levelname} {process} [{filename}:{lineno}] - {message}', |
| 15 | + 'style': '{', |
| 16 | + } |
| 17 | + }, |
| 18 | + 'handlers': { |
| 19 | + 'console': { |
| 20 | + 'level': 'INFO', |
| 21 | + 'class': 'logging.StreamHandler', |
| 22 | + 'formatter': 'standard', |
| 23 | + }, |
| 24 | + }, |
| 25 | + 'loggers': { |
| 26 | + '': { |
| 27 | + 'handlers': ['console'], |
| 28 | + 'level': 'DEBUG', |
| 29 | + 'propagate': True, |
| 30 | + }, |
| 31 | + # 'werkzeug': { |
| 32 | + # 'handlers': ['console'], |
| 33 | + # 'level': 'INFO', |
| 34 | + # 'propagate': False, |
| 35 | + # }, |
| 36 | + }, |
| 37 | +}) |
| 38 | + |
| 39 | +logger = logging.getLogger(__name__) |
| 40 | + |
| 41 | +load_dotenv('.env.private') |
76 | 42 |
|
77 | 43 | DEVELOPER_MESSAGE_TEMPLATE = """You're a private chef. The couple you work for has given you examples of their favorite recipes as Markdown below. Help them meal plan, either by using these recipes or thinking of new ones that you think they'd like based on the given examples. Be concise and include no superfluous details. When sharing a recipe, use the format of the included Markdown recipes.
|
78 | 44 |
|
79 | 45 | {recipes}
|
80 |
| -""" |
| 46 | +""" # noqa |
| 47 | + |
| 48 | + |
| 49 | +# TODO: Message slack on a schedule with menu for the week. |
| 50 | +# Allow interaction in a thread (bolt app), both about the menu but also on-demand (at any time). |
| 51 | +# Bonus: if there's a really good recipe, open a PR to merge it to the repo. |
| 52 | +def make_prompt(write=False): |
| 53 | + paths = [ |
| 54 | + 'recipes/alkaline-noodles.md', |
| 55 | + 'recipes/almond-cake.md', |
| 56 | + 'recipes/banana-bread.md', |
| 57 | + 'recipes/basque-cheesecake.md', |
| 58 | + 'recipes/black-bean-soup.md', |
| 59 | + 'recipes/blueberry-muffins.md', |
| 60 | + 'recipes/caldo-verde.md', |
| 61 | + 'recipes/candied-walnuts.md', |
| 62 | + 'recipes/chicken-and-dumplings.md', |
| 63 | + 'recipes/chicken-and-pepper-stir-fry.md', |
| 64 | + 'recipes/chicken-noodle-soup.md', |
| 65 | + 'recipes/chicken-salad.md', |
| 66 | + 'recipes/chili-oil.md', |
| 67 | + 'recipes/chocolate-chip-cookies.md', |
| 68 | + 'recipes/chocolate-ice-cream.md', |
| 69 | + 'recipes/chocolate-mug-cake.md', |
| 70 | + 'recipes/churros.md', |
| 71 | + 'recipes/cioppino.md', |
| 72 | + 'recipes/clam-chowder.md', |
| 73 | + 'recipes/daikon-rib-soup.md', |
| 74 | + 'recipes/dashi.md', |
| 75 | + 'recipes/dumplings.md', |
| 76 | + 'recipes/egg-and-tomato.md', |
| 77 | + 'recipes/financiers.md', |
| 78 | + 'recipes/florentines.md', |
| 79 | + 'recipes/garlic-shrimp.md', |
| 80 | + 'recipes/gazpacho.md', |
| 81 | + 'recipes/general-tsos-chicken.md', |
| 82 | + 'recipes/granola.md', |
| 83 | + 'recipes/lemon-bars.md', |
| 84 | + 'recipes/lobster-rolls.md', |
| 85 | + 'recipes/miso-soup.md', |
| 86 | + 'recipes/nachos.md', |
| 87 | + 'recipes/oatmeal-raisin-cookies.md', |
| 88 | + 'recipes/orecchiette-with-sausage-and-broccoli-rabe.md', |
| 89 | + 'recipes/pan-con-tomate.md', |
| 90 | + 'recipes/pan-fried-baozi.md', |
| 91 | + 'recipes/panzanella.md', |
| 92 | + 'recipes/pho-bo.md', |
| 93 | + 'recipes/pie-crust.md', |
| 94 | + 'recipes/pizza.md', |
| 95 | + 'recipes/pizzelles.md', |
| 96 | + 'recipes/pot-beans.md', |
| 97 | + 'recipes/potato-salad.md', |
| 98 | + 'recipes/pumpkin-pie.md', |
| 99 | + 'recipes/ratatouille.md', |
| 100 | + 'recipes/red-cooked-fish.md', |
| 101 | + 'recipes/red-cooked-ribs.md', |
| 102 | + 'recipes/rice-pudding.md', |
| 103 | + 'recipes/roasted-chicken.md', |
| 104 | + 'recipes/roasted-vegetable.md', |
| 105 | + 'recipes/scones.md', |
| 106 | + 'recipes/sheet-pan-brats.md', |
| 107 | + 'recipes/shoyu-ramen.md', |
| 108 | + 'recipes/smashed-cucumber-salad.md', |
| 109 | + 'recipes/soft-boiled-eggs.md', |
| 110 | + 'recipes/soltero.md', |
| 111 | + 'recipes/somen.md', |
| 112 | + 'recipes/soondubu-jjigae.md', |
| 113 | + 'recipes/spaetzle.md', |
| 114 | + 'recipes/sugar-cookies.md', |
| 115 | + 'recipes/taiwanese-beef-noodle-soup.md', |
| 116 | + 'recipes/thumbprint-cookies.md', |
| 117 | + 'recipes/tomato-soup.md', |
| 118 | + 'recipes/wontons-in-chili-oil.md', |
| 119 | + 'recipes/yeasted-waffles.md', |
| 120 | + 'recipes/yuca-fries.md', |
| 121 | + ] |
| 122 | + |
| 123 | + contents = [] |
| 124 | + for path in paths: |
| 125 | + with open(f'../{path}') as f: |
| 126 | + content = f.read() |
| 127 | + contents.append(content.strip()) |
81 | 128 |
|
82 |
| -with open('chefbot/prompt.txt', 'w') as f: |
83 | 129 | recipes = '\n\n'.join(contents)
|
| 130 | + # NOTE: o3-mini-2025-01-31, medium reasoning effort works well. Markdown isn't always correct. |
84 | 131 | prompt = DEVELOPER_MESSAGE_TEMPLATE.format(recipes=recipes)
|
85 | 132 |
|
86 |
| - f.write(prompt) |
| 133 | + if write: |
| 134 | + with open('prompt.txt', 'w') as f: |
| 135 | + f.write(prompt) |
87 | 136 |
|
88 |
| -# NOTE: o3-mini-2025-01-31, medium reasoning effort works well. Markdown isn't always correct. |
| 137 | + return prompt |
89 | 138 |
|
90 |
| -# TODO: Message slack on a schedule with menu for the week. |
91 |
| -# Allow interaction in a thread (bolt app), both about the menu but also on-demand (at any time). |
92 |
| -# If there's a really good recipe, open a PR to merge it to the repo. |
| 139 | + |
| 140 | +app = App( |
| 141 | + token=os.environ.get('SLACK_BOT_TOKEN'), |
| 142 | + signing_secret=os.environ.get('SLACK_SIGNING_SECRET') |
| 143 | +) |
| 144 | + |
| 145 | + |
| 146 | +@app.event('app_mention') |
| 147 | +def respond_in_thread(event, say): |
| 148 | + ts = event.get('ts') |
| 149 | + |
| 150 | + say( |
| 151 | + text='yo', |
| 152 | + thread_ts=ts |
| 153 | + ) |
| 154 | + |
| 155 | + |
| 156 | +if __name__ == '__main__': |
| 157 | + port = int(os.environ.get('PORT', 3000)) |
| 158 | + app.start(port=port) |
0 commit comments