A bot for Glitch's editor

Project URL: Glitch :・゚✧

the code for this has some spaghettiness to it, but here it is for fun anyway, a bot that watches you type in the Glitch editor and edits with you.

and I don’t mean that it programs with you, it’s only an experiment to show how to interact with the live collaboration system, “OT.” here it’s set up so that when you type a comment starting with > , it’ll repeat the comment, starting with < , in uppercase.

help me think of wacky things to do with this.

6 Likes

This works, and is so cool! I’ll try using that to implement ChatGPT in Glitch.

Too late, I’m doing it myself. :slight_smile:

1 Like

I actually started building it, but had some problems with the fetching URLs stuff so I gave up.

As you are working on your bots, let me know what roadblocks you hit, what API endpoints would help you succeed, what kind of bots you’d like to build for the Glitch editor, etc. I think this is super interesting work and love the idea of community-built bots on here!

4 Likes

lol done (send gpt-reset to reset your conversation, it also wipes when you stop the bot.js while it’s running)

3 Likes

do I fix conversations wiping when you stop bot.js? and also probably make a README.md on how to use it :eyes:

this is an awesome project, it’ll make MY work easier that’s for sure.

EDIT: There’s some documentation on how to use it now and I’m making it easier to use by the minute :slight_smile:

For those trying to work with this: Your user token is in your cachedUser object inside localStorage, as your persistentToken value. This is neccesary to create the connection to your project. The rest I handle- including getting the project ID, you just have to give the username. Should work with private ones too since I pass in your user token at that point.

Heyyyy! I spent a good few hours working on this and I want to die.

It’s done now though! Go check it out, it’s somewhat easy to integrate now (and once you’ve done it, you can just keep the tab open to integrate ChatGPT with your project)

It also now respects whitespace fully :+1:

1 Like

yo @wh0 you know more than me about this, can you help? I tried to add whitespace support but it sometimes replaces in the wrong spot (I do put in the whitespace length to avoid that but it seems to not be working)

it also has ChatGPT support if you want to test that too

regex first capture group doesn’t look like a pattern for matching spaces. (. ) matches any character followed by one space. could try (\s*)(\S.*)?

Worked like a charm! A few changes and now it actually respects whitespace. You probably saw the dirty patch I made to fix an indentation issue near the bottom :frowning:

new issue: offsets in .html :cry:

offsets in your indentation in .html / .svelte cause issues with the bot. trying to figure out the offset generation as we speak but it’s painful :frowning:

So far I’ve figured out the offsets to make the line appear right BUT now we have the issue of broken bits after, I’m removing part of my code to see if it helps

EDIT: for some reason Glitch injects a SINGLE SPACE whenever the .html offset issue happens. no more auto new lines to mitigate. please tell me if this is the right way to do this

oh it’s better not to use start or end like that after sending the first transaction. every time you await there could have been other edits made that shift things around. you can rely on the transactions to be up to date

confused coder sounds

what should I change? I only use await to grab the message from OpenAI’s API and also in whatever code you had

const whitespaceLength = spacesRemoved.length;
...
unsubmittedTx.tx[docId][0][2] = spacesRemoved + "// < Contacting ChatGPT...";
...
unsubmittedTx2.tx[docId][0][0] += whitespaceLength + 5; // relative offset
unsubmittedTx2.tx[docId][0][1] = 22; // splice length

the relative offset in [0] looks right, for bringing you to just before the “C” in “Contacting”
the splice length in [1] looks one too many, as Contacting ChatGPT... is 21 characters. you have no guarantees what comes outside the transaction’s splices, so it’s not safe to do 22 there.


edit:
and that if thing that comes later shouldn’t trigger, as long as there are no concurrent edits going on. does it?

hey wait a minute, I could’ve sworn I put 21 there. >:/

anyway fixed, testing patch

EDIT: apparently a single space is injected after sending the first message which is why I set it to 22 >:?

also the extra space comes back. :frowning:

