Tinderbox Forum

Agents as user attribute values

Can I create a user attribute whose value is an agent?

I’m designing a Tinderbox as backup for Andy van Dam’s upcoming Hypertext 30 Keynote on Sept. 17. The foundational structure is related to what I created in the Memex and Beyond website (http://cs.brown.edu/memex/), only this is a 2D space and will cover all the ACM Hypertext conferences since 1987 plus a few other things such as references to Doug Engelbart’s papers, including his 1962 SRI report “Augmenting Human Intellect: A Conceptual Framework”. In my HT '01 demo of ConceptLab I tried to create a searchable, reconfigurable 2D framework for the structure, but it was pretty ugly and not really extensible. The categories are People, Projects, Institutions, Publications, Conferences, Concepts/Keywords, and these categories are all interlinked as you can see in the Memex and Beyond website. There will be hundreds of documents referenced and the Tinderbox will dynamically grow over time. To build this network, with links to PDFs of the specific documents, I need to automatically populate the appropriate category individuals for each document registered in the Tinderbox. After the Tinderbox is populated with this network of information, I then want to use agents to gather all related information in a 2D manner for a specific person or institution or project or concept or conference or publication.

The reason why I wanted to use an agent as an attribute value is that this Tinderbox will be rapidly growing and Attributes such as Publications for a person such as Catherine Marshall will have many values, the number of which grows over time. Plus, these values are actually “links” to another part of the Tinderbox.

In general, this is an academic research resource base that I’m creating in response to this very important Keynote.

1 Like

@SkylarkMichelle - I have a TBX mapping all papers in the ACM Hypertext '97-'18 including ECHT '92 and '94 and am currently adding info for ECHT '90 (I know it’s not formally adopted as part of the ACM conference but is is HT and covers papers on Microcosm so seems pertinent.

Here’s just something I output from it: https://www.shoantel.com/proj/acm-ht/2018/index.html

This all grew from playing around with Les Carr’s 2004 Tinderbox experiments (on the old wiki).

Notes for papers have a fair amount of metadata:


I’ve also extracted all authors and normalised for spelling, accents, alternat forename, change of surname etc. All authors link to their papers.

Happy to send you a copy if you want. It’s a lot of my effort but the data is ultimately all derived from dl.acm - though their records have goodly amount of typos that i’ve corrected along the way.

Last point. don’t try and do a project at this size in a single map - it’s simply too much data, even though map performance has improved significantly in recent versions. The doc pre-dates hyperbolic view so I’ve not tried that but it too may chug a bit with a doc with this many notes and links.

Note: if wondering why I’m just not posting a copy, I’m still working on the doc and I’m also uncertain about the copyright issue re the dl.acm source. Normally, anyone you can find to ask about such things gives a default ‘no’ - albeit because they don’t understand or simply don’t care.]


Note for later readers: the control concepts described here really are only pertinent at scale - with thousands of notes. For more normal documents with a few hundred notes or fewer, such precautions are overkill.

Further to my last, re agents. My experience is making an agent for every [thing] doesn’t scale up nicely. You end up with a lot of agents and have to tweak their $AgentPriority or turn updates off.

More flexible I’ve found are edicts, although they too need use with care. The find() action essentially allows a note to run a query like an agent, without needing and agent:

 ... action code stuff;

Now rather than a thousand notes each needing an agent, the note can use a find to populate attributes and make/break links. In the case of links, you are now working from the context of the original, rather than an alias, it is easier to ensure links are between originals at both ends (though recent action code changes have made the task easier in agents, too).

An edict runs once only the following events (and assuming $EdictDisabled is not set true locally):

  • On first creation
  • On editing the edict code;
  • At document start.
  • Approximately once per hour during the current document session.
  • If File -> Update Agents Now is run (i.e. a one-off manual agent update also updates all edicts once as well and works even if there are no agents in the document).

