[00:02.180 --> 00:03.160] Good afternoon, everyone. [00:03.720 --> 00:05.020] It's very good to see you. [00:06.880 --> 00:09.560] It's... I'm kind of scared, forgive me. [00:09.900 --> 00:10.860] It's great to see you. [00:11.240 --> 00:12.580] Great to see you on a Sunday at HOPE. [00:12.720 --> 00:13.940] I know we're all kind of partied out. [00:14.060 --> 00:16.000] We're all kind of tired from Saturday night and the concerts. [00:17.320 --> 00:19.540] It means a lot to me that you're all here, and I wanted to thank you. [00:21.300 --> 00:23.980] So, that said, I'm going to dive right into my talk. [00:24.160 --> 00:26.780] This is Constructing Exocortices with Huginn and Halo. [00:29.320 --> 00:30.660] So, just a moment. [00:34.610 --> 00:35.410] Okay, there we go. [00:35.690 --> 00:37.130] Now the slides are properly sized. [00:37.710 --> 00:42.410] My obligatory disclaimer, I'm speaking only for myself, not my employers, past, present, or future. [00:44.870 --> 00:46.530] So, a brief overview of my talk. [00:46.670 --> 00:48.790] I'm going to talk about what an exocortex is. [00:48.950 --> 00:50.990] I'm going to talk about some possible components of one. [00:51.210 --> 00:52.710] I'm going to talk about what they can do. [00:53.230 --> 01:00.890] I'm also going to go into one of the applications I built into my own exocortex that I use fairly heavily, which is a personal web archive. [01:01.390 --> 01:03.490] I'm going to describe how you can build one. [01:03.850 --> 01:06.130] I'm going to talk about the software you can use to build one. [01:06.650 --> 01:10.790] And I'm going to talk about how to interact with the framework used to build an exocortex. [01:10.990 --> 01:12.010] The framework is called Huginn. [01:12.970 --> 01:16.750] I'm going to show a simple agent network and a complex agent network. [01:17.130 --> 01:21.930] I'm going to show what the events that comprise the information inside the framework look like. [01:22.450 --> 01:26.670] Then I'm going to talk about the soft stuff, which is why I built an exocortex and what I do with it. [01:27.110 --> 01:31.350] I'm going to show a few of the agent networks that I use. [01:32.390 --> 01:36.050] Then I'm going to talk about what I get out of it and what you guys can get out of it. [01:36.890 --> 01:38.270] So, let's move on. [01:38.530 --> 01:40.250] What is an exocortex? [01:41.050 --> 01:46.750] Well, of course, there's a Greek prefix, exo, meaning outside or external to. [01:47.690 --> 01:54.630] The word exocortex was first postulated, or the concept of an exocortex, excuse me, was first postulated by J.C. [01:54.670 --> 01:58.630] Arlick Leiter in March of 1960 in a paper he wrote called Man-Computer Symbiosis. [01:59.810 --> 02:14.450] He said that an exocortex was either a hypothetical or a nascent additional cortex of the human brain situated outside of the organism, which would function in addition to the various lobes of the brain, like the frontal, the parietal, the occipital, the temporal lobe, [02:14.590 --> 02:15.110] etc., etc. [02:16.450 --> 02:31.490] He also said that an exocortex constituted an external information processing system which could provide additional cognitive capacity or abilities to the human mind, which are not yet directly connected to the human brain, but we're starting to get there. [02:31.630 --> 02:40.930] We've got TDCS, TMS, BrainGate, and these direct interface technologies are going to be developing in years to come, but I'm not going to touch on those. [02:41.950 --> 02:49.170] A couple years later, Benjamin Houston wrote that an exocortex would be an organ that resides outside of the brain that aids in high-level thinking. [02:49.170 --> 02:57.870] Ideally, there would be a symbiotic relationship between the user and the information processing infrastructure where each complements and compensates for the shortcomings of the other. [02:59.030 --> 03:07.190] Ultimately, where the bits meet the hardware, an exocortex is a hardware and software construct which works in concert with the brain to extend its capabilities. [03:09.030 --> 03:11.350] So, some possible components of an exocortex. [03:11.610 --> 03:14.070] They're actually surprisingly common these days. [03:14.450 --> 03:18.210] We've got networked handheld devices like smart watches and smart glasses. [03:18.970 --> 03:21.190] Pretty much everyone has a cell phone these days. [03:21.430 --> 03:29.890] So, we've got cellular data service, Wi-Fi, and Bluetooth for interfacing devices, as well as accessing information storage services. [03:30.770 --> 03:40.850] There are information processing and storage capabilities, which are everything from notebook computers, netbook computers, laptops, all the way up to virtual machines and bare metal. [03:41.450 --> 03:50.950] Of course, there's security infrastructure like multi-factor authentication, protecting access to these assets, firewalls, IDSs, IPSs, enforced crypto, real-time response. [03:51.670 --> 03:52.330] You know the drill. [03:53.550 --> 03:55.970] And there is externally addressable mass storage. [03:56.550 --> 04:02.150] Blogs, link collections, wikis, personal archives, file dumps, home directories, in short, it's your stuff. [04:02.390 --> 04:11.130] It's all of the information that you collect, you accumulate, you process, you go through later to draw conclusions, to come up with new ideas, and implement those ideas. [04:11.470 --> 04:14.210] And, of course, there is the software that hooks it all together. [04:14.550 --> 04:15.170] Lots of software. [04:17.830 --> 04:19.830] I'm trying to cut down a little bit of the feedback here. [04:19.830 --> 04:22.890] So, what can an exo-cortex do? [04:25.930 --> 04:27.450] Ultimately, whatever you design it to do. [04:28.890 --> 04:36.730] An exo-cortex's functional modules can monitor data feeds in real-time and respond to them. [04:36.850 --> 04:38.830] They can manage some aspects of your finances. [04:39.710 --> 04:41.690] They can implement a personal search engine. [04:41.910 --> 04:43.970] They can manage an archive data on your behalf. [04:44.150 --> 04:45.310] They can monitor your infrastructure. [04:45.550 --> 04:48.230] And they can find things that are useful to you that you didn't know about previously. [04:49.910 --> 04:52.750] The application that I mentioned earlier is a personal web archive. [04:52.990 --> 04:56.530] And I've got it broken down, broadly speaking, into functional modules. [04:56.870 --> 05:02.070] The user interface front-end is an instant messenger client that's running on both my smartphone and my desktop. [05:03.330 --> 05:09.890] The UI back-end is a bot which is connected to the same XMPP server that stores requests in a message queue. [05:20.410 --> 05:28.830] There's a software agent that pulls that message queue every 60 seconds, configurable, looking for URLs. [05:29.090 --> 05:32.770] And when it finds the URL, it snips it out of the message and it downloads it. [05:34.210 --> 05:39.030] When it downloads the HTML, it renders the HTML into text and then... [05:40.010 --> 05:40.770] Excuse me. [05:41.170 --> 05:42.270] It... I'm really sorry. [05:42.630 --> 05:44.910] And then uploads it into the archive application. [05:45.430 --> 05:50.490] The archive itself is an application that stores text very efficiently and presents it in a form that's easy to read later. [05:51.010 --> 05:54.690] It also makes it easy to edit pages, rename pages, and delete pages. [05:54.690 --> 06:00.170] I use a copy of Etherpad Lite with the REST API built... with the REST API plugin for it. [06:00.930 --> 06:04.470] There's also a search engine which lets you search the archive for desired content later. [06:04.630 --> 06:07.690] Because it's kind of worthless if you can't find all the stuff you have. [06:08.890 --> 06:14.270] And there's an inventing system which alerts the user when archival is complete or when a problem arises. [06:15.070 --> 06:29.270] So whenever the... either the page is archived or there's an error, I get an email on my phone that either has the URL to my personal archive that goes right to that page or I get an error message that describes what happened. [06:29.430 --> 06:32.570] Couldn't access the page, 403, 404, what have you. [06:34.550 --> 06:34.990] Okay. [06:35.590 --> 06:39.050] Now, how can you build an exocortex if you have a need to build one? [06:39.310 --> 06:41.550] Well, first, you have to figure out what you want to accomplish. [06:42.210 --> 06:43.910] Do you want to just experiment with it? [06:43.970 --> 06:44.910] Do you want to build an archive? [06:45.230 --> 06:47.150] Do you want to experiment with machine learning? [06:47.150 --> 06:51.930] Do you want to build an automation system that plugs into different APIs? [06:53.170 --> 06:55.150] Now, you want to have some idea of what you want to accomplish. [06:55.670 --> 06:57.030] Then, stand up a server or two. [06:57.470 --> 07:04.830] Virtual machines work well, bare metal works well, or you can set up an account with a service like Heroku and then upload your code to it and interact with it that way. [07:05.850 --> 07:11.910] Install your software, build some agent networks, build some bots if you want that sit outside of it but interact with those agents. [07:12.230 --> 07:13.610] And I'll get into the distinction a little bit later. [07:14.390 --> 07:15.890] And then, set up your user interface. [07:15.890 --> 07:19.130] The UI can be minimal, which is set it and forget it. [07:19.490 --> 07:20.550] The agents run in the background. [07:20.790 --> 07:21.890] Occasionally, you'll get a message. [07:23.770 --> 07:31.770] There's medium...the user interface can be...can have...can use telephones for user interface. [07:32.150 --> 07:41.450] You can send SMS messages, have them picked up by an SMS provider, parse it for correctness, parse the commands out, have it obey the commands. [07:42.310 --> 07:51.630] You can use...you can send commands to the agent networks via email, or you can use some nifty app like an XMPP client or something like beeper.io. [07:51.910 --> 07:54.990] And then, you can pretty much enjoy not having to hit refresh all the time. [07:56.630 --> 08:00.770] The software I use to build my exo-cortex is based around... [08:02.750 --> 08:03.690] All right, thank you. [08:04.170 --> 08:08.070] Is based around a software framework by Andrew Cantino called Huginn. [08:10.230 --> 08:14.150] It's a framework for building networks of autonomous agents that carry out tasks. [08:14.150 --> 08:15.230] It's written in Ruby. [08:15.450 --> 08:16.930] It uses Rails for the front end. [08:17.330 --> 08:19.450] And it has an event-based architecture internally. [08:20.110 --> 08:23.990] There are dozens of classes of agents that are optimized for carrying out specific tasks. [08:25.690 --> 08:35.810] External but plugged into Huginn is a lot of my own code, which is called Halo, which is a collection of bots that carry out more complex tasks that Huginn's event-based architecture isn't well-suited for. [08:36.370 --> 08:41.930] The thing about the event-based architecture is it's very good for short turnaround time tasks. [08:42.210 --> 08:43.170] An event comes in. [08:43.250 --> 08:43.890] It's processed. [08:44.050 --> 08:45.110] It gets sent to another agent. [08:45.490 --> 08:46.690] That agent processes it. [08:46.770 --> 08:47.770] It gets sent to another agent. [08:47.890 --> 08:48.690] It gets processed. [08:48.830 --> 08:49.550] The output happens. [08:50.210 --> 08:53.090] The turnaround time for that is usually in order of a couple of seconds. [08:55.250 --> 09:08.870] Unfortunately, the Huginn framework isn't well-suited for things like taking a rather large volume of text, running it through a text-to-speech synthesizer, then placing a voice-over IP call, playing the synthesized speech over the call, and then tearing everything down. [09:10.450 --> 09:19.090] But a bot that takes its cues from Huginn and is running external to the event scheduler is much more suited for that. [09:21.010 --> 09:29.510] So some of the bots that I built in that comprise Halo, the speech synthesis, voice-over-IP client, integration with other external applications. [09:29.510 --> 09:31.670] I wrote interfaces for Etherpad Lite. [09:31.670 --> 09:36.470] I wrote interfaces for GPS receivers and mapping software. [09:36.790 --> 09:40.290] I also wrote a fair amount of software that interfaces with search engines. [09:41.930 --> 09:43.870] There are different ways to interact with Huginn. [09:44.230 --> 09:48.610] Of all the agents, there are basically three classes of agent. [09:48.750 --> 09:50.050] Input, processing, and output. [09:50.450 --> 09:54.530] To interact with Huginn, there are a fair amount of input agents. [09:54.530 --> 09:58.710] There's a webhook agent, which basically you give it the URL of a webhook. [09:58.810 --> 09:59.750] You give it an API key. [10:00.030 --> 10:03.230] It pulls events out, packages those events, and sends them on. [10:04.250 --> 10:09.150] It can read from and write to MQTT message queues that it's subscribed to. [10:10.310 --> 10:16.030] There's a website agent, which lets you interact with other websites and APIs. [10:16.390 --> 10:27.670] And there are also many different agents for specific services, like Trello, Weather Underground, a couple of flight booking services, things like that. [10:27.670 --> 10:34.030] And there is also an agent, which is disabled by default, which lets you run shell commands local to the box Huginn is running on. [10:34.310 --> 10:35.990] So it will spawn a shell. [10:36.130 --> 10:45.530] It'll run a script or a command or something, capture standard out and standard error, package those as an event, and put them into the internal event queue. [10:45.810 --> 10:47.650] The output agents are pretty straightforward. [10:48.030 --> 10:49.790] There's the MQTT agent, of course. [10:50.450 --> 10:55.470] There are a couple of agent classes, which interact with other websites and APIs. [10:55.470 --> 11:02.530] There's also a post agent, which lets you make arbitrary HTTP requests of arbitrary sites. [11:03.110 --> 11:05.950] So get, put, delete, head, stuff like that. [11:06.230 --> 11:13.810] And there is a data output agent, which sets up a custom RSS feed or a custom REST API, which emits JSON. [11:15.770 --> 11:20.730] This is probably one of the simplest agent networks that you can build in an exocortex. [11:21.410 --> 11:26.350] Here's an RSS agent, which expects its RSS feed to change every five days. [11:27.270 --> 11:35.630] The clean flag basically tells the XML parser inside of the agent, assume that this is good, this is well-formed and well-formatted XML. [11:36.050 --> 11:41.930] If you start getting errors, you toggle that to true, and it'll do its best to clean up the XML and then pull events out of it. [11:41.930 --> 11:47.610] And then here's the URL of the RSS feed to pull on some schedule. [11:47.950 --> 11:50.510] So 2600.com stroke rss.xml. [11:51.050 --> 11:57.550] For every entry in the XML document that has changed, it's packaged and made it as an event. [11:57.810 --> 12:04.970] And each of those events is sent to an email agent, which, as the name implies, constructs SMTP messages. [12:05.670 --> 12:10.810] So the subject line will consist of the title of the article from that entry in the RSS feed. [12:11.050 --> 12:32.170] The headline, which is the first line of the email, it consists of the line published on, date published, the body of the email, the description field of the post on the website, two line breaks, and then the contents of the content field in the RSS event. [12:32.590 --> 12:37.710] And the expected perceived period in days, it'll expect to receive an event at least once every 365 days. [12:37.910 --> 12:41.290] And if it doesn't, it will shut itself down and assume it's in an error state. [12:41.870 --> 12:45.130] And every time an email agent fires, the article is emailed automatically. [12:45.350 --> 12:51.430] By default, it goes to an email address that's configured in the hoogans.env file. [12:51.590 --> 12:53.150] It's the system configuration file. [12:53.150 --> 12:57.950] But you can also give it an arbitrary list of email addresses to send events to. [12:59.590 --> 13:01.430] Now, here's a more complex agent design. [13:01.670 --> 13:05.810] I can show you the source code for it, but it would span probably 20 slides, because it's pretty involved. [13:06.330 --> 13:08.690] But at a high level, here's what it consists of. [13:09.110 --> 13:14.730] There's an RSS agent, which pulls the RSS feed for the DNA Lounge archive on archive.org. [13:16.410 --> 13:24.170] The DNA Lounge in San Francisco makes available for a certain period of time, downloadable MP3s of all the concerts and club nights they hold. [13:24.890 --> 13:30.230] And there's a small collective in San Francisco that downloads those MP3s and uploads them to the Internet Archive. [13:30.490 --> 13:33.370] And that collection has its own RSS feed. [13:34.270 --> 13:39.450] So I have an RSS agent that pulls that RSS feed every 24 hours. [13:39.590 --> 13:47.210] And then it sends the events from that RSS feed to a couple of trigger agents, which look for specific keywords in the title field. [13:47.650 --> 13:55.890] So I look for Information Society concerts, Crew Shadows concerts, Onomatoguchi concerts, and Turbo Drive, which is a club night I think they don't have often enough. [13:56.070 --> 13:57.090] But it's not about that. [13:58.590 --> 14:14.090] There are a couple of RSS agents, which also pull the Internet Archive's HackerCon collection, the Infocom Cabinet Collection, which is their archive of curiosa and ephemera from the game company Infocom, and the Internet Archive's National Security Archive, [14:14.090 --> 14:14.990] which I highly recommend. [14:16.230 --> 14:24.470] The events from those three RSS agents get sent through a number of trigger agents, of which I've listed just a few here, which look for another specific set of keywords. [14:24.930 --> 14:27.110] For example, COINTELPRO, Hack and Freak. [14:27.810 --> 14:40.070] All of these events then get sent through a deduplication agent, which has a memory of a fixed size of events, and every time an event reaches it, it goes back through its memory to see if it's ever seen it before. [14:40.790 --> 14:46.150] I deduplicate based upon the human readable message written by the trigger agents. [14:46.370 --> 14:59.450] I can just as easily deduplicate based on the globally unique ID in the ID field of the RSS event, but it's easier to deduplicate on the human readable message. [14:59.810 --> 15:03.750] And everything that makes it through the deduplication phase gets emailed. [15:03.950 --> 15:08.910] So I get a direct link to download whatever just hit one of those archives. [15:11.710 --> 15:13.550] This is what one of the events looks like. [15:13.750 --> 15:15.490] It's a pretty standard JSON document. [15:15.910 --> 15:20.130] And this is from an RSS... this is from an RSS agent. [15:20.410 --> 15:22.650] So I've had to cut it down by about 30 lines. [15:22.930 --> 15:25.070] But I think you get the gist of what it looks like. [15:25.570 --> 15:27.070] Date published, last updated. [15:27.330 --> 15:30.350] Those are two... those are timestamps in two different formats. [15:30.710 --> 15:32.830] So depending on what you want to do with them, you'll pick one or the other. [15:32.830 --> 15:36.190] The specific URL of the article. [15:36.630 --> 15:42.150] The description of the article, which is basically the bit above the fold in the content management system. [15:42.470 --> 15:47.790] Content is the complete... the entire article from the content management system. [15:48.410 --> 15:49.230] The title of the article. [15:49.870 --> 15:56.350] Authors is a JSON array of strings where each string is the byline of one of the authors. [15:56.350 --> 16:02.990] And categories is a JSON array of strings where each string is one of the categories the CMS uses to manage articles. [16:05.830 --> 16:06.790] Okay, so... [16:06.790 --> 16:10.850] Now you're probably wondering why I built Nexo Cortex to do all this crazy stuff. [16:11.230 --> 16:14.210] Well, it didn't start out as a unified project or even a personal tool. [16:14.210 --> 16:18.670] It was my... it was my... I want to learn about Foo project when I started college. [16:18.870 --> 16:24.050] Where Foo was C or Perl or Python or how do I make HTTP requests? [16:24.350 --> 16:25.390] How do I parse HTML? [16:25.930 --> 16:29.650] How do I do... how do I programmatically recognize and sort text? [16:29.810 --> 16:30.290] Stuff like that. [16:30.850 --> 16:34.190] It was also a manifestation of my, hey, I'm not on dial-up syndrome. [16:34.410 --> 16:37.150] Because I discovered the joys of Ethernet in the comp sci dorm. [16:37.950 --> 16:41.710] This meant that I had constant access to the net and all the information sources on it. [16:41.710 --> 16:44.970] Which also meant that I didn't have enough time to keep up with everything. [16:45.570 --> 16:47.430] I became something of an information junkie. [16:47.590 --> 16:51.950] So I started writing bots that would pull all the stuff that I kept reading in between classes. [16:52.450 --> 16:55.270] And it would filter it based upon what I was interested in. [16:55.430 --> 16:59.050] And I would get an email every couple of hours with a digest of what popped up. [17:00.510 --> 17:04.390] And keep... keep in mind that RSS wasn't invented until 1999. [17:04.790 --> 17:07.430] And the Atom spec didn't make it big until about two years later. [17:08.250 --> 17:11.130] So years went by and I kept rewriting my code. [17:11.130 --> 17:13.890] And I kept having to modify it because the net changes. [17:14.270 --> 17:19.110] And it eventually mutated into this unmaintainable, you know, shoggoth of hacks. [17:19.510 --> 17:24.230] And eventually, to stand up one new bot, I was having to do substantial rewrites to an entire bot. [17:25.830 --> 17:31.490] So I started writing my own framework to reimplement all of these agents and make them easier to maintain. [17:31.730 --> 17:34.290] And I got a proof of concept going and I showed it to some of my coworkers. [17:34.290 --> 17:38.950] And my coworkers said, hey, there's this thing called Huginn written by Andrew Cantino. [17:39.030 --> 17:40.030] Why don't you take a look at it? [17:40.370 --> 17:46.830] So I took a look at it and realized in about 60 seconds that it did way more than my weekends of hacking did. [17:46.830 --> 17:51.470] So I scrapped my own code base and ported all of my stuff over to Huginn in an afternoon. [17:51.470 --> 17:56.030] And I started building on top of Huginn and I've been using it ever since. [17:57.850 --> 18:03.590] I see no reason to reinvent the wheel if somebody has already written a wheel that is way better than anything I can do. [18:04.370 --> 18:06.830] What I can do, however, is I can build on top of it. [18:06.910 --> 18:07.650] I can extend it. [18:07.750 --> 18:08.990] I can try to add new stuff to it. [18:09.010 --> 18:10.110] I can try to make it more useful. [18:11.670 --> 18:16.830] I started writing bots that were external to Huginn because I also ran into some of Huginn's functional limits. [18:19.750 --> 18:21.610] So what do I do with my exocortex? [18:22.690 --> 18:27.790] I tend to name my agent networks and bots so I can keep them straight in my head. [18:28.030 --> 18:35.750] I try to make them, if not thematically relevant, then at least, you know, somewhat catchy. [18:35.750 --> 18:48.590] So, for example, Antigone, whenever I send Antigone a URL, it submits that URL to a bunch of independent search engines that rely, at least in part, on user interactions. [18:49.070 --> 19:04.330] It also submits that URL to my copy of Yassi, which is a personal open source search engine written in Java, which uses a distributed hash table to form a global network of independent search engines. [19:04.330 --> 19:15.410] So, basically, you can make queries of it, and I have my own copy that I submit URLs to, so I have a personal search engine, and I submit a copy to the global search engine network because I'm trying to help it build. [19:17.310 --> 19:19.210] Jackhammer implements my personal web archive. [19:19.990 --> 19:29.450] Argus and Montauk are interfaces to my personal search engines because I have a couple of servers that are full of files and stuff, and I try to keep them indexed. [19:30.430 --> 19:36.110] Butterfly in China is an agent network that compiles daily weather and air quality index reports. [19:36.750 --> 19:42.630] Cherry Bomb monitors police, fire, and EMS radio dispatch networks for statistically unusual spikes in listenership. [19:43.510 --> 19:51.610] Edison follows and analyzes feeds of several dozen news agencies, the World Health Organization, a bunch of defense-related news magazines, and online archives. [19:52.230 --> 20:00.150] Firefly monitors currency and cryptocurrency networks, markets accounts and addresses for statistically unusual activity. [20:00.870 --> 20:08.570] Glitch monitors manufacturer websites, Linux distros, exploit archives, stuff like that, looking for new vulnerabilities. [20:08.570 --> 20:17.350] I use that to keep my own stuff updated, and I use Glitch heavily at work to keep situational awareness for what we have to do next. [20:18.170 --> 20:29.770] Iron Monger follows the stock prices of the 20 largest defense contractors, petroleum markets, investment funds, and multinational corporations around the world as a sort of indicator of geopolitical change. [20:30.970 --> 20:43.410] Pathfinder is plugged into the public APIs of several public transit services, calculates best routes, and alerts on delays in police activities, because BART shuts down or gets snarled up at the weirdest times, and I like to know why. [20:45.250 --> 20:48.250] And Switchboard carries out secretarial duties for me. [20:48.450 --> 20:59.390] She monitors my email addresses, watches for new files on different services like Box.com, Dropbox, stuff on Pastebin, things like that. [21:00.730 --> 21:04.190] Switchboard automatically posts to my blog and syndicates my blog posts. [21:05.730 --> 21:14.770] Switchboard has a couple of agent networks that inform certain people of certain new developments, like things going on, commits to GitHub, things like that. [21:15.590 --> 21:23.470] Because Google took away SMS messaging for calendar, I have my own calendaring service now, and I get SMS messages as reminders. [21:24.530 --> 21:35.170] And also, Switchboard has agent networks which monitor the credits that I have available to me in certain paid subscription accounts, like Shodan and my voice over IP provider. [21:35.430 --> 21:40.490] So, if I start getting low, I get an email, and then I have to throw some money at them and crank my account balance up. [21:42.430 --> 21:43.090] Demo time. [21:43.430 --> 21:44.770] Please, man with gods, be with me. [21:46.670 --> 21:47.110] Okay. [21:47.290 --> 21:50.470] So, this is Butterfly in China. [21:50.470 --> 21:57.870] I'm using Huginn's graphical flow charting application to show how the agents relate. [21:59.450 --> 22:03.110] In a nutshell, I'm going to show the agent network for New York City. [22:05.770 --> 22:10.690] This is a website agent that pulls the air quality index forecast for New York City. [22:10.910 --> 22:12.590] I'm going to show what that looks like real quick. [22:15.860 --> 22:18.040] This is the schedule every morning at 4 a.m. [22:18.220 --> 22:18.560] Eastern Time. [22:20.120 --> 22:24.220] This is the list of agents that will receive events that are generated by this agent. [22:24.540 --> 22:26.600] And this is basically the source code to the agent. [22:27.780 --> 22:30.940] This particular agent expects an update to show up every seven days. [22:30.940 --> 22:39.960] This is the URL that it pulls data from, airnowapi.org, which basically provides an API of air quality indexes. [22:40.800 --> 22:54.440] Here's the forecast, the zip code, asks for JSON, asks for the forecast for the area code 1-0-0-0-1, and a distance of 25 kilometers. [22:55.000 --> 22:59.980] And there is a liquid templating tag here for my API key. [23:01.080 --> 23:03.140] You email them, they'll give you an API key. [23:03.340 --> 23:04.600] They just ask you not to abuse the service. [23:05.360 --> 23:07.140] A surprising number of places are like that. [23:07.220 --> 23:10.000] If you email them and ask very nicely for an API key, they'll just give it to you. [23:10.440 --> 23:14.880] They might ask you to make fewer than 1,000 or 10,000 requests an hour, but that's not difficult. [23:18.360 --> 23:21.060] This agent's going to expect JSON to come back. [23:21.720 --> 23:27.640] And for every JSON document it gets, it's going to expect that the JSON document will have changed. [23:28.520 --> 23:31.900] If it hasn't changed, it'll just throw the event away and go to sleep. [23:32.020 --> 23:46.600] But if it has changed, it will parse the JSON document, and it will use JSON paths to pick out two of the entries, which is the AQI, which is a numerical value, and what that numerical value corresponds to as an English word. [23:46.800 --> 23:51.340] And it will pack them into the variables AQI and summary, respectively. [23:54.550 --> 24:00.450] And it will emit... it will pass copies of that event on to four other agents, which are trigger agents. [24:00.590 --> 24:03.910] And basically, they parse the event looking for something very specific. [24:04.750 --> 24:06.930] And I'll show what one of those looks like. [24:11.180 --> 24:14.120] Whenever a trigger agent receives an event, it runs, you don't schedule them. [24:14.820 --> 24:18.140] And basically, it expects to receive an event every seven days. [24:18.480 --> 24:22.580] It will not keep the event, so after it's parsed it and made a determination, it will throw it away. [24:22.800 --> 24:24.460] That helps save room in the database. [24:25.180 --> 24:27.660] And the rules that it matches against are... [24:27.660 --> 24:31.000] It looks at the value of the variable AQI in the event. [24:31.200 --> 24:36.860] And if it is greater than 101, and if it is less than or equal to 150, it will form the message. [24:37.300 --> 24:40.380] Today's air quality forecast is value of the variable summary. [24:42.000 --> 24:44.800] Actual AQI value is the value of AQI. [24:45.060 --> 24:46.700] The AQI is unhealthy today. [24:46.860 --> 24:47.560] Be extremely careful. [24:47.720 --> 24:48.640] Have your inhaler on you. [24:50.640 --> 24:59.960] This goes into an event formatting agent, which basically takes events and makes another event by putting together bits and pieces of other events. [25:03.100 --> 25:04.620] And this one's really simple. [25:04.800 --> 25:13.720] Take the value of message from whatever event it receives, copy the value into another value called message, and throw it down the chain. [25:15.320 --> 25:19.440] And there is another agent sitting over here, which only gets weather forecasts. [25:19.920 --> 25:22.160] This pulls... okay, this is weather agent. [25:22.500 --> 25:26.660] I have an API key for weatherunderground.com. [25:26.660 --> 25:39.740] And all it does is it contacts weatherunderground.com, gets a weather forecast for the zip code 10001, expects it to change once every two days, and then it emits that event. [25:41.440 --> 25:44.120] And that event goes to another event formatting agent. [25:46.200 --> 25:52.500] Today's weather forecast for location is conditions with a high of high degrees Fahrenheit, and a low of low degrees Fahrenheit. [25:52.500 --> 25:54.640] The average humidity is average humidity percent. [25:55.460 --> 26:00.120] And it... all of that goes into an email digest agent, which runs on a certain schedule. [26:01.820 --> 26:06.380] Today's New York City weather report headline, here's your New York City, New York weather report for today. [26:06.860 --> 26:09.540] Here are two email addresses that receive it. [26:10.220 --> 26:14.160] And that's pretty much... and this is repeated several times. [26:15.360 --> 26:17.260] The next agent network is Cherry Bomb. [26:18.320 --> 26:21.220] Cherry Bomb is the event... or Cherry Bomb is the event... [26:21.220 --> 26:24.940] is the agent network which monitors police scanners. [26:25.200 --> 26:27.400] I'm just going to show very briefly how that works. [26:27.520 --> 26:28.840] I'm not going to go into too much detail. [26:30.060 --> 26:37.940] If you... if you go to broadcastify.com, you will find police scanners plugged into the... plugged into the net all over the world. [26:37.940 --> 26:43.360] And for each page, there's a little counter that says how many people are listening to it at any one time. [26:43.940 --> 26:48.180] And that little counter on the web page is a CSS entity called .c. [26:48.540 --> 26:59.580] So this agent pulls down the HTML, parses... or fuzzes out the CSS entity .c, grabs the text of it, and then emits it in an event. [26:59.580 --> 27:06.840] And then that numerical value goes through a peak detector. [27:07.120 --> 27:12.180] And what the peak detector does is the peak detector has a 14-day memory. [27:12.900 --> 27:15.720] That value is updated once every 30 minutes. [27:15.720 --> 27:24.380] And if that value changes by two standard deviations on a five-minute time scale, it sends a message and then I get an email on my... [27:24.380 --> 27:27.900] I get a link actually sent to my phone through beeper.io. [27:27.900 --> 27:33.580] I can tap on the link, I go right to radioreference.com, and I'm listening in on the police. [27:34.960 --> 27:36.820] I do it for the BART Police Dispatch. [27:36.820 --> 27:38.680] I do it for the Oakland Police Dispatch. [27:38.840 --> 27:43.620] I do it for San Francisco Bay Area EMS and the Alameda California Fire Dispatch. [27:45.780 --> 27:47.880] Edison is my news bot. [27:48.300 --> 27:50.100] I guess I should say news agent network. [27:50.540 --> 28:10.600] Edison follows the Associated Press Twitter feed and a very large number of news sources from the United States, where I live, outside of the United States, Voice of America, Voice of Europe, Asahi Shambun, the World Health Organization, a bunch of defense-related journals like NextGov and Defense News, [28:11.180 --> 28:12.400] National Interest. [28:12.800 --> 28:16.380] Here is the example agent I pulled out for the DNA Lounge. [28:21.900 --> 28:29.520] The Blacklisted 411 Collection, Archive.org's Mapping the Internet Dataset, which is kind of fun to poke around in sometimes. [28:30.540 --> 28:32.560] The Archive.org's HackerCons Collection. [28:32.860 --> 28:36.860] They have an extensive collection of media from pretty much every HackerCon that's ever been held. [28:37.020 --> 28:37.840] I highly recommend it. [28:39.160 --> 28:42.120] Defense One is another defense-related magazine and Electrospace. [28:43.240 --> 28:46.780] And the last agent network I would like to show off is Iron Monger. [28:47.920 --> 28:53.300] Iron Monger pulls stock taker information for defense contractors. [28:54.080 --> 28:57.260] Here's the OPEC crude oil reference basket price. [28:59.820 --> 29:01.020] RDSA, HOKCY. [29:01.280 --> 29:12.200] And for each of these, there is a peak detector, which watches for rapid stock price changes on the order of two and a half standard deviations in five minutes, as well as trade volume changes. [29:12.420 --> 29:15.140] I get two standard deviations in five minutes. [29:15.680 --> 29:25.220] That usually means that somebody has either made a very large buy, a very large sell, or somebody has closed a very large contract, which usually means that something is going to go very wrong somewhere in the world. [29:30.140 --> 29:31.860] Okay, so what do I get out of this? [29:32.240 --> 29:35.220] Because I'm a self-admitted information junkie, but I admit it. [29:35.740 --> 29:37.180] I spend a lot of time at... [29:37.180 --> 29:45.340] I spend a lot less time at work reading security briefs and websites and Twitter feeds to keep on top of new vulnerabilities and attacks and data breaches. [29:45.840 --> 29:49.060] I get more work done by applying that information than I do hunting it down. [29:49.960 --> 29:58.020] While I'm doing research for stuff, I farm the tasks of executing searches against multiple search engines out to bots so I can spend more time digesting the information and writing. [29:59.240 --> 30:09.480] I send one of my bots a text message or an XMPP message to the effect of Montauk get me the top 40 hits or top 40 hits for... [30:09.480 --> 30:11.880] I don't know... [30:11.880 --> 30:14.180] early 20th century chandeliers. [30:14.940 --> 30:26.920] And then five or ten minutes later, I'll get an email back with 40 search results ranked by relevancy, also ranked with a... [30:26.920 --> 30:28.300] What's the word for it? [30:30.960 --> 30:32.240] There's a couple of other... [30:32.920 --> 30:36.780] I also run the results through a couple of natural language processing modules. [30:37.180 --> 30:38.260] So, sentiment detection. [30:38.440 --> 30:39.500] Sentiment detection analysis. [30:39.900 --> 30:45.920] So, in addition to what the search engine thinks the relevancy is, the sentiment detection modules also make... [30:46.560 --> 30:48.300] also help determine how relevant it is. [30:48.520 --> 30:51.320] And then I'm writing, okay, that looks interesting. [30:51.480 --> 30:51.660] Click. [30:51.820 --> 30:53.320] Open it up in a new tab in a new window. [30:53.980 --> 30:54.980] Go back to writing. [30:55.200 --> 30:56.740] I don't have to spend the time grinding up the... [30:56.740 --> 30:58.780] you know, searching for the data myself. [30:59.020 --> 31:00.300] Some of the grinding up is done for me. [31:02.080 --> 31:06.380] I find out about new and interesting stuff without having to spend hours a day browsing dozens of sites. [31:06.680 --> 31:15.120] I get email digests with links that I scan whenever I have a free moment and I filter out stuff that's not interesting whenever I go back and tinker with code because I tinker with code. [31:15.720 --> 31:18.320] I also have a framework for experimenting with stuff in a new way. [31:19.340 --> 31:25.360] Because it's really easy to get information into and out of Huginn in the form of RSS feeds and custom REST APIs. [31:25.800 --> 31:29.100] I've been wanting to experiment with neural networks and machine learning systems. [31:29.360 --> 31:31.720] So I've got kind of a crazy idea. [31:34.080 --> 31:35.280] Turn the screen back on. [31:36.020 --> 31:36.500] Come on. [31:36.840 --> 31:37.200] There we go. [31:37.720 --> 31:49.100] I got the idea from reading an article written by the guy who wrote a machine learning system that would analyze posts on Hacker News to determine what might or might not be interesting to him. [31:49.100 --> 31:52.120] And it caused some amount of controversy on Hacker News. [31:52.260 --> 31:53.140] So I think I like to try out myself. [31:54.820 --> 32:02.640] It also means that even though I'm an info junkie, I get to spend more time with my family, I get to spend more time hacking, and I get to spend more time enjoying myself. [32:04.940 --> 32:07.520] So now what can you get out of it? [32:08.200 --> 32:11.700] This was a trickier question to answer when I was writing these slides. [32:11.840 --> 32:12.960] So I thought about it a lot. [32:13.520 --> 32:18.460] Of course there's news and social network monitoring for whatever interests you and use cases that you happen to have. [32:18.620 --> 32:24.000] Like keeping an eye out for data breaches, the next massive death or terrorist strike. [32:24.420 --> 32:28.900] I'm really sorry I had to go there, but I think we're all worried about our friends and family. [32:29.600 --> 32:31.420] Also, everyone's favorite, leaked zero days. [32:34.240 --> 32:39.020] And ExoCortex is good for connecting devices and software so they can interact with each other. [32:42.060 --> 32:47.220] Hopefully when I get home I'll start playing around with the Mycroft speech recognition system. [32:47.860 --> 32:49.700] It's an open source speech recognition package. [32:50.300 --> 32:55.460] I plan on plugging it into my Moppity jukebox as well as my Kodai media box in the living room. [32:56.160 --> 33:05.380] So I can basically say something to the effect of jukebox, random default playlist, shuffle, and I've got music to hack by. [33:06.080 --> 33:11.000] I've also been toying with the idea of interfacing an RTL-based SDR. [33:11.520 --> 33:19.280] I have a couple of the RTL-828 radio scanners which use the software package GQRX, which is built on top of GNU radio. [33:20.000 --> 33:21.680] It doesn't have a REST API yet. [33:21.680 --> 33:22.560] I'm going to write one. [33:22.740 --> 33:24.940] But it does have a very good network API. [33:25.300 --> 33:33.260] So I also have the sort of crazy idea of saying, Mycroft, scan from 100 megahertz to 550 megahertz. [33:33.260 --> 33:42.220] And the Raspberry Pi that I have with the RTL-828 on it will just start scanning on a predefined interval and stop whenever it finds something interesting. [33:43.180 --> 33:50.900] There's also something I plan on doing at work, which is connecting our Radius server to a copy of Metasploit using the RPC API. [33:51.240 --> 33:53.560] So basically, a new box joins the network. [33:53.560 --> 33:56.000] The user logs into the Radius server. [33:56.240 --> 33:58.760] The Radius server runs a script that... [33:58.760 --> 34:05.000] The Radius server runs a script that pings my ExoCortex to say, hey, there's a new box on the wireless network. [34:05.640 --> 34:09.900] ExoCortex picks it up and hits Metasploit's RPC API. [34:10.560 --> 34:12.180] Metasploit throws Autopone at it. [34:12.260 --> 34:16.200] And then the results of Autopone get emailed to TechOps. [34:16.380 --> 34:18.220] TechOps intervenes if it's too bad. [34:25.320 --> 34:29.700] Also, I use ExoCortex to interact with cryptocurrency networks. [34:30.120 --> 34:38.860] It's very easy for someone to plug a copy of Huginn into pretty much any Bitcoin, Litecoin, or any other coin gateway. [34:41.540 --> 34:44.200] Do puts and gets on the order book. [34:45.160 --> 34:49.800] I don't know if any of them support moving money out of the gateway to bank. [34:50.540 --> 34:53.100] I wouldn't be surprised if that gets added very soon. [34:53.700 --> 34:56.940] If you're into currency trading, it is something you can totally do. [34:58.700 --> 35:06.520] My lawyer is probably going to yell at me after this, so I'm also going to say that I accept no responsibility for what may or may not happen. [35:08.480 --> 35:10.380] You flip currency at your own risk. [35:13.240 --> 35:14.760] I'm so going to get yelled at for that. [35:18.340 --> 35:22.640] ExoCortexes are also good for responding to sudden changes in your online social activity. [35:23.660 --> 35:38.440] If you suddenly stop posting for some reason, or if you post certain things at certain times, or just post certain things at all, you can set up ExoCortex to respond in pretty much whatever way you want. [35:39.260 --> 35:41.000] It could be a discrest call. [35:41.180 --> 35:42.740] It could be texting your lawyer. [35:43.040 --> 35:46.600] It could be for all the people on this list. [35:47.300 --> 35:50.960] Text them a copy of the National Lawyers Guild, phone number, stuff like that. [35:54.120 --> 35:59.820] ExoCortexes are also very good at interacting with third-party APIs and making them do things they're not really supposed to do. [36:01.500 --> 36:10.980] Everybody's played with Google Maps mashups, stuff like the Fukushima map, I think it was the Thor Network's DDoS map before that went offline. [36:11.400 --> 36:37.240] But think about doing not a map mashup, but a mashup with Halo's speech synthesizer, the Trello agent to send text messages, the voice over IP bot to create and place phone calls via voice over IP, an RTL828 radio scanner, which is constantly scanning police bands, [36:37.840 --> 36:42.940] as well as some code to detect whenever listenership spikes. [36:43.280 --> 36:57.920] So whenever listenership spikes, the radio scanner tunes to that frequency, records three minutes, throws it over to the voice over IP box, it just starts calling people and playing it back because they're in that general location and they need to know what's going on. [37:00.840 --> 37:02.820] And I think I've... [37:02.820 --> 37:04.700] Well, are there any comments or questions? [37:10.540 --> 37:19.420] When you were talking about how you can get it to go through search engines for you to do research more easily, that seemed really interesting to me. [37:19.600 --> 37:25.800] How do you get it to collate the results from multiple search engines into one top 40 list? [37:26.140 --> 37:26.620] Okay. [37:26.940 --> 37:29.000] So what I used to do was I... [37:29.820 --> 37:40.220] An early version of the search engine bot had a configuration file which specified what search engines were in it, as well as the... as well as what... [37:40.800 --> 37:41.040] Okay. [37:41.400 --> 37:50.400] It would then download the HTML and it would pull out all of the URLs in the HTML and then sort them and then each of the... [37:50.400 --> 37:56.860] And for each search engine, the configuration file was what links to filter out because it was... [37:57.180 --> 38:00.480] because there would be links to, like, go back to the homepage or stuff like that. [38:02.500 --> 38:05.860] And then I stopped doing that because it got way too difficult to maintain. [38:05.860 --> 38:06.560] So... [38:06.560 --> 38:08.760] I stood up a copy of Searx. [38:09.220 --> 38:10.660] It's by Eskimoo. [38:10.740 --> 38:12.400] It's spelled S-E-A-R-X. [38:12.700 --> 38:17.300] It's an open source front end to search engines and it also has a really good JSON API. [38:19.080 --> 38:19.680] So... [38:19.680 --> 38:24.080] Basically, that search request gets routed to the Searx search API. [38:24.700 --> 38:25.300] Searx... [38:25.300 --> 38:32.460] Or Searx simultaneously searches all of the search engines it's configured for and I have it configured for 40 different search engines. [38:33.000 --> 38:38.880] Pulls all the results down, does the first level collation based upon what it considers relevance. [38:39.120 --> 38:52.340] And then I have some additional glue code that pulls down the HTML pages, renders them as text, and then runs it through the NLP package to do the sentiment analysis and then sort of refiddles the... [38:52.880 --> 38:55.980] sort of refiddles the accuracy and then sends it as an email. [38:59.740 --> 39:03.780] Hi, so your system plugs into a lot of different APIs, a lot of different external things. [39:03.780 --> 39:06.240] How are you handling errors in those systems? [39:07.620 --> 39:09.320] So, the errors that... [39:09.320 --> 39:13.860] So, for the agents that are built into Huginn, it has its own really good error handling. [39:15.000 --> 39:16.580] It's usually stuff like... [39:16.580 --> 39:17.740] I'll give you an example. [39:18.020 --> 39:21.260] For the Twitter agent, it'll send back, hey, you got error 420. [39:21.660 --> 39:22.840] If you've ever used... [39:22.840 --> 39:24.140] If you've ever got... [39:24.140 --> 39:31.000] If you've ever used Twitter's API, if you go over your rate allotment, they will hit you with an error 420, enhance your calm. [39:31.680 --> 39:33.760] Which basically means you have to wait for an hour. [39:36.260 --> 39:38.840] Do you have an example of a really good use case? [39:39.240 --> 39:39.700] Like this... [39:39.700 --> 39:42.140] Like substantially helped you in something? [39:43.360 --> 39:43.920] Or... [39:43.920 --> 39:44.680] My... [39:44.680 --> 39:49.980] The two substantial use cases that I've had for this were the search engine bot. [39:50.100 --> 39:56.460] Because I find that I do more and more writing praises and analyses at work, which means I have to do research. [39:57.680 --> 39:58.040] Um... [39:58.610 --> 39:58.980] Also... [39:59.740 --> 40:01.300] The agent network switchboard. [40:02.220 --> 40:02.580] Because... [40:02.580 --> 40:06.180] I wrote switchboard to specifically manage parts of my life I don't have time to anymore. [40:07.360 --> 40:07.720] So... [40:07.720 --> 40:15.900] Even though I've got a bunch of email addresses for work, you know, personal stuff, all that, I don't have time to go through it, even though I've pared it down as far as I can. [40:16.040 --> 40:18.960] So I look for the really important stuff, the really important people. [40:18.960 --> 40:24.720] And I get a message on my phone saying, hey, this person contacted you. [40:24.900 --> 40:30.980] And I know that if I'm getting a notification that says, hey, this person contacted you, this is really high priority, I have to get to it. [40:31.300 --> 40:33.900] Because otherwise, I will just not respond. [40:33.900 --> 40:38.200] I'll forget to, and it goes to the bottom of the stack, and then I find myself apologizing a lot later. [40:39.520 --> 40:39.960] Um... [40:39.960 --> 40:40.680] Lifestyle management. [40:45.310 --> 40:50.370] Are there any hooks for to-dos or project management? [40:51.370 --> 40:51.890] Um... [40:51.890 --> 40:52.270] In... [40:52.270 --> 40:53.450] Inside of your exocortex. [40:55.450 --> 40:55.960] Um... [40:55.960 --> 40:59.080] My to-dos are generally part of my calendar. [41:00.330 --> 41:00.850] And... [41:01.520 --> 41:11.460] The way that I manage that is, I just put events in my calendar, and switchboard hits the ICS feed, and then whenever it starts coming up, I start getting text messages on it. [41:12.430 --> 41:12.750] Uh... [41:12.750 --> 41:13.950] Project management, no. [41:15.330 --> 41:15.850] Um... [41:15.850 --> 41:16.950] I've been considering it. [41:17.020 --> 41:18.560] I don't do a whole lot of project management. [41:18.560 --> 41:19.930] I don't actually know how to do it. [41:20.850 --> 41:21.290] So... [41:21.290 --> 41:22.370] Well, I don't. [41:22.460 --> 41:23.450] So I don't know... [41:23.450 --> 41:25.450] I don't know at this time what would go into it. [41:25.930 --> 41:26.370] Um... [41:26.370 --> 41:32.960] I can carefully speculate and say that if a project management package had an API of some kind, uh... [41:32.960 --> 41:36.040] Specifically a web-based API, REST would be great, but it doesn't have to be. [41:37.120 --> 41:37.560] Um... [41:37.560 --> 41:47.160] It would be fairly easy to write an agent network that would pull the API to pull events out of it, process it, and then, um... [41:47.160 --> 41:51.270] make requests back to the API to update the events that it pulled out originally. [41:52.140 --> 41:52.700] Uh... [41:52.700 --> 41:53.950] The specifics of it would be... [41:53.950 --> 41:54.330] It... [41:54.330 --> 41:57.080] It would be application-specific, but it would definitely be possible. [41:58.930 --> 41:59.480] Hi. [41:59.950 --> 42:00.120] Uh... [42:00.120 --> 42:00.600] Thanks for the talk. [42:01.160 --> 42:01.620] Um... [42:01.620 --> 42:02.140] So... [42:02.140 --> 42:04.830] Do you use any semantic web technologies? [42:05.040 --> 42:05.580] I know you... [42:05.580 --> 42:07.350] I've talked about RSS a lot. [42:07.540 --> 42:12.540] I know it is integrated with semantic web in some ways, but does it actually affect, uh... [42:12.540 --> 42:14.790] you know, your whole infrastructure at all? [42:15.830 --> 42:16.390] No. [42:17.060 --> 42:17.620] Um... [42:18.190 --> 42:18.750] I'm... [42:19.350 --> 42:19.910] I've... [42:19.910 --> 42:28.700] I keep running across stuff about the semantic web, but the information sources I use don't seem to use them at all. [42:29.200 --> 42:30.160] It's kind of odd. [42:30.660 --> 42:31.120] Um... [42:31.120 --> 42:31.660] RSS... [42:31.660 --> 42:36.850] As far as RSS is concerned, in the context of semantic web, um... [42:36.850 --> 42:37.750] it's a user interface. [42:38.390 --> 42:38.830] That... [42:38.830 --> 42:39.520] I don't see it as... [42:39.520 --> 42:41.370] I don't see it or treat it as really anything else. [42:43.220 --> 42:44.500] You mentioned, uh... [42:44.500 --> 42:46.080] your personal search engine. [42:46.350 --> 42:48.560] I wondered if you could expand a little more on some of the... [42:48.560 --> 42:50.460] the tools and techniques you're using for... [42:50.460 --> 42:51.330] the... [42:51.330 --> 42:52.080] indexing and... [42:52.080 --> 42:53.020] and searching your own files. [42:53.370 --> 42:53.810] Okay. [42:54.580 --> 42:55.020] So... [42:55.020 --> 42:55.770] Um... [42:55.770 --> 42:56.790] There is an open... [42:56.790 --> 42:59.330] There is an open source search engine called YACY. [42:59.410 --> 43:00.220] Y-A-C-Y. [43:00.220 --> 43:03.960] The homepage for it is Y-A-C-Y.D-E. [43:04.690 --> 43:07.660] And it is an open source distributed search engine. [43:08.350 --> 43:08.910] Um... [43:08.910 --> 43:09.770] Basically, it's... [43:09.770 --> 43:12.480] There is a distributed hash table which every... [43:13.120 --> 43:13.500] Excuse me. [43:13.620 --> 43:15.890] Which almost every YACY instance is connected to. [43:16.560 --> 43:17.120] And... [43:17.120 --> 43:30.200] Basically, every YACY instance in the DHT, uh... [43:30.200 --> 43:31.620] If something's been indexed by YACY. [43:31.950 --> 43:32.350] And... [43:32.350 --> 43:33.250] Whatever node you... [43:33.250 --> 43:33.680] That... [43:33.680 --> 43:34.720] They query... [43:34.720 --> 43:37.480] First checks its own index to see if it's been spidered. [43:37.680 --> 43:43.500] If it hasn't been spidered, it checks the DHT to figure out what node out there may have spidered it. [43:43.750 --> 43:50.640] And then, if it finds a match, it relays the search request to that particular node in the DHT. [43:50.640 --> 43:54.600] And if that particular node has indexed it, it sends... [43:54.600 --> 43:58.620] It sends the search request back to the node that the user contacted. [43:59.180 --> 44:00.250] And the user gets the search... [44:00.250 --> 44:01.640] Gets the... [44:02.180 --> 44:02.640] Uh... [44:02.640 --> 44:03.300] Search results that way. [44:04.200 --> 44:04.620] Um... [44:04.620 --> 44:04.860] You... [44:04.860 --> 44:09.750] Users also submit domains to the YACY network proactively to spider it. [44:10.020 --> 44:10.270] Or... [44:10.270 --> 44:13.560] Proactively for spidering to make the search engine more useful. [44:13.560 --> 44:17.980] Now, you can also set up a YACY node in what is called Caruso mode. [44:18.180 --> 44:18.620] Which is... [44:18.620 --> 44:20.620] It doesn't interact with the YACY network. [44:20.750 --> 44:21.840] It's entirely isolated. [44:22.940 --> 44:25.500] But it's still a fully functional search engine. [44:25.660 --> 44:29.500] And it still presents the XML and JSON APIs for interacting with it. [44:29.640 --> 44:35.460] Not only for making search requests, but for making requests to submit URLs for indexing. [44:36.420 --> 44:36.940] Um... [44:36.940 --> 44:37.440] I do both. [44:38.080 --> 44:41.160] I have a personal one for stuff that's just of interest to me. [44:41.160 --> 44:46.480] Because it's also my way of keeping track of stuff I've been looking up. [44:48.040 --> 44:48.600] Um... [44:48.600 --> 44:56.000] Also, to be a good citizen of the net, I also submit URLs for spidering to the YACY network to help make it more effective for everyone else out there. [44:58.340 --> 44:58.900] Um... [44:58.900 --> 44:59.440] It's... [44:59.440 --> 45:00.290] Now... [45:00.290 --> 45:03.160] The front end to the other search engines I use... [45:03.770 --> 45:04.320] I... [45:04.320 --> 45:11.300] I decided to go with Searx just because I got tired of having to rewrite my search engine parser every couple of weeks. [45:11.790 --> 45:13.580] I'd rather just have a... [45:13.580 --> 45:20.140] I'd rather just have a cron job, do a git pull, and then update the copy of Searx, restart it, and just hit the ground running. [45:23.040 --> 45:23.480] Hi. [45:23.780 --> 45:24.100] Uh... [45:24.100 --> 45:26.880] Did you have to do anything to secure this system? [45:27.080 --> 45:29.720] And did you have any security concerns when you were setting it up? [45:30.420 --> 45:30.900] Um... [45:30.900 --> 45:33.320] My security concerns are paranoia. [45:33.980 --> 45:34.460] Because... [45:35.400 --> 45:39.000] Functionally speaking, this is a big part of who I am and what I do. [45:40.060 --> 45:40.540] Um... [45:40.540 --> 45:43.740] If you go digging around in someone's exocortex, you're gonna find out a lot about them. [45:44.480 --> 45:44.960] Um... [45:44.960 --> 45:49.620] So, there are serious privacy implications to people getting access to it, which... [45:49.620 --> 45:51.260] Who probably should not have access to it. [45:52.420 --> 45:52.900] Um... [45:52.900 --> 45:52.980] Um... [45:52.980 --> 45:57.060] I've built multiple layers of security and, um... [45:57.060 --> 45:59.000] All of my stuff requires API keys. [45:59.940 --> 46:00.380] Everything... [46:00.380 --> 46:00.560] Um... [46:00.560 --> 46:03.580] Even the stuff that listens on the loopback interface only. [46:04.020 --> 46:04.260] Um... [46:04.260 --> 46:04.720] The code is... [46:04.720 --> 46:07.040] It's hard-coded to listen on the loopback interface. [46:07.500 --> 46:10.260] So, you would have to physically compromise the machine to get into it. [46:10.820 --> 46:11.260] Um... [46:11.260 --> 46:12.680] I don't put all my eggs in one basket. [46:12.820 --> 46:14.280] I have multiple servers around the world. [46:14.500 --> 46:15.140] Some are virtual. [46:15.300 --> 46:15.800] Some are physical. [46:16.580 --> 46:17.020] Um... [46:17.020 --> 46:18.780] They don't all have copies of the same thing. [46:19.800 --> 46:20.120] Uh... [46:20.600 --> 46:21.040] Um... [46:21.040 --> 46:22.620] Everything is backed up every couple of hours. [46:22.940 --> 46:24.020] All the backups are encrypted. [46:24.900 --> 46:25.340] Um... [46:25.340 --> 46:28.700] All the backups are downloaded and taken offline to removable drive. [46:30.360 --> 46:30.800] Um... [46:30.800 --> 46:30.980] Yeah. [46:31.080 --> 46:31.540] I am that paranoid. [46:33.080 --> 46:33.520] Um... [46:33.520 --> 46:33.980] Just in case. [46:34.120 --> 46:34.900] Just in case. [46:35.660 --> 46:36.100] Uh... [46:36.100 --> 46:36.920] Unfortunately, I... [46:36.920 --> 46:39.960] I do log certain things because... [46:39.960 --> 46:40.920] Occasionally, I do... [46:40.920 --> 46:43.980] Because I always tinker with stuff and bugs do crop up. [46:44.140 --> 46:45.520] So, I do have to go through and debug it. [46:45.740 --> 46:48.400] And having the option of logging really helps with that. [46:49.560 --> 46:49.920] Um... [46:49.920 --> 46:52.980] For a while, I tried to go the all, I don't log anything route. [46:53.740 --> 46:54.100] And... [46:54.100 --> 46:58.560] But then, when I started running into weird interactions and weird errors, I kept having to go back. [46:58.700 --> 47:02.440] Okay, I'm gonna copy and paste the configuration for the logger module in. [47:02.620 --> 47:05.020] And then, you know, logger.debug, blah, blah, blah. [47:05.260 --> 47:09.400] Or I could just leave it in and then turn it all the way down and only turn it up as I need to. [47:11.100 --> 47:11.460] Um... [47:11.460 --> 47:12.620] Everything is encrypted by default. [47:12.620 --> 47:14.260] I also have multiple layers of authentication. [47:14.680 --> 47:15.360] Different usernames. [47:15.500 --> 47:16.100] Different passwords. [47:17.020 --> 47:17.620] Uh... [47:17.620 --> 47:20.440] Separate databases in the database servers. [47:21.100 --> 47:21.340] Uh... [47:21.340 --> 47:23.040] Separate service accounts in the database. [47:23.500 --> 47:25.700] Separate backup service accounts in the databases. [47:26.000 --> 47:27.340] Which are specific to those databases. [47:29.740 --> 47:30.340] Uh... [47:30.340 --> 47:31.640] Also, operating system diversity. [47:34.580 --> 47:37.800] So, you have a very well-defined system of all the different aspects. [47:38.000 --> 47:43.000] Have you thought about creating it as modules to share out with other people to help them create theirs? [47:43.340 --> 47:44.320] I have indeed. [47:45.240 --> 47:45.680] So... [47:46.240 --> 47:48.920] I have a GitHub repository that I'm going... [47:48.920 --> 47:50.620] That I'm going to post a link to. [47:50.800 --> 47:53.560] Or I should actually say Switchboard is going to post a link to in a couple of days. [47:55.580 --> 47:56.020] Uh... [47:56.020 --> 47:56.940] Which has... [47:56.940 --> 47:57.640] Yep, gotcha. [47:58.240 --> 48:01.580] Which has the source code to a bunch of agent networks for Huginn. [48:02.000 --> 48:03.560] So, basically, you can import them into Huginn. [48:03.900 --> 48:04.260] And... [48:04.800 --> 48:07.720] As long as you have the API key for WeatherNow dot... [48:07.720 --> 48:08.040] Uh... [48:08.480 --> 48:08.660] WeatherNow... [48:08.660 --> 48:09.680] Excuse me. [48:10.740 --> 48:11.460] WeatherUnderground.com. [48:12.680 --> 48:13.040] Um... [48:13.040 --> 48:13.720] They'll all come up. [48:13.800 --> 48:14.460] They'll all start running. [48:14.620 --> 48:15.380] You can look at them. [48:15.440 --> 48:16.020] You can play with them. [48:16.080 --> 48:16.840] You can tinker with them. [48:16.960 --> 48:19.460] And you can use them to learn how to build your own agent networks. [48:20.840 --> 48:21.820] Also, uh... [48:21.820 --> 48:22.260] The Halo. [48:22.640 --> 48:24.800] All of those bots are in their own GitHub repository. [48:24.800 --> 48:26.780] And, actually, there's going to be a link to that. [48:27.280 --> 48:30.200] Actually, there was a link to the repository in an earlier slide. [48:32.440 --> 48:32.840] Yep. [48:33.000 --> 48:36.880] Here's the link to the repository for Huginn by Andrew Cantino. [48:37.100 --> 48:37.460] Uh... [48:37.460 --> 48:37.800] Hi, Andrew. [48:38.340 --> 48:41.300] And down here is a link to the, uh... [48:41.300 --> 48:43.360] GitHub repository for Halo, which is all of my bots. [48:45.740 --> 48:46.360] And, uh... [48:46.360 --> 48:48.840] I'm trying to document my bots as well as I can. [48:49.080 --> 48:50.940] So, other people can stand them up. [48:51.100 --> 48:51.840] They can look at the code. [48:51.840 --> 48:53.340] They can tinker with them. [48:53.900 --> 48:54.340] Uh... [48:54.340 --> 48:55.040] Submit patches. [48:55.280 --> 48:56.040] Make pull requests. [48:56.280 --> 48:56.800] Open bugs. [48:57.440 --> 48:59.200] And contribute more bots to it. [48:59.400 --> 49:03.320] Because I really want to see this technology take off as a personal technology. [49:05.640 --> 49:06.080] Um... [49:06.080 --> 49:06.300] Uh... [49:06.300 --> 49:09.300] Also, my slides will go up on Monday or Tuesday. [49:09.940 --> 49:10.380] So... [49:10.380 --> 49:10.720] This... [49:10.720 --> 49:12.520] My slides are on an HTML page. [49:12.680 --> 49:13.600] So, you can just click on it. [49:13.680 --> 49:14.220] You'll go right to it. [49:14.480 --> 49:14.880] Awesome. [49:15.380 --> 49:15.560] Um... [49:15.560 --> 49:17.840] Now, personally, how do you manage all the notifications? [49:18.860 --> 49:19.380] Yeah. [49:19.700 --> 49:20.000] That's... [49:20.000 --> 49:21.840] So, that took some fine-tuning. [49:22.480 --> 49:25.540] So, the lowest priority stuff are digest messages. [49:25.980 --> 49:26.920] So, that digest... [49:26.920 --> 49:29.640] So, those digests get sent every couple of hours. [49:30.000 --> 49:33.500] And I might look at those if I'm standing in line bored or something. [49:33.860 --> 49:34.380] Uh... [49:34.380 --> 49:36.640] The next level of priority up are individual emails. [49:36.820 --> 49:41.940] So, if I get an email, then that's something that I should probably pay closer attention to. [49:41.940 --> 49:43.860] And that's usually stuff coming out of Ironmonger. [49:44.220 --> 49:46.420] The next level of severity up... [49:46.420 --> 49:47.140] Or sensitivity... [49:47.140 --> 49:47.600] Or... [49:47.600 --> 49:47.720] Yeah... [49:47.720 --> 49:48.060] Severity. [49:48.620 --> 49:50.440] Is stuff that comes from... [49:51.180 --> 49:51.740] Uh... [49:51.740 --> 49:52.520] Beeper.io. [49:53.060 --> 49:53.940] Which is basically... [49:54.740 --> 49:55.160] Um... [49:55.160 --> 49:57.800] It's sort of kind of like text messaging, but not. [49:58.360 --> 49:58.800] Uh... [49:58.800 --> 50:00.060] And it's things like... [50:00.060 --> 50:03.020] Interesting stuff that crops up on Twitter or things like that. [50:03.720 --> 50:04.280] Um... [50:04.280 --> 50:05.580] Cryptocurrency network notifications. [50:05.980 --> 50:09.380] The next level of severity up from that is... [50:10.200 --> 50:12.620] Actual SMS or MMS text messages. [50:13.400 --> 50:14.600] And the next level of security... [50:14.600 --> 50:18.880] Or next level of severity up from that are getting phone calls from the voice over IP bot. [50:19.300 --> 50:21.680] Because if something made it all the way up to... [50:21.680 --> 50:28.720] Text is being turned into speech, which is then being placed over a voice over IP network, then I really have to see that. [50:29.180 --> 50:29.640] Uh... [50:29.640 --> 50:30.960] I also have some stuff in... [50:30.960 --> 50:34.940] I also have some stuff built into my exocortex that calls up other people just in case. [50:36.160 --> 50:36.620] Um... [50:36.620 --> 50:38.040] Those are usually health related stuff. [50:40.240 --> 50:40.720] Um... [50:40.720 --> 50:44.100] So UI designer here, so more the behavioral aspect of it. [50:44.220 --> 50:47.180] The way that I see it, you have a circle of advisors that is like... [50:47.800 --> 50:48.220] Uh... [50:48.220 --> 50:49.120] Uh... [50:49.120 --> 50:49.920] Uh... [50:49.920 --> 50:50.680] Um... [50:50.680 --> 50:52.160] Digest or triggers... [50:52.160 --> 50:52.340] Uh-huh. [50:52.560 --> 50:55.720] That come at you and reduce your anxiety because you're a news junkie. [50:55.920 --> 50:56.220] Got it. [50:56.680 --> 50:57.140] Uh... [50:57.140 --> 51:05.800] Do you have any case of some part of information that didn't come true that you already had an intuition of like, this is missing? [51:06.040 --> 51:07.560] And when it arrives, it's kind of... [51:07.560 --> 51:08.640] You know what I mean? [51:08.740 --> 51:11.380] It's like you're trying to get to a certain... [51:12.740 --> 51:14.340] Trying to control a situation. [51:15.080 --> 51:15.500] And... [51:15.500 --> 51:17.800] And some information that was supposed to come didn't. [51:18.180 --> 51:20.840] But you already had the intuition that it should. [51:23.060 --> 51:23.740] Uh... [51:23.740 --> 51:26.400] If I'm understanding you correctly, am I... [51:26.400 --> 51:31.720] Do things occasionally come across my exocortex that seem fishy or not complete? [51:32.620 --> 51:33.940] No, it's never complete. [51:34.440 --> 51:34.800] It's never complete. [51:34.800 --> 51:38.500] And that if you can learn, get an intuition out of it. [51:38.640 --> 51:38.960] Yeah. [51:39.140 --> 51:40.240] It goes both ways, right? [51:40.540 --> 51:41.020] Yeah. [51:41.220 --> 51:41.580] Uh... [51:41.580 --> 51:43.420] A lot of that is information security related. [51:43.660 --> 51:45.860] Stuff like vulnerabilities, uh... [51:45.860 --> 51:48.080] Data breaches, rumors of... [51:49.060 --> 51:49.540] Uh... [51:49.540 --> 51:51.920] Rumors of corporations being compromised, stuff like that. [51:53.160 --> 51:55.140] Sometimes it makes sense, sometimes it doesn't. [51:55.440 --> 51:55.740] Uh... [51:55.740 --> 51:58.860] Some of the political and geopolitical analysis stuff... [51:58.860 --> 52:00.680] I don't take it as... [52:00.680 --> 52:04.580] I don't take it as perfect, but I do take it under advisement. [52:06.280 --> 52:06.760] Um... [52:06.760 --> 52:08.560] For what it's worth, the geopolitical... [52:08.560 --> 52:10.620] The geopolitical analysis stuff... [52:11.600 --> 52:12.080] Is... [52:12.080 --> 52:14.280] I am very relieved when it winds up not being true. [52:15.940 --> 52:16.420] And... [52:16.420 --> 52:17.720] If nothing else, it's... [52:17.720 --> 52:21.480] Let me build a much better bullshit detector for interacting with the world personally. [52:25.700 --> 52:26.980] Hi there, thank you for your talk. [52:27.640 --> 52:28.120] Uh... [52:28.120 --> 52:28.720] Do you... [52:28.720 --> 52:34.560] Have you developed or have you had any sense of anxiety over losing agency over part of this now equivalent? [52:34.560 --> 52:37.480] Or externalized part of your personality or part of your affordances? [52:39.620 --> 52:40.020] Uh... [52:40.020 --> 52:40.180] No. [52:40.460 --> 52:43.180] I haven't developed anxiety over it because... [52:44.480 --> 52:50.140] It's actually helped me manage how much information I need to feel like I understand the world. [52:50.860 --> 52:52.660] And I don't have to do it personally now. [52:52.780 --> 52:57.820] I don't have to run around like a chicken with my head cut off, punching F5 every five minutes to see if something new has come up. [52:57.820 --> 52:58.900] But I mean, do you... [52:58.900 --> 52:59.240] Do you... [52:59.240 --> 52:59.480] Are you... [53:00.360 --> 53:01.160] I apologize. [53:01.420 --> 53:04.120] Are you concerned about losing that now? [53:04.300 --> 53:05.060] You've become... [53:05.060 --> 53:06.100] It's become part of you. [53:06.240 --> 53:08.380] It's now living external to your biological being. [53:08.940 --> 53:10.800] Those are giving you certain types of abilities. [53:11.240 --> 53:18.260] And if those are stripped from you or if they break and you no longer have access to them, does that present you with any sense of anxiety? [53:18.440 --> 53:19.580] Like losing those abilities. [53:19.580 --> 53:20.000] Okay. [53:20.160 --> 53:22.300] It does give me a certain sense of anxiety. [53:22.640 --> 53:29.400] And the way that I manage that is I try to go on media fasts about three days a week. [53:29.720 --> 53:31.020] So basically, I... [53:31.020 --> 53:34.360] You know, there's a scheduler agent which basically you... [53:34.360 --> 53:37.760] Which controls whether or not agents run or not. [53:38.200 --> 53:43.480] And the reason I have those schedulers in place is once five o'clock on Friday comes around, I'm shutting down. [53:44.840 --> 53:45.440] That's it. [53:45.440 --> 53:51.240] I go offline, I spend it with my family, and then it's only the highest priority stuff that gets evented on. [53:51.640 --> 53:55.560] And that's work and that is family-related stuff. [53:55.800 --> 53:59.800] But otherwise, I'm offline, I'm spending time with my family, I'm... [53:59.800 --> 54:03.980] You know, I'm hacking for fun, I'm watching TV, I'm doing other stuff. [54:04.540 --> 54:09.160] Also, to manage that sort of anxiety because it is a very real risk. [54:09.780 --> 54:13.700] It's helped me focusing on my health, going to the gym, stuff like that. [54:13.700 --> 54:19.180] And then, you know, losing myself in a workout with my headphones on for two hours. [54:20.340 --> 54:22.300] So, yes, but. [54:24.640 --> 54:26.540] I just had a real quick question for you. [54:26.760 --> 54:26.880] Yeah. [54:27.020 --> 54:29.840] About how large would you say the infrastructure for that is? [54:29.940 --> 54:35.700] Number, maybe like an estimate of nodes and... or hardware and virtual machines? [54:35.700 --> 54:38.840] And are you using any sort of config management on them? [54:40.300 --> 54:41.420] Okay, so... [54:41.420 --> 54:46.000] I will carefully say between six and a dozen machines, virtual and physical. [54:46.600 --> 54:51.720] Each of them has anywhere from 40 gigabytes of storage to 40 terabytes of storage. [54:54.000 --> 55:04.700] No links slower than 100 megabits, anywhere from 64 to 256 gigabytes of RAM. [55:05.620 --> 55:13.640] And as for configuration management, I'm sorry to say that they're all more or less bespoke, but I try to keep that under control with... [55:15.480 --> 55:19.760] Basically, I check out the... I check out the appropriate Git repository. [55:20.420 --> 55:24.120] And then everything has a shell script to start it up. [55:24.260 --> 55:26.140] And then I have a custom... [55:26.140 --> 55:29.280] If it's a BSD style in its script... [55:29.280 --> 55:32.300] If it's a BSD style system, then I have BSD style in its script. [55:32.440 --> 55:36.920] Otherwise, I have custom.screenrc files that I run screen-l. [55:37.580 --> 55:39.080] Everything comes up all at once. [55:39.620 --> 55:44.140] And then not only can I monitor it if I SSH in, but everything's started and everything's managed. [55:44.800 --> 55:45.660] Great, thank you. [55:46.680 --> 55:48.040] And I am out of time. [55:48.240 --> 55:49.040] Thank you very much, everyone.