it does, the .html offset issue causes it to flip (end no longer equals the value returned in unsubmittedTx2 and that new value breaks things, hence the offset fix

how much does the [0] change by?

it depends on how offset it is
one HTML object = 2
two HTML objects = 4
you get the point

it’s an annoying bug and I fucking hate it

my initial patch for it only fully accounts for removing the whitespace from one HTML object

weeeeird let me try in a remix

go ahead. I’m going to try to squash it and will edit if I get it down

EDIT: squashed, my code now has a fix
the offset is unsubmittedTx2.tx[0][0] - end + whitespaceLength + 5

subtract the offset from relative offset
add the offset to splice length

(Glitch, what the FU-)

okay after tons of printf debugging, here’s how things were going haywire. don’t blame Glitch, it was a bug in my code.

  1. the Glitch editor, when you press enter on an indented line, as was the case in your HTML use case, creates a new line and indents it appropriately.
  2. when it tells the Glitch OT server about the new indented line, it doesn’t insert it as “newline, space, space, …”. it first inserts just the newline, then in a second operation, it inserts the indentation spaces.
  3. my code would handle an incoming list of operations (an “oplist”) by increasing the version number and then examining each operation in sequence.
  4. when my code examines an operation that finishes one or more lines, it invokes the callback for handling a new line, synchronously. but in this case, it hasn’t even finished processing the oplist.
  5. the synchronous part of the line handler starts sending out a new transaction, mistakenly thinking it is already operating on the new version, as the version number has already been increased.
  6. then my code finally gets to the second part of the incoming oplist, and it incorrectly sees this a something that needs to fix up the outstanding transaction.

so as a result,

  • an oplist goes out to the OT server that tries to operate on the wrong starting state.
  • the client’s view of the outstanding transaction incorrectly gets updated, which later causes the successor transaction to be created with the wrong information too
  • basically everything thereafter goes wrong because of the above

I’ve made the following fixes in the original maple-separated-seal:

  1. Move the version increment to the end of the oplist apply-er:

     function opListApply(opList) {
    -  version = opList.version + 1;
       for (const op of opList.ops) {
         docsVisitOp(op);
         txsVisitOp(op);
         readerVisitOp(op);
       }
    +  version = opList.version + 1;
     }
    

    this is a safeguard to make any transactions sent while in the middle of processing an incoming oplist fail on the server. okay and I just realized that I had not settled whether oplist is one word or two words together, as opList :person_facepalming:.

  2. wait for a microtask at the top of readerVisitLine

     function readerVisitLine(docId, unsubmittedTx) {
    +  (async () => {
    +    try {
    +      // wait for a microtask, after we finish processing the whole oplist that
    +      // this line appeared in.
    +      await Promise.resolve();
    +
       if (!unsubmittedTx.tx) throw unsubmittedTx.reason;
       ...
       const submitTxPromise = submitUnsubmittedTx(unsubmittedTx);
    -  (async () => {
    -    try {
           const unsubmittedTx2 = await submitTxPromise;
    

    this prevents us from submitting a transaction until after the whole incoming oplist is processed. note that the first if (!unsubmittedTx) throw is now required, as an oplist may create a line and then disturb it in the same version, before we finish awaiting that Promise.resolve().

1 Like

This is only a partial fix sadly :frowning:

Magic spaces were part of the problem. Using your new code:

  • Magic spacing corresponding to the indent appears! That was part of the problem if you had no indent (Or a lot of unneeded indent), as that spacing can possibly cause issues.

I’ll update my bot to the new code but now I need to add even more code to handle the dumb spaces.

EDIT: New code makes it even harder to work around the dumb space issue >:/
I’m going to stay on the old codebase in order to keep the workaround for now

oh is this for when you don’t have a newline at the end of the string that the bot adds?

No the newline just moves the spaces AFTER the newline and makes mitigation worse

but isn’t it nice to have the extra newline and indent?

(indent)      // > (your message)(your newline)
(bot indent)  // < (bot message)(bot newline)
(added indent)(cursor)

that way you can start typing another // > ... right away

vs without the extra newline:

(indent)      // > (your message)(your newline)
(bot indent)  // < (bot message)(added indent)(cursor)

It would be nice if the indent worked right, currently it only spawns the indent the editor expects (Which often doesn’t work with extra / removed indents)

do you have an example of that, when it’s wrong?

  • make a .html file
  • add a script element
  • remove the indent (bad idea but oh well)
  • use the bot
  • indent comes back >:/
  • add a bunch of tabs as unnecesary indent
  • use the bot
  • unneccesary tabs are not applied

edge case but still a thing

1 Like

image
it’s inserting responses at the same indent level as the request
image

the glitch editor has its opinion on how much to indent a new line, and it does so unrelated to the bot

1 Like

there’s the problem. I want it to be on the same line as the first request, and ignore glitch’s annoying indent. I’m assuming this is impossible

also if you remove the newline the spaces just appear after the response anyway

I suppose you could scan forward in the document and detect spaces and delete them from the transaction

here’s an idea on how I could do this

  • grab the next ~200 characters from our // < ... starting point

  • make a regex statement matching that starting part and then all spaces until a non-space is hit

  • collect those spaces into a regex group and do some stuff with them- namely, removing or adding more spaces to compensate for the extra ones

I have no idea how to do that but it would work

wait did I read this right? did you want it like this?

(indent)      // > (your message) < (bot message)(your newline)
(added indent)(cursor)
1 Like

yes. the negative indent too

there’s no negative indent there.

but there’s a part where it sets the relative offset to end, meaning to insert the text right after the newline. you would instead use end - 1, so that it gets inserted before the newline. and with that, don’t insert any newlines, because that would make it look like the same line has been created again

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.