{"id":13657518,"url":"https://github.com/smashwilson/hubot-markov","last_synced_at":"2025-10-12T20:17:48.515Z","repository":{"id":12205419,"uuid":"14811291","full_name":"smashwilson/hubot-markov","owner":"smashwilson","description":"Hubot watches all, and builds a markov model from everything you say.","archived":false,"fork":false,"pushed_at":"2023-02-27T20:34:05.000Z","size":540,"stargazers_count":62,"open_issues_count":15,"forks_count":23,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-11T16:25:12.537Z","etag":null,"topics":["coffeescript","hubot","markov-model"],"latest_commit_sha":null,"homepage":"","language":"CoffeeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smashwilson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2013-11-29T22:27:44.000Z","updated_at":"2025-01-04T02:01:23.000Z","dependencies_parsed_at":"2024-01-11T23:23:03.209Z","dependency_job_id":"f506665e-51d5-4e01-ad7f-6651f0fdc4b3","html_url":"https://github.com/smashwilson/hubot-markov","commit_stats":{"total_commits":245,"total_committers":19,"mean_commits":"12.894736842105264","dds":0.6979591836734693,"last_synced_commit":"06fe77506f800b372e3b18cd86470a828bcd60fb"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smashwilson%2Fhubot-markov","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smashwilson%2Fhubot-markov/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smashwilson%2Fhubot-markov/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smashwilson%2Fhubot-markov/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smashwilson","download_url":"https://codeload.github.com/smashwilson/hubot-markov/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243815552,"owners_count":20352189,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["coffeescript","hubot","markov-model"],"created_at":"2024-08-02T05:00:44.327Z","updated_at":"2025-10-12T20:17:43.482Z","avatar_url":"https://github.com/smashwilson.png","language":"CoffeeScript","funding_links":[],"categories":["CoffeeScript","Miscellaneous"],"sub_categories":[],"readme":"# Hubot Markov Model\n\n[![npm](https://img.shields.io/npm/v/hubot-markov.svg?style=plastic)](https://www.npmjs.com/package/hubot-markov) | ![Continuous Integration](https://github.com/smashwilson/hubot-markov/workflows/Continuous%20Integration/badge.svg)\n\nGenerates a markov model based on everything that your Hubot sees in your chat.\n\n## Installing\n\n1. Add `hubot-markov` to your `package.json` with `npm install --save hubot-markov`:\n\n```json\n  \"dependencies\": {\n    \"hubot-markov\": \"~2.0.0\"\n  },\n```\n\n2. Require the module in `external-scripts.json`:\n\n```json\n[\"hubot-markov\"]\n```\n\n3. Run `npm update` and restart your Hubot.\n\nConsult the [upgrading guide](./docs/upgrade.md) for instructions on migrating from older major versions.\n\n## Commands\n\nBy default, saying anything at all in chat trains the model. The robot is always watching!\n\n`Hubot: markov` will randomly generate text based on the current contents of its model.\n\n`Hubot: markov your mother is a` will generate a random phrase seeded with the phrase you give it. This command might output \"your mother is a classy lady\", for example. Remember: Hubot is an innocent soul, and what he says only acts as a mirror for everything in your hearts.\n\n`Hubot: remarkov` and `Hubot: mmarkov` are similar, but traverse node transitions in different directions: `remarkov` chains backwards from a given ending state, and `mmarkov` chains both forward and backward.\n\n## Configuration\n\nThe Hubot markov model can optionally be configured by setting environment variables:\n\n* `HUBOT_MARKOV_DEFAULT_MODEL` _(default: true)_ controls the inclusion of the default, forward-chaining model that learns from all text messages. Set this to `false` to omit the default model and disable the `markov` and `mmarkov` commands.\n\n* `HUBOT_MARKOV_REVERSE_MODEL` _(default: true)_ controls the inclusion of the reverse model. Setting this to `false` saves some space in your database, but doesn't let you use `remarkov` or `mmarkov`.\n\n* `HUBOT_MARKOV_PLY` _(default: 1)_ controls the *order* of the default models that are built; effectively, how many previous states (words) are considered to choose the next state. You can bump this up if you'd like, but the default of 1 is both economical with storage and maximally hilarious.\n\n* `HUBOT_MARKOV_LEARN_MIN` _(default: 1)_ controls the minimum length of a phrase that will be used to train the default models. Set this higher to avoid training your model with a bunch of immediate terminal transitions like \"lol\".\n\n* `HUBOT_MARKOV_GENERATE_MAX` _(default: 50)_ controls the maximum size of a markov chain that will be generated by the `markov`, `remarkov`, and `mmarkov` commands.\n\n* `HUBOT_MARKOV_STORAGE` _(default: memory)_ controls the backing storage used to persist the default models. Choices include:\n  * `memory`, the default, which stores transitions entirely in-process (lost on restart);\n  * `redis`, which stores data in a Redis cache; or\n  * `postgres`, which stores data in a PostgreSQL database.\n\n* `HUBOT_MARKOV_STORAGE_URL` supplies additional configuration required by the `redis` and `postgres` storage backends. The formats are `redis://${USER}:${PASSWORD}@${HOSTNAME}:${PORT}/${DBNUM}` and `postgres://${USER}:${PASSWORD}@${HOSTNAME}:${PORT}/${DATABASE}` with defaults omitted.\n\n* `HUBOT_MARKOV_RESPOND_CHANCE` controls the chance that Hubot will respond un-prompted to a message it sees by using the last word in the message as the seed. Set this to a value between 0 and 1.0 to enable the feature. Leaving this variable unset or setting it to 0 will disable the feature.\n\n* `HUBOT_MARKOV_INCLUDE_URLS` _(default: false)_ will default to ignoring messages that include URLs from the default models.\n\n* `HUBOT_MARKOV_IGNORELIST` _(default: empty)_ is interpreted as a comma-separated list of usernames to ignore for purposes of markov indexing. You can use this to prevent the output of other bots or integrations from clogging up your model.\n\n* `HUBOT_MARKOV_IGNORE_MESSAGE_LIST` _(default: empty)_ is interpreted as a comma-separated list of sub-phrases to ignore from default and reverse models. Is a basic substring match for every message. Use this to ignore terms, like your bot's username\n\n* `HUBOT_MARKOV_LEARNING_LISTEN_MODE` - _(default: 'catch-all')_ change the robot.listen mode for learning, helpful if you have other plugins that interfere with robot.catchAll. Options:\n  * 'catch-all', learn message if no other scripts process message. \n  * 'hear-all', learn every message, regardless if another script handled it.\n  *  If set to another value, will use it as a robot.listen regex pattern\n  \n* `HUBOT_MARKOV_RESPOND_LISTEN_MODE` - _(default: 'catch-all')_ change the robot.listen mode for responding, helpful if you have other plugins that interfere with robot.catchAll. Options:\n  * 'catch-all', learn message if no other scripts process message. \n  * 'hear-all', learn every message, regardless if another script handled it.\n  *  If set to another value, will use it as a robot.listen regex pattern\n\nTo re-use a PostgreSQL connection with other parts of your Hubot, define a robot method called `getDatabase` that returns the connection object. This package uses [pg-promise](https://www.npmjs.com/package/pg-promise).\n\n## Custom models\n\nStore and generate text from arbitrary sources and in more complex commands by using the programmatic API available at `robot.markov`. Call `robot.markov.createModel` during script initialization to configure a model, then use `robot.markov.modelNamed` to access the model instance in commands that train it or generate from it.\n\n### Example: Manual Model\n\n```coffee\nmodule.exports = (robot) -\u003e\n  MODELNAME = 'manual'\n\n  # Create or connect to a model with all default options\n  robot.markov.createModel MODELNAME\n\n  robot.respond /modeladd\\s+(.+)/, (msg) -\u003e\n    robot.markov.modelNamed MODELNAME, (model) -\u003e\n      model.learn msg.match[1], -\u003e\n        msg.reply 'Input accepted.'\n\n  robot.respond /modelgen(?:\\s+(.+))/, (msg) -\u003e\n    robot.markov.modelNamed MODELNAME, (model) -\u003e\n      model.generate msg.match[1] or '', 50, (output) -\u003e\n        msg.reply output\n```\n\n### Example: Letter-Based Model\n\n```coffee\nmodule.exports = (robot) -\u003e\n  MODELNAME = 'letters'\n\n  # Create or connect to a model with a custom pre- and post-processor\n  robot.markov.createModel MODELNAME, {}, (model) -\u003e\n    model.processWith\n      pre: (input) -\u003e input.split('')\n      post: (output) -\u003e output.join('')\n\n  robot.catchAll (msg) -\u003e\n    # Filter out \"lol\"\n    return if /^\\s*l(o+)l\\s*/.test msg.text\n\n    robot.markov.modelNamed MODELNAME, (model) -\u003e\n      model.learn msg.text\n\n  robot.respond /lettergen(?:\\s+(.+))/, (msg) -\u003e\n    robot.markov.modelNamed MODELNAME, (model) -\u003e\n      model.generate msg.match[1] or '', 100, (output) -\u003e\n        msg.reply output\n```\n\nThe full API is available in [the docs/ directory.](./docs/api.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmashwilson%2Fhubot-markov","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmashwilson%2Fhubot-markov","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmashwilson%2Fhubot-markov/lists"}