So a quite flexible system, where you can run the edicts you need, when you need and not clog your editing with lots of unneeded always-on behaviours.

At scale, prototype are your friend. I use them a lot. They are also a good way to maintain rules and edicts across lots of notes. Be aware that $EdictDisabled (and $RuleDisabled) are intrinsic so are not inherited. To make an edict switchable via the prototype, use this sort of edict wrapper (amend the code and you can do the same with rules):

... edict code;

The $IsPrototype test is there because in this sort of scenario you generally don’t want the edict to run in the prototype. $EdictDisabled normally does this, but we’re now using it as a proxy switch for all notes using the prototype, so we simply ensure that the note executing the edict isn’t itself a prototype.

If this doesn’t make sense do ask

Thanks Mark,

I have been slowly working on a notebook which now contains many notes and a series of flags/tags I have created within the body of these notes ($Text). I am still trying to wrap my head around Edicts and how I can use these to find all of a given flag that is contained within the $Text. Here is a brief description, let me know if this is doable and/or feasible to do in tinderbox.

I have created a number of ‘people’ notes and have a rule that turns their name into a custom attribute (which is a flag I am using in my notes). For example, John Smith has a custom attribute ($hFlag) that removes the space and adds an @ (so for this ‘person’ note, $hFlag = @JohnSmith.

When I then create notes that relate to, reference or mention John Smith, i add @JohnSmith within the body of the note.

Can I use an edict in the ‘John Smith’ person note to ‘find’ or aggregate all of the other notes in my map that contain the @JohnSmith string?

I hope this makes sense. As I take notes, I ‘flag’ things based on people or concepts using various flags and would like to be able to find/aggregate these specific flags to better utilize the information I am capturing.

Thanks for any help on this.

Remember that Edicts belong to individual notes, and are like slow-moving Rules.

If this were my document I would create an Agent (perhaps a low-priority agent) to query your notes and create aliases for the notes containing @JohnSmith, etc.

If you are going to have numerous “flags” then consider using Attribute Browser instead of a lot of agents.

(Note, the way you are using the term “flag” is probably different than Tinderbox’s $Flags, which is also a robust way of adding visual clues to notes.)

Also, take a look at $NLNames, which operates automatically within each Note and, once added as a Key Attribute via a note or note’s prototype, can expose the names found in your notes.

First: Edict and Rules do the same thing. Rules run frequently; edict run about once an hour, though Tinderbox can update an edict more often if it wants to. So:

  • Rules are easier to test
  • Switch rules to edicts if your Tinderbox document has too much to do, and you don’t really need frequent updates.

The natural way to collect information about notes that mention John Smith is to use an agent:

. Query: $Text.contains("@JohnSmith")

But a note could get a list of notes that mention Mr. Smith

. Rule or Edict:$MySet= find($Text.contains("@JohnSmith"))

1 Like

Actually this sounds like a variant on a very common process in my research when I takes the values() of a given attribute, save the list to $Text, explode it and then link those notes back to all notes where the new note’s name is the/a value in the original source attribute.

The difference here is you want to work in a map. If these new edicts collected (i.e. moved) notes—I presume present on the same map then what would happen is a note mentioned several people. The one note can’t move to two places at once. How do you propose the avoid the latter problem? Or am i misunderstanding your intent?

The problem isn’t so much the edict query code as understanding how it will achieve the effect you desire.

Thanks for the reply’s. There is stuff here I need to explore and appreciate the guidance.

Yes Mark, this is similar. I want to be able to add notes and not know how they will relate until I choose to look for all the notes containing different ‘flags’ I add as I take the notes.

I do not need these agents/edicts/rules to run constantly. Instead, if I add a note and then want to look back at other notes that have ‘John Smith’ or other words/concepts/people, I could run then.

Maybe what I should do is create a generic action (that I can deactivate) with User defined parameters that I could fill in and run to examine ‘related’ notes.

I will play with some things and likely ask for guidance when I get stuck again.

Thanks again