Browse Source

JavaScriptAgent can access storage provided by KeyValueStoreAgents

Akinori MUSHA 1 year ago
parent
commit
c59c3e6275

+ 7 - 0
app/models/agents/java_script_agent.rb

@@ -33,6 +33,7 @@ module Agents
       * `this.options(key)`
       * `this.log(message)`
       * `this.error(message)`
+      * `this.kvs` (whose properties are variables provided by KeyValueStoreAgents)
       * `this.escapeHtml(htmlToEscape)`
       * `this.unescapeHtml(htmlToUnescape)`
     MD
@@ -129,6 +130,12 @@ module Agents
       context.attach('getCredential', ->(k) { credential(k); })
       context.attach('setCredential', ->(k, v) { set_credential(k, v) })
 
+      kvs = Agents::KeyValueStoreAgent.merge(controllers).find_each.to_h { |kvs|
+        [kvs.options[:variable], kvs.memory.as_json]
+      }
+      context.attach("getKeyValueStores", -> { kvs })
+      context.eval("Object.defineProperty(Agent, 'kvs', { get: getKeyValueStores })")
+
       if (options['language'] || '').downcase == 'coffeescript'
         context.eval(CoffeeScript.compile(code))
       else

+ 48 - 0
spec/models/agents/java_script_agent_spec.rb

@@ -413,4 +413,52 @@ describe Agents::JavaScriptAgent do
       end
     end
   end
+
+  describe "KVS" do
+    before do
+      Agents::KeyValueStoreAgent.create!(
+        name: "kvs1",
+        options: {
+          key: "{{ key }}",
+          value: "{{ value }}",
+          variable: "var1",
+        },
+        memory: {
+          x: "Huginn",
+        },
+        user: users(:jane),
+        control_targets: [@agent]
+      )
+
+      Agents::KeyValueStoreAgent.create!(
+        name: "kvs2",
+        options: {
+          key: "{{ key }}",
+          value: "{{ value }}",
+          variable: "var2",
+        },
+        memory: {
+          y: "Muninn",
+        },
+        user: users(:jane),
+        control_targets: [@agent]
+      )
+    end
+
+    it "can be accessed via Agent.kvs()" do
+      @agent.options['code'] = <<~JS
+        Agent.check = function() {
+          this.createEvent({ message: `I got values from KVS: ${this.kvs.var1["x"]} and ${this.kvs.var2["y"]}.` });
+        };
+      JS
+      @agent.save!
+
+      expect {
+        @agent.check
+      }.to change { @agent.events.count }.by(1)
+
+      created_event = @agent.events.last
+      expect(created_event.payload).to eq("message" => "I got values from KVS: Huginn and Muninn.")
+    end
+  end
